Skip to content

Commit

Permalink
proposal
Browse files Browse the repository at this point in the history
  • Loading branch information
frenzibyte committed Jul 18, 2024
1 parent 5317086 commit 6ae2f46
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 53 deletions.
117 changes: 117 additions & 0 deletions osu.Game/Overlays/OverlayColourPalette.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// 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 osu.Framework.Bindables;
using osu.Framework.Graphics;
using osuTK.Graphics;

namespace osu.Game.Overlays
{
public class OverlayColourPalette
{
/// <summary>
/// The hue degree associated with the colour shades provided by this <see cref="OverlayColourPalette"/>.
/// </summary>
public readonly BindableInt Hue;

public OverlayColourPalette(OverlayColourScheme colourScheme)
: this(colourScheme.GetHue())
{
}

public OverlayColourPalette(int hue)
{
Hue = new BindableInt(hue);
}

public Colour4 Get(OverlayColourShade shade)
{
switch (shade)
{
// Note that the following five colours are also defined in `OsuColour` as `{colourScheme}{0,1,2,3,4}`.
// The difference as to which should be used where comes down to context.
// If the colour in question is supposed to always match the view in which it is displayed theme-wise, use `OverlayColourProvider`.
case OverlayColourShade.Colour0:
return getColour(1, 0.8f);

case OverlayColourShade.Colour1:
return getColour(1, 0.7f);

case OverlayColourShade.Colour2:
return getColour(0.8f, 0.6f);

case OverlayColourShade.Colour3:
return getColour(0.6f, 0.5f);

case OverlayColourShade.Colour4:
return getColour(0.4f, 0.3f);

case OverlayColourShade.Highlight1:
return getColour(1, 0.7f);

case OverlayColourShade.Content1:
return getColour(0.4f, 1);

case OverlayColourShade.Content2:
return getColour(0.4f, 0.9f);

case OverlayColourShade.Light1:
return getColour(0.4f, 0.8f);

case OverlayColourShade.Light2:
return getColour(0.4f, 0.75f);

case OverlayColourShade.Light3:
return getColour(0.4f, 0.7f);

case OverlayColourShade.Light4:
return getColour(0.4f, 0.5f);

case OverlayColourShade.Dark1:
return getColour(0.2f, 0.35f);

case OverlayColourShade.Dark2:
return getColour(0.2f, 0.3f);

case OverlayColourShade.Dark3:
return getColour(0.2f, 0.25f);

case OverlayColourShade.Dark4:
return getColour(0.2f, 0.2f);

case OverlayColourShade.Dark5:
return getColour(0.2f, 0.15f);

case OverlayColourShade.Dark6:
return getColour(0.2f, 0.1f);

case OverlayColourShade.Foreground1:
return getColour(0.1f, 0.6f);

case OverlayColourShade.Background1:
return getColour(0.1f, 0.4f);

case OverlayColourShade.Background2:
return getColour(0.1f, 0.3f);

case OverlayColourShade.Background3:
return getColour(0.1f, 0.25f);

case OverlayColourShade.Background4:
return getColour(0.1f, 0.2f);

case OverlayColourShade.Background5:
return getColour(0.1f, 0.15f);

case OverlayColourShade.Background6:
return getColour(0.1f, 0.1f);

default:
throw new ArgumentOutOfRangeException(nameof(shade));
}
}

private Color4 getColour(float saturation, float lightness) => Framework.Graphics.Colour4.FromHSL(Hue.Value / 360f, saturation, lightness);
}
}
106 changes: 53 additions & 53 deletions osu.Game/Overlays/OverlayColourProvider.cs
Original file line number Diff line number Diff line change
@@ -1,72 +1,72 @@
// 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.

using osuTK.Graphics;
using System;
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Graphics;

namespace osu.Game.Overlays
{
public class OverlayColourProvider
public partial class OverlayColourProvider : Component
{
/// <summary>
/// The hue degree associated with the colour shades provided by this <see cref="OverlayColourProvider"/>.
/// </summary>
public int Hue { get; private set; }
private readonly double providerDuration;
private readonly Easing providerEasing;

public OverlayColourProvider(OverlayColourScheme colourScheme)
: this(colourScheme.GetHue())
[Resolved]
private OverlayColourPalette palette { get; set; } = null!;

private readonly List<DrawableColourRegistration> registrations = new List<DrawableColourRegistration>();

public OverlayColourProvider(double providerDuration = 300, Easing providerEasing = Easing.OutQuint)
{
this.providerDuration = providerDuration;
this.providerEasing = providerEasing;
}

public OverlayColourProvider(int hue)
public void AssignColour(Drawable drawable, OverlayColourShade shade, Func<Colour4, Colour4>? adjustment = null)
{
Hue = hue;
var registration = new DrawableColourRegistration(new WeakReference<Drawable>(drawable), shade, adjustment);
registrations.Add(registration);
}

// Note that the following five colours are also defined in `OsuColour` as `{colourScheme}{0,1,2,3,4}`.
// The difference as to which should be used where comes down to context.
// If the colour in question is supposed to always match the view in which it is displayed theme-wise, use `OverlayColourProvider`.
// If the colour usage is special and in general differs from the surrounding view in choice of hue, use the `OsuColour` constants.
public Color4 Colour0 => getColour(1, 0.8f);
public Color4 Colour1 => getColour(1, 0.7f);
public Color4 Colour2 => getColour(0.8f, 0.6f);
public Color4 Colour3 => getColour(0.6f, 0.5f);
public Color4 Colour4 => getColour(0.4f, 0.3f);
protected override void LoadComplete()
{
base.LoadComplete();
palette.Hue.BindValueChanged(_ => updateColours());
}

public Color4 Highlight1 => getColour(1, 0.7f);
public Color4 Content1 => getColour(0.4f, 1);
public Color4 Content2 => getColour(0.4f, 0.9f);
public Color4 Light1 => getColour(0.4f, 0.8f);
public Color4 Light2 => getColour(0.4f, 0.75f);
public Color4 Light3 => getColour(0.4f, 0.7f);
public Color4 Light4 => getColour(0.4f, 0.5f);
public Color4 Dark1 => getColour(0.2f, 0.35f);
public Color4 Dark2 => getColour(0.2f, 0.3f);
public Color4 Dark3 => getColour(0.2f, 0.25f);
public Color4 Dark4 => getColour(0.2f, 0.2f);
public Color4 Dark5 => getColour(0.2f, 0.15f);
public Color4 Dark6 => getColour(0.2f, 0.1f);
public Color4 Foreground1 => getColour(0.1f, 0.6f);
public Color4 Background1 => getColour(0.1f, 0.4f);
public Color4 Background2 => getColour(0.1f, 0.3f);
public Color4 Background3 => getColour(0.1f, 0.25f);
public Color4 Background4 => getColour(0.1f, 0.2f);
public Color4 Background5 => getColour(0.1f, 0.15f);
public Color4 Background6 => getColour(0.1f, 0.1f);
private void updateColours()
{
for (int i = 0; i < registrations.Count; i++)
{
var registration = registrations[i];

if (!registration.Drawable.TryGetTarget(out var drawable))
{
registrations.RemoveAt(i--);
continue;
}

/// <summary>
/// Changes the <see cref="Hue"/> to a different degree.
/// Note that this does not trigger any kind of signal to any drawable that received colours from here, all drawables need to be updated manually.
/// </summary>
/// <param name="colourScheme">The proposed colour scheme.</param>
public void ChangeColourScheme(OverlayColourScheme colourScheme) => ChangeColourScheme(colourScheme.GetHue());
var colour = palette.Get(registration.Shade);

/// <summary>
/// Changes the <see cref="Hue"/> to a different degree.
/// Note that this does not trigger any kind of signal to any drawable that received colours from here, all drawables need to be updated manually.
/// </summary>
/// <param name="hue">The proposed hue degree.</param>
public void ChangeColourScheme(int hue) => Hue = hue;
if (registration.Adjustment != null)
colour = registration.Adjustment(colour);

private Color4 getColour(float saturation, float lightness) => Framework.Graphics.Colour4.FromHSL(Hue / 360f, saturation, lightness);
drawable.FadeColour(colour, providerDuration, providerEasing);
}
}

private record DrawableColourRegistration(WeakReference<Drawable> Drawable, OverlayColourShade Shade, Func<Colour4, Colour4>? Adjustment);
}

public static class OverlayColourProviderExtensions
{
public static T WithOverlayColour<T>(this T drawable, OverlayColourProvider colourProvider, OverlayColourShade shade, Func<Colour4, Colour4>? adjustment = null)
where T : Drawable
{
colourProvider.AssignColour(drawable, shade, adjustment);
return drawable;
}
}
}
34 changes: 34 additions & 0 deletions osu.Game/Overlays/OverlayColourShade.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 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.

namespace osu.Game.Overlays
{
public enum OverlayColourShade
{
Colour0,
Colour1,
Colour2,
Colour3,
Colour4,
Highlight1,
Content1,
Content2,
Light1,
Light2,
Light3,
Light4,
Dark1,
Dark2,
Dark3,
Dark4,
Dark5,
Dark6,
Foreground1,
Background1,
Background2,
Background3,
Background4,
Background5,
Background6,
}
}

0 comments on commit 6ae2f46

Please sign in to comment.