1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 09:27:34 +08:00

Merge pull request #1196 from smoogipooo/menu-mvvm

Update UI controls in line with framework changes
This commit is contained in:
Dan Balasescu 2017-08-29 19:29:14 +09:00 committed by GitHub
commit 2742fe46cf
13 changed files with 476 additions and 353 deletions

@ -1 +1 @@
Subproject commit 3db7e231653ec6ffe28b5dcd1a86230ec754cc1c Subproject commit 167d5cda8f3ddae702ffc8d8d22dac67e48b509c

View File

@ -69,28 +69,28 @@ namespace osu.Desktop.Tests.Visual
private class MyContextMenuContainer : Container, IHasContextMenu private class MyContextMenuContainer : Container, IHasContextMenu
{ {
public ContextMenuItem[] ContextMenuItems => new ContextMenuItem[] public MenuItem[] ContextMenuItems => new MenuItem[]
{ {
new OsuContextMenuItem(@"Some option"), new OsuMenuItem(@"Some option"),
new OsuContextMenuItem(@"Highlighted option", MenuItemType.Highlighted), new OsuMenuItem(@"Highlighted option", MenuItemType.Highlighted),
new OsuContextMenuItem(@"Another option"), new OsuMenuItem(@"Another option"),
new OsuContextMenuItem(@"Choose me please"), new OsuMenuItem(@"Choose me please"),
new OsuContextMenuItem(@"And me too"), new OsuMenuItem(@"And me too"),
new OsuContextMenuItem(@"Trying to fill"), new OsuMenuItem(@"Trying to fill"),
new OsuContextMenuItem(@"Destructive option", MenuItemType.Destructive), new OsuMenuItem(@"Destructive option", MenuItemType.Destructive),
}; };
} }
private class AnotherContextMenuContainer : Container, IHasContextMenu private class AnotherContextMenuContainer : Container, IHasContextMenu
{ {
public ContextMenuItem[] ContextMenuItems => new ContextMenuItem[] public MenuItem[] ContextMenuItems => new MenuItem[]
{ {
new OsuContextMenuItem(@"Simple option"), new OsuMenuItem(@"Simple option"),
new OsuContextMenuItem(@"Simple very very long option"), new OsuMenuItem(@"Simple very very long option"),
new OsuContextMenuItem(@"Change width", MenuItemType.Highlighted) { Action = () => this.ResizeWidthTo(Width * 2, 100, Easing.OutQuint) }, new OsuMenuItem(@"Change width", MenuItemType.Highlighted, () => this.ResizeWidthTo(Width * 2, 100, Easing.OutQuint)),
new OsuContextMenuItem(@"Change height", MenuItemType.Highlighted) { Action = () => this.ResizeHeightTo(Height * 2, 100, Easing.OutQuint) }, new OsuMenuItem(@"Change height", MenuItemType.Highlighted, () => this.ResizeHeightTo(Height * 2, 100, Easing.OutQuint)),
new OsuContextMenuItem(@"Change width back", MenuItemType.Destructive) { Action = () => this.ResizeWidthTo(Width / 2, 100, Easing.OutQuint) }, new OsuMenuItem(@"Change width back", MenuItemType.Destructive, () => this.ResizeWidthTo(Width / 2, 100, Easing.OutQuint)),
new OsuContextMenuItem(@"Change height back", MenuItemType.Destructive) { Action = () => this.ResizeHeightTo(Height / 2, 100, Easing.OutQuint) }, new OsuMenuItem(@"Change height back", MenuItemType.Destructive, () => this.ResizeHeightTo(Height / 2, 100, Easing.OutQuint)),
}; };
} }
} }

View File

@ -9,6 +9,6 @@ namespace osu.Game.Graphics.Cursor
{ {
public class OsuContextMenuContainer : ContextMenuContainer public class OsuContextMenuContainer : ContextMenuContainer
{ {
protected override ContextMenu<ContextMenuItem> CreateContextMenu() => new OsuContextMenu<ContextMenuItem>(); protected override Menu CreateMenu() => new OsuContextMenu();
} }
} }

View File

@ -1,52 +1,38 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
namespace osu.Game.Graphics.UserInterface namespace osu.Game.Graphics.UserInterface
{ {
public class OsuContextMenu<TItem> : ContextMenu<TItem> public class OsuContextMenu : OsuMenu
where TItem : ContextMenuItem
{ {
protected override Menu<TItem> CreateMenu() => new CustomMenu(); private const int fade_duration = 250;
public class CustomMenu : Menu<TItem> public OsuContextMenu()
{ {
private const int fade_duration = 250; CornerRadius = 5;
EdgeEffect = new EdgeEffectParameters
public CustomMenu()
{ {
CornerRadius = 5; Type = EdgeEffectType.Shadow,
ItemsContainer.Padding = new MarginPadding { Vertical = OsuContextMenuItem.MARGIN_VERTICAL }; Colour = Color4.Black.Opacity(0.1f),
Masking = true; Radius = 4,
EdgeEffect = new EdgeEffectParameters };
{
Type = EdgeEffectType.Shadow,
Colour = Color4.Black.Opacity(0.1f),
Radius = 4,
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Background.Colour = colours.ContextMenuGray;
}
protected override void AnimateOpen() => this.FadeIn(fade_duration, Easing.OutQuint);
protected override void AnimateClose() => this.FadeOut(fade_duration, Easing.OutQuint);
protected override void UpdateContentHeight()
{
var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight;
this.ResizeTo(new Vector2(1, State == MenuState.Opened ? actualHeight : 0), 300, Easing.OutQuint);
}
} }
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
BackgroundColour = colours.ContextMenuGray;
}
protected override void AnimateOpen() => this.FadeIn(fade_duration, Easing.OutQuint);
protected override void AnimateClose() => this.FadeOut(fade_duration, Easing.OutQuint);
protected override MarginPadding ItemFlowContainerPadding => new MarginPadding { Vertical = DrawableOsuMenuItem.MARGIN_VERTICAL };
} }
} }

View File

@ -1,114 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Game.Graphics.Sprites;
namespace osu.Game.Graphics.UserInterface
{
public class OsuContextMenuItem : ContextMenuItem
{
private const int transition_length = 80;
private const int margin_horizontal = 17;
public const int MARGIN_VERTICAL = 4;
private const int text_size = 17;
private OsuSpriteText text;
private OsuSpriteText textBold;
private SampleChannel sampleClick;
private SampleChannel sampleHover;
private readonly MenuItemType type;
protected override Container CreateTextContainer(string title) => new Container
{
AutoSizeAxes = Axes.Both,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Children = new Drawable[]
{
text = new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
TextSize = text_size,
Text = title,
Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL },
},
textBold = new OsuSpriteText
{
AlwaysPresent = true,
Alpha = 0,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
TextSize = text_size,
Text = title,
Font = @"Exo2.0-Bold",
Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL },
}
}
};
public OsuContextMenuItem(string title, MenuItemType type = MenuItemType.Standard) : base(title)
{
this.type = type;
}
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
sampleHover = audio.Sample.Get(@"UI/generic-hover");
sampleClick = audio.Sample.Get(@"UI/generic-click");
BackgroundColour = Color4.Transparent;
BackgroundColourHover = OsuColour.FromHex(@"172023");
updateTextColour();
}
private void updateTextColour()
{
switch (type)
{
case MenuItemType.Standard:
textBold.Colour = text.Colour = Color4.White;
break;
case MenuItemType.Destructive:
textBold.Colour = text.Colour = Color4.Red;
break;
case MenuItemType.Highlighted:
textBold.Colour = text.Colour = OsuColour.FromHex(@"ffcc22");
break;
}
}
protected override bool OnHover(InputState state)
{
sampleHover.Play();
textBold.FadeIn(transition_length, Easing.OutQuint);
text.FadeOut(transition_length, Easing.OutQuint);
return base.OnHover(state);
}
protected override void OnHoverLost(InputState state)
{
textBold.FadeOut(transition_length, Easing.OutQuint);
text.FadeIn(transition_length, Easing.OutQuint);
base.OnHoverLost(state);
}
protected override bool OnClick(InputState state)
{
sampleClick.Play();
return base.OnClick(state);
}
}
}

View File

@ -14,107 +14,177 @@ using OpenTK;
namespace osu.Game.Graphics.UserInterface namespace osu.Game.Graphics.UserInterface
{ {
public class OsuDropdown<T> : Dropdown<T> public class OsuDropdown<T> : Dropdown<T>, IHasAccentColour
{ {
protected override DropdownHeader CreateHeader() => new OsuDropdownHeader { AccentColour = AccentColour }; private Color4 accentColour;
public Color4 AccentColour
protected override Menu CreateMenu() => new OsuMenu();
private Color4? accentColour;
public virtual Color4 AccentColour
{ {
get { return accentColour.GetValueOrDefault(); } get { return accentColour; }
set set
{ {
accentColour = value; accentColour = value;
if (Header != null) updateAccentColour();
((OsuDropdownHeader)Header).AccentColour = value;
foreach (var item in MenuItems.OfType<OsuDropdownMenuItem>())
item.AccentColour = value;
} }
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
if (accentColour == null) if (accentColour == default(Color4))
AccentColour = colours.PinkDarker; accentColour = colours.PinkDarker;
updateAccentColour();
} }
protected override DropdownMenuItem<T> CreateMenuItem(string text, T value) => new OsuDropdownMenuItem(text, value) { AccentColour = AccentColour }; private void updateAccentColour()
public class OsuDropdownMenuItem : DropdownMenuItem<T>
{ {
public OsuDropdownMenuItem(string text, T current) : base(text, current) var header = Header as IHasAccentColour;
if (header != null) header.AccentColour = accentColour;
var menu = Menu as IHasAccentColour;
if (menu != null) menu.AccentColour = accentColour;
}
protected override DropdownHeader CreateHeader() => new OsuDropdownHeader();
protected override DropdownMenu CreateMenu() => new OsuDropdownMenu();
#region OsuDropdownMenu
protected class OsuDropdownMenu : DropdownMenu, IHasAccentColour
{
// todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring
public OsuDropdownMenu()
{ {
Foreground.Padding = new MarginPadding(2); CornerRadius = 4;
BackgroundColour = Color4.Black.Opacity(0.5f);
Masking = true;
CornerRadius = 6;
Children = new[]
{
new FillFlowContainer
{
Direction = FillDirection.Horizontal,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Children = new Drawable[]
{
Chevron = new SpriteIcon
{
AlwaysPresent = true,
Icon = FontAwesome.fa_chevron_right,
Colour = Color4.Black,
Alpha = 0.5f,
Size = new Vector2(8),
Margin = new MarginPadding { Left = 3, Right = 3 },
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
},
Label = new OsuSpriteText {
Text = text,
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
}
}
}
};
} }
private Color4? accentColour; // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring
protected override void AnimateOpen() => this.FadeIn(300, Easing.OutQuint);
protected override void AnimateClose() => this.FadeOut(300, Easing.OutQuint);
protected readonly SpriteIcon Chevron; // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring
protected readonly OsuSpriteText Label; protected override MarginPadding ItemFlowContainerPadding => new MarginPadding(5);
protected override void FormatForeground(bool hover = false) // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring
protected override void UpdateMenuHeight()
{ {
base.FormatForeground(hover); var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight;
Chevron.Alpha = hover ? 1 : 0; this.ResizeHeightTo(State == MenuState.Opened ? actualHeight : 0, 300, Easing.OutQuint);
} }
private Color4 accentColour;
public Color4 AccentColour public Color4 AccentColour
{ {
get { return accentColour.GetValueOrDefault(); } get { return accentColour; }
set set
{ {
accentColour = value; accentColour = value;
BackgroundColourHover = BackgroundColourSelected = value; foreach (var c in Children.OfType<IHasAccentColour>())
FormatBackground(); c.AccentColour = value;
FormatForeground();
} }
} }
[BackgroundDependencyLoader] protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuDropdownMenuItem(item) { AccentColour = accentColour };
private void load(OsuColour colours)
{
BackgroundColour = Color4.Transparent;
BackgroundColourHover = accentColour ?? colours.PinkDarker;
BackgroundColourSelected = Color4.Black.Opacity(0.5f);
}
}
public class OsuDropdownHeader : DropdownHeader #region DrawableOsuDropdownMenuItem
protected class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem, IHasAccentColour
{
private Color4? accentColour;
public Color4 AccentColour
{
get { return accentColour ?? nonAccentSelectedColour; }
set
{
accentColour = value;
updateColours();
}
}
private void updateColours()
{
BackgroundColourHover = accentColour ?? nonAccentHoverColour;
BackgroundColourSelected = accentColour ?? nonAccentSelectedColour;
UpdateBackgroundColour();
UpdateForegroundColour();
}
private Color4 nonAccentHoverColour;
private Color4 nonAccentSelectedColour;
public DrawableOsuDropdownMenuItem(MenuItem item)
: base(item)
{
Foreground.Padding = new MarginPadding(2);
Masking = true;
CornerRadius = 6;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
BackgroundColour = Color4.Transparent;
nonAccentHoverColour = colours.PinkDarker;
nonAccentSelectedColour = Color4.Black.Opacity(0.5f);
updateColours();
}
protected override void UpdateForegroundColour()
{
base.UpdateForegroundColour();
var content = Foreground.Children.FirstOrDefault() as Content;
if (content != null) content.Chevron.Alpha = IsHovered ? 1 : 0;
}
protected override Drawable CreateContent() => new Content();
protected class Content : FillFlowContainer, IHasText
{
public string Text
{
get { return Label.Text; }
set { Label.Text = value; }
}
public readonly OsuSpriteText Label;
public readonly SpriteIcon Chevron;
public Content()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Direction = FillDirection.Horizontal;
Children = new Drawable[]
{
Chevron = new SpriteIcon
{
AlwaysPresent = true,
Icon = FontAwesome.fa_chevron_right,
Colour = Color4.Black,
Alpha = 0.5f,
Size = new Vector2(8),
Margin = new MarginPadding { Left = 3, Right = 3 },
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
},
Label = new OsuSpriteText
{
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
}
};
}
}
}
#endregion
}
#endregion
public class OsuDropdownHeader : DropdownHeader, IHasAccentColour
{ {
protected readonly SpriteText Text; protected readonly SpriteText Text;
protected override string Label protected override string Label
@ -125,14 +195,14 @@ namespace osu.Game.Graphics.UserInterface
protected readonly SpriteIcon Icon; protected readonly SpriteIcon Icon;
private Color4? accentColour; private Color4 accentColour;
public virtual Color4 AccentColour public virtual Color4 AccentColour
{ {
get { return accentColour.GetValueOrDefault(); } get { return accentColour; }
set set
{ {
accentColour = value; accentColour = value;
BackgroundColourHover = value; BackgroundColourHover = accentColour;
} }
} }
@ -167,7 +237,7 @@ namespace osu.Game.Graphics.UserInterface
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
BackgroundColour = Color4.Black.Opacity(0.5f); BackgroundColour = Color4.Black.Opacity(0.5f);
BackgroundColourHover = accentColour ?? colours.PinkDarker; BackgroundColourHover = colours.PinkDarker;
} }
} }
} }

View File

@ -1,11 +1,17 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK; using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Game.Graphics.Sprites;
namespace osu.Game.Graphics.UserInterface namespace osu.Game.Graphics.UserInterface
{ {
@ -14,19 +20,136 @@ namespace osu.Game.Graphics.UserInterface
public OsuMenu() public OsuMenu()
{ {
CornerRadius = 4; CornerRadius = 4;
Background.Colour = Color4.Black.Opacity(0.5f); BackgroundColour = Color4.Black.Opacity(0.5f);
ItemsContainer.Padding = new MarginPadding(5);
} }
protected override void AnimateOpen() => this.FadeIn(300, Easing.OutQuint); protected override void AnimateOpen() => this.FadeIn(300, Easing.OutQuint);
protected override void AnimateClose() => this.FadeOut(300, Easing.OutQuint); protected override void AnimateClose() => this.FadeOut(300, Easing.OutQuint);
protected override void UpdateContentHeight() protected override void UpdateMenuHeight()
{ {
var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight; var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight;
this.ResizeTo(new Vector2(1, State == MenuState.Opened ? actualHeight : 0), 300, Easing.OutQuint); this.ResizeHeightTo(State == MenuState.Opened ? actualHeight : 0, 300, Easing.OutQuint);
}
protected override MarginPadding ItemFlowContainerPadding => new MarginPadding(5);
protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuMenuItem(item);
protected class DrawableOsuMenuItem : DrawableMenuItem
{
private const int margin_horizontal = 17;
private const int text_size = 17;
private const int transition_length = 80;
public const int MARGIN_VERTICAL = 4;
private SampleChannel sampleClick;
private SampleChannel sampleHover;
private TextContainer text;
public DrawableOsuMenuItem(MenuItem item)
: base(item)
{
}
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
sampleHover = audio.Sample.Get(@"UI/generic-hover");
sampleClick = audio.Sample.Get(@"UI/generic-click");
BackgroundColour = Color4.Transparent;
BackgroundColourHover = OsuColour.FromHex(@"172023");
updateTextColour();
}
private void updateTextColour()
{
switch ((Item as OsuMenuItem)?.Type)
{
default:
case MenuItemType.Standard:
text.Colour = Color4.White;
break;
case MenuItemType.Destructive:
text.Colour = Color4.Red;
break;
case MenuItemType.Highlighted:
text.Colour = OsuColour.FromHex(@"ffcc22");
break;
}
}
protected override bool OnHover(InputState state)
{
sampleHover.Play();
text.BoldText.FadeIn(transition_length, Easing.OutQuint);
text.NormalText.FadeOut(transition_length, Easing.OutQuint);
return base.OnHover(state);
}
protected override void OnHoverLost(InputState state)
{
text.BoldText.FadeOut(transition_length, Easing.OutQuint);
text.NormalText.FadeIn(transition_length, Easing.OutQuint);
base.OnHoverLost(state);
}
protected override bool OnClick(InputState state)
{
sampleClick.Play();
return base.OnClick(state);
}
protected override Drawable CreateContent() => text = new TextContainer();
private class TextContainer : Container, IHasText
{
public string Text
{
get { return NormalText.Text; }
set
{
NormalText.Text = value;
BoldText.Text = value;
}
}
public readonly SpriteText NormalText;
public readonly SpriteText BoldText;
public TextContainer()
{
Anchor = Anchor.CentreLeft;
Origin = Anchor.CentreLeft;
AutoSizeAxes = Axes.Both;
Children = new Drawable[]
{
NormalText = new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
TextSize = text_size,
Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL },
},
BoldText = new OsuSpriteText
{
AlwaysPresent = true,
Alpha = 0,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
TextSize = text_size,
Font = @"Exo2.0-Bold",
Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL },
}
};
}
}
} }
} }
} }

View File

@ -0,0 +1,25 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Graphics.UserInterface;
namespace osu.Game.Graphics.UserInterface
{
public class OsuMenuItem : MenuItem
{
public readonly MenuItemType Type;
public OsuMenuItem(string text, MenuItemType type = MenuItemType.Standard)
: base(text)
{
Type = type;
}
public OsuMenuItem(string text, MenuItemType type, Action action)
: base(text, action)
{
Type = type;
}
}
}

View File

@ -37,34 +37,34 @@ namespace osu.Game.Graphics.UserInterface
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
if (accentColour == null) if (accentColour == default(Color4))
AccentColour = colours.Blue; AccentColour = colours.Blue;
} }
private Color4? accentColour; private Color4 accentColour;
public Color4 AccentColour public Color4 AccentColour
{ {
get { return accentColour.GetValueOrDefault(); } get { return accentColour; }
set set
{ {
accentColour = value; accentColour = value;
var dropDown = Dropdown as OsuTabDropdown; var dropdown = Dropdown as IHasAccentColour;
if (dropDown != null) if (dropdown != null)
dropDown.AccentColour = value; dropdown.AccentColour = value;
foreach (var item in TabContainer.Children.OfType<OsuTabItem>()) foreach (var i in TabContainer.Children.OfType<IHasAccentColour>())
item.AccentColour = value; i.AccentColour = value;
} }
} }
public class OsuTabItem : TabItem<T> public class OsuTabItem : TabItem<T>, IHasAccentColour
{ {
protected readonly SpriteText Text; protected readonly SpriteText Text;
private readonly Box box; private readonly Box box;
private Color4? accentColour; private Color4 accentColour;
public Color4 AccentColour public Color4 AccentColour
{ {
get { return accentColour.GetValueOrDefault(); } get { return accentColour; }
set set
{ {
accentColour = value; accentColour = value;
@ -103,7 +103,7 @@ namespace osu.Game.Graphics.UserInterface
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
if (accentColour == null) if (accentColour == default(Color4))
AccentColour = colours.Blue; AccentColour = colours.Blue;
} }
@ -140,38 +140,55 @@ namespace osu.Game.Graphics.UserInterface
protected override void OnDeactivated() => fadeInactive(); protected override void OnDeactivated() => fadeInactive();
} }
// todo: this needs to go
private class OsuTabDropdown : OsuDropdown<T> private class OsuTabDropdown : OsuDropdown<T>
{ {
protected override DropdownHeader CreateHeader() => new OsuTabDropdownHeader
{
AccentColour = AccentColour,
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
};
protected override DropdownMenuItem<T> CreateMenuItem(string text, T value)
{
var item = base.CreateMenuItem(text, value);
item.ForegroundColourHover = Color4.Black;
return item;
}
public OsuTabDropdown() public OsuTabDropdown()
{ {
DropdownMenu.Anchor = Anchor.TopRight;
DropdownMenu.Origin = Anchor.TopRight;
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
DropdownMenu.Background.Colour = Color4.Black.Opacity(0.7f);
DropdownMenu.MaxHeight = 400;
} }
protected override DropdownMenu CreateMenu() => new OsuTabDropdownMenu();
protected override DropdownHeader CreateHeader() => new OsuTabDropdownHeader
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight
};
private class OsuTabDropdownMenu : OsuDropdownMenu
{
public OsuTabDropdownMenu()
{
Anchor = Anchor.TopRight;
Origin = Anchor.TopRight;
BackgroundColour = Color4.Black.Opacity(0.7f);
MaxHeight = 400;
}
protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuTabDropdownMenuItem(item) { AccentColour = AccentColour };
private class DrawableOsuTabDropdownMenuItem : DrawableOsuDropdownMenuItem
{
public DrawableOsuTabDropdownMenuItem(MenuItem item)
: base(item)
{
ForegroundColourHover = Color4.Black;
}
}
}
protected class OsuTabDropdownHeader : OsuDropdownHeader protected class OsuTabDropdownHeader : OsuDropdownHeader
{ {
public override Color4 AccentColour public override Color4 AccentColour
{ {
get { return base.AccentColour; } get
{
return base.AccentColour;
}
set set
{ {
base.AccentColour = value; base.AccentColour = value;
@ -179,18 +196,6 @@ namespace osu.Game.Graphics.UserInterface
} }
} }
protected override bool OnHover(InputState state)
{
Foreground.Colour = BackgroundColour;
return base.OnHover(state);
}
protected override void OnHoverLost(InputState state)
{
Foreground.Colour = BackgroundColourHover;
base.OnHoverLost(state);
}
public OsuTabDropdownHeader() public OsuTabDropdownHeader()
{ {
RelativeSizeAxes = Axes.None; RelativeSizeAxes = Axes.None;
@ -220,6 +225,18 @@ namespace osu.Game.Graphics.UserInterface
Padding = new MarginPadding { Left = 5, Right = 5 }; Padding = new MarginPadding { Left = 5, Right = 5 };
} }
protected override bool OnHover(InputState state)
{
Foreground.Colour = BackgroundColour;
return base.OnHover(state);
}
protected override void OnHoverLost(InputState state)
{
Foreground.Colour = BackgroundColourHover;
base.OnHoverLost(state);
}
} }
} }
} }

View File

@ -15,15 +15,37 @@ namespace osu.Game.Overlays.Music
{ {
public class CollectionsDropdown<T> : OsuDropdown<T> public class CollectionsDropdown<T> : OsuDropdown<T>
{ {
protected override DropdownHeader CreateHeader() => new CollectionsHeader { AccentColour = AccentColour };
protected override Menu CreateMenu() => new CollectionsMenu();
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
AccentColour = colours.Gray6; AccentColour = colours.Gray6;
} }
protected override DropdownHeader CreateHeader() => new CollectionsHeader();
protected override DropdownMenu CreateMenu() => new CollectionsMenu();
private class CollectionsMenu : OsuDropdownMenu
{
public CollectionsMenu()
{
CornerRadius = 5;
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
Colour = Color4.Black.Opacity(0.3f),
Radius = 3,
Offset = new Vector2(0f, 1f),
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
BackgroundColour = colours.Gray4;
}
}
private class CollectionsHeader : OsuDropdownHeader private class CollectionsHeader : OsuDropdownHeader
{ {
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -48,26 +70,5 @@ namespace osu.Game.Overlays.Music
}; };
} }
} }
private class CollectionsMenu : OsuMenu
{
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Background.Colour = colours.Gray4;
}
public CollectionsMenu()
{
CornerRadius = 5;
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
Colour = Color4.Black.Opacity(0.3f),
Radius = 3,
Offset = new Vector2(0f, 1f),
};
}
}
} }
} }

View File

@ -12,8 +12,9 @@ namespace osu.Game.Overlays.SearchableList
{ {
public class SlimEnumDropdown<T> : OsuEnumDropdown<T> public class SlimEnumDropdown<T> : OsuEnumDropdown<T>
{ {
protected override DropdownHeader CreateHeader() => new SlimDropdownHeader { AccentColour = AccentColour }; protected override DropdownHeader CreateHeader() => new SlimDropdownHeader();
protected override Menu CreateMenu() => new SlimMenu();
protected override DropdownMenu CreateMenu() => new SlimMenu();
private class SlimDropdownHeader : OsuDropdownHeader private class SlimDropdownHeader : OsuDropdownHeader
{ {
@ -31,11 +32,11 @@ namespace osu.Game.Overlays.SearchableList
} }
} }
private class SlimMenu : OsuMenu private class SlimMenu : OsuDropdownMenu
{ {
public SlimMenu() public SlimMenu()
{ {
Background.Colour = Color4.Black.Opacity(0.7f); BackgroundColour = Color4.Black.Opacity(0.7f);
} }
} }
} }

View File

@ -257,9 +257,9 @@ namespace osu.Game.Overlays.Settings.Sections.General
private class UserDropdown : OsuEnumDropdown<UserAction> private class UserDropdown : OsuEnumDropdown<UserAction>
{ {
protected override DropdownHeader CreateHeader() => new UserDropdownHeader { AccentColour = AccentColour }; protected override DropdownHeader CreateHeader() => new UserDropdownHeader();
protected override Menu CreateMenu() => new UserDropdownMenu();
protected override DropdownMenuItem<UserAction> CreateMenuItem(string text, UserAction value) => new UserDropdownMenuItem(text, value) { AccentColour = AccentColour }; protected override DropdownMenu CreateMenu() => new UserDropdownMenu();
public Color4 StatusColour public Color4 StatusColour
{ {
@ -277,6 +277,49 @@ namespace osu.Game.Overlays.Settings.Sections.General
AccentColour = colours.Gray5; AccentColour = colours.Gray5;
} }
private class UserDropdownMenu : OsuDropdownMenu
{
public UserDropdownMenu()
{
Masking = true;
CornerRadius = 5;
Margin = new MarginPadding { Bottom = 5 };
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
Colour = Color4.Black.Opacity(0.25f),
Radius = 4,
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
BackgroundColour = colours.Gray3;
}
protected override MarginPadding ItemFlowContainerPadding => new MarginPadding();
protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableUserDropdownMenuItem(item);
private class DrawableUserDropdownMenuItem : DrawableOsuDropdownMenuItem
{
public DrawableUserDropdownMenuItem(MenuItem item)
: base(item)
{
Foreground.Padding = new MarginPadding { Top = 5, Bottom = 5, Left = 10, Right = 5 };
CornerRadius = 5;
}
protected override Drawable CreateContent() => new Content
{
Label = { Margin = new MarginPadding { Left = UserDropdownHeader.LABEL_LEFT_MARGIN - 11 } }
};
}
}
private class UserDropdownHeader : OsuDropdownHeader private class UserDropdownHeader : OsuDropdownHeader
{ {
public const float LABEL_LEFT_MARGIN = 20; public const float LABEL_LEFT_MARGIN = 20;
@ -324,38 +367,9 @@ namespace osu.Game.Overlays.Settings.Sections.General
} }
} }
private class UserDropdownMenu : OsuMenu
{
public UserDropdownMenu()
{
Margin = new MarginPadding { Bottom = 5 };
CornerRadius = 5;
ItemsContainer.Padding = new MarginPadding(0);
Masking = true;
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
Colour = Color4.Black.Opacity(0.25f),
Radius = 4,
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Background.Colour = colours.Gray3;
}
}
private class UserDropdownMenuItem : OsuDropdownMenuItem
{
public UserDropdownMenuItem(string text, UserAction current) : base(text, current)
{
Foreground.Padding = new MarginPadding { Top = 5, Bottom = 5, Left = 10, Right = 5 };
Label.Margin = new MarginPadding { Left = UserDropdownHeader.LABEL_LEFT_MARGIN - 11 };
CornerRadius = 5;
}
}
} }
private enum UserAction private enum UserAction

View File

@ -91,7 +91,7 @@
<Compile Include="Graphics\UserInterface\LineGraph.cs" /> <Compile Include="Graphics\UserInterface\LineGraph.cs" />
<Compile Include="Graphics\UserInterface\MenuItemType.cs" /> <Compile Include="Graphics\UserInterface\MenuItemType.cs" />
<Compile Include="Graphics\UserInterface\OsuContextMenu.cs" /> <Compile Include="Graphics\UserInterface\OsuContextMenu.cs" />
<Compile Include="Graphics\UserInterface\OsuContextMenuItem.cs" /> <Compile Include="Graphics\UserInterface\OsuMenuItem.cs" />
<Compile Include="Input\Bindings\DatabasedKeyBinding.cs" /> <Compile Include="Input\Bindings\DatabasedKeyBinding.cs" />
<Compile Include="Input\Bindings\DatabasedKeyBindingInputManager.cs" /> <Compile Include="Input\Bindings\DatabasedKeyBindingInputManager.cs" />
<Compile Include="Input\KeyBindingStore.cs" /> <Compile Include="Input\KeyBindingStore.cs" />