Updated to use ppy's implementation

This commit is contained in:
MrTheMake
2017-07-14 12:08:56 +02:00
211 changed files with 2744 additions and 1414 deletions

View File

@ -12,10 +12,11 @@ using osu.Framework.Input;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Online.Chat;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.Chat
{
public class ChannelListItem : ClickableContainer, IFilterable
public class ChannelListItem : OsuClickableContainer, IFilterable
{
private const float width_padding = 5;
private const float channel_width = 150;

View File

@ -35,7 +35,7 @@ namespace osu.Game.Overlays.Chat
public IEnumerable<Channel> Channels
{
set { ChannelFlow.Children = value.Select(c => new ChannelListItem(c)); }
set { ChannelFlow.ChildrenEnumerable = value.Select(c => new ChannelListItem(c)); }
}
public ChannelSection()

View File

@ -16,10 +16,11 @@ using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.Chat;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.Chat
{
public class ChannelSelectionOverlay : FocusedOverlayContainer
public class ChannelSelectionOverlay : OsuFocusedOverlayContainer
{
public static readonly float WIDTH_PADDING = 170;
@ -38,7 +39,7 @@ namespace osu.Game.Overlays.Chat
{
set
{
sectionsFlow.Children = value;
sectionsFlow.ChildrenEnumerable = value;
foreach (ChannelSection s in sectionsFlow.Children)
{
@ -80,7 +81,7 @@ namespace osu.Game.Overlays.Chat
Padding = new MarginPadding { Top = 85, Right = WIDTH_PADDING },
Children = new[]
{
new ScrollContainer
new OsuScrollContainer
{
RelativeSizeAxes = Axes.Both,
Children = new[]

View File

@ -7,6 +7,7 @@ using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics.Containers;
using osu.Game.Online.Chat;
namespace osu.Game.Overlays.Chat
@ -25,7 +26,7 @@ namespace osu.Game.Overlays.Chat
Children = new Drawable[]
{
scroll = new ScrollContainer
scroll = new OsuScrollContainer
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
@ -67,7 +68,7 @@ namespace osu.Game.Overlays.Chat
var displayMessages = newMessages.Skip(Math.Max(0, newMessages.Count() - Channel.MAX_HISTORY));
//up to last Channel.MAX_HISTORY messages
flow.Add(displayMessages.Select(m => new ChatLine(m)));
flow.AddRange(displayMessages.Select(m => new ChatLine(m)));
if (!IsLoaded) return;

View File

@ -22,10 +22,11 @@ using osu.Framework.Input;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Overlays.Chat;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays
{
public class ChatOverlay : FocusedOverlayContainer, IOnlineComponent
public class ChatOverlay : OsuFocusedOverlayContainer, IOnlineComponent
{
private const float textbox_height = 60;
private const float channel_selection_min_height = 0.3f;
@ -59,7 +60,7 @@ namespace osu.Game.Overlays
private readonly Container channelSelectionContainer;
private readonly ChannelSelectionOverlay channelSelection;
public override bool Contains(Vector2 screenSpacePos) => chatContainer.Contains(screenSpacePos) || channelSelection.State == Visibility.Visible && channelSelection.Contains(screenSpacePos);
public override bool Contains(Vector2 screenSpacePos) => chatContainer.ReceiveMouseInputAt(screenSpacePos) || channelSelection.State == Visibility.Visible && channelSelection.ReceiveMouseInputAt(screenSpacePos);
public ChatOverlay()
{
@ -193,7 +194,7 @@ namespace osu.Game.Overlays
protected override bool OnDragStart(InputState state)
{
if (!channelTabs.Hovering)
if (!channelTabs.IsHovered)
return base.OnDragStart(state);
startDragChatHeight = chatHeight.Value;

View File

@ -15,10 +15,11 @@ using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.Dialog
{
public class PopupDialog : FocusedOverlayContainer
public class PopupDialog : OsuFocusedOverlayContainer
{
public static readonly float ENTER_DURATION = 500;
public static readonly float EXIT_DURATION = 200;
@ -56,7 +57,7 @@ namespace osu.Game.Overlays.Dialog
get { return buttonsContainer.Children; }
set
{
buttonsContainer.Children = value;
buttonsContainer.ChildrenEnumerable = value;
foreach (PopupDialogButton b in value)
{
var action = b.Action;

View File

@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Game.Graphics;
namespace osu.Game.Overlays.Dialog
@ -10,11 +9,9 @@ namespace osu.Game.Overlays.Dialog
public class PopupDialogCancelButton : PopupDialogButton
{
[BackgroundDependencyLoader]
private void load(OsuColour colours, AudioManager audio)
private void load(OsuColour colours)
{
ButtonColour = colours.Blue;
SampleHover = audio.Sample.Get(@"Menu/menuclick");
SampleClick = audio.Sample.Get(@"Menu/menuback");
}
}
}

View File

@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Game.Graphics;
namespace osu.Game.Overlays.Dialog
@ -10,11 +9,9 @@ namespace osu.Game.Overlays.Dialog
public class PopupDialogOkButton : PopupDialogButton
{
[BackgroundDependencyLoader]
private void load(OsuColour colours, AudioManager audio)
private void load(OsuColour colours)
{
ButtonColour = colours.Pink;
SampleHover = audio.Sample.Get(@"Menu/menuclick");
SampleClick = audio.Sample.Get(@"Menu/menu-play-click");
}
}
}

View File

@ -7,10 +7,11 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Overlays.Dialog;
using OpenTK.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays
{
public class DialogOverlay : FocusedOverlayContainer
public class DialogOverlay : OsuFocusedOverlayContainer
{
private readonly Container dialogContainer;
private PopupDialog currentDialog;

View File

@ -1,14 +1,12 @@
// 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.Linq;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Textures;
using osu.Framework.Localisation;
using osu.Game.Database;
using osu.Game.Graphics;
@ -50,7 +48,7 @@ namespace osu.Game.Overlays.Direct
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, LocalisationEngine localisation, TextureStore textures)
private void load(OsuColour colours, LocalisationEngine localisation)
{
Children = new[]
{
@ -59,7 +57,7 @@ namespace osu.Game.Overlays.Direct
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
},
GetBackground(textures),
CreateBackground(),
new Box
{
RelativeSizeAxes = Axes.Both,
@ -180,11 +178,11 @@ namespace osu.Game.Overlays.Direct
Margin = new MarginPadding { Top = vertical_padding, Right = vertical_padding },
Children = new[]
{
new Statistic(FontAwesome.fa_play_circle, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.PlayCount ?? 0)
new Statistic(FontAwesome.fa_play_circle, SetInfo.OnlineInfo?.PlayCount ?? 0)
{
Margin = new MarginPadding { Right = 1 },
},
new Statistic(FontAwesome.fa_heart, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.FavouriteCount ?? 0),
new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0),
},
},
};

View File

@ -12,10 +12,9 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Database;
using osu.Framework.Allocation;
using osu.Framework.Localisation;
using osu.Framework.Graphics.Textures;
using System.Linq;
using osu.Framework.Input;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.Direct
{
@ -48,7 +47,7 @@ namespace osu.Game.Overlays.Direct
}
[BackgroundDependencyLoader]
private void load(LocalisationEngine localisation, TextureStore textures)
private void load(LocalisationEngine localisation)
{
Children = new[]
{
@ -57,7 +56,7 @@ namespace osu.Game.Overlays.Direct
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
},
GetBackground(textures),
CreateBackground(),
new Box
{
RelativeSizeAxes = Axes.Both,
@ -104,11 +103,11 @@ namespace osu.Game.Overlays.Direct
Margin = new MarginPadding { Right = height - vertical_padding * 2 + vertical_padding },
Children = new Drawable[]
{
new Statistic(FontAwesome.fa_play_circle, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.PlayCount ?? 0)
new Statistic(FontAwesome.fa_play_circle, SetInfo.OnlineInfo?.PlayCount ?? 0)
{
Margin = new MarginPadding { Right = 1 },
},
new Statistic(FontAwesome.fa_heart, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.FavouriteCount ?? 0),
new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0),
new FillFlowContainer
{
Anchor = Anchor.TopRight,
@ -151,7 +150,7 @@ namespace osu.Game.Overlays.Direct
};
}
private class DownloadButton : ClickableContainer
private class DownloadButton : OsuClickableContainer
{
private readonly TextAwesome icon;

View File

@ -2,12 +2,10 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System.Linq;
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Database;
using osu.Game.Graphics;
@ -24,7 +22,7 @@ namespace osu.Game.Overlays.Direct
SetInfo = setInfo;
}
protected IEnumerable<DifficultyIcon> GetDifficultyIcons()
protected List<DifficultyIcon> GetDifficultyIcons()
{
var icons = new List<DifficultyIcon>();
@ -34,20 +32,25 @@ namespace osu.Game.Overlays.Direct
return icons;
}
protected Drawable GetBackground(TextureStore textures)
protected Drawable CreateBackground() => new DelayedLoadWrapper(new BeatmapSetCover(SetInfo)
{
return new AsyncLoadWrapper(new BeatmapBackgroundSprite(new OnlineWorkingBeatmap(SetInfo.Beatmaps.FirstOrDefault(), textures, null))
{
FillMode = FillMode.Fill,
OnLoadComplete = d => d.FadeInFromZero(400, EasingTypes.Out),
}) { RelativeSizeAxes = Axes.Both };
}
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fill,
OnLoadComplete = d => d.FadeInFromZero(400, EasingTypes.Out),
})
{
RelativeSizeAxes = Axes.Both,
TimeBeforeLoad = 300
};
public class Statistic : FillFlowContainer
{
private readonly SpriteText text;
private int value;
public int Value
{
get { return value; }

View File

@ -9,16 +9,18 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Overlays.SearchableList;
namespace osu.Game.Overlays.Direct
{
public class FilterControl : SearchableListFilterControl<DirectSortCritera, RankStatus>
public class FilterControl : SearchableListFilterControl<DirectSortCriteria, RankStatus>
{
public readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
private FillFlowContainer<RulesetToggleButton> modeButtons;
protected override Color4 BackgroundColour => OsuColour.FromHex(@"384552");
protected override DirectSortCritera DefaultTab => DirectSortCritera.Title;
protected override DirectSortCriteria DefaultTab => DirectSortCriteria.Ranked;
protected override Drawable CreateSupplementaryControls()
{
modeButtons = new FillFlowContainer<RulesetToggleButton>
@ -35,14 +37,14 @@ namespace osu.Game.Overlays.Direct
{
DisplayStyleControl.Dropdown.AccentColour = colours.BlueDark;
var b = new Bindable<RulesetInfo>(); //backup bindable incase the game is null
Ruleset.BindTo(game?.Ruleset ?? new Bindable<RulesetInfo> { Value = rulesets.GetRuleset(0) });
foreach (var r in rulesets.AllRulesets)
{
modeButtons.Add(new RulesetToggleButton(game?.Ruleset ?? b, r));
modeButtons.Add(new RulesetToggleButton(Ruleset, r));
}
}
private class RulesetToggleButton : ClickableContainer
private class RulesetToggleButton : OsuClickableContainer
{
private readonly TextAwesome icon;
@ -94,7 +96,7 @@ namespace osu.Game.Overlays.Direct
}
}
public enum DirectSortCritera
public enum DirectSortCriteria
{
Title,
Artist,
@ -102,5 +104,6 @@ namespace osu.Game.Overlays.Direct
Difficulty,
Ranked,
Rating,
Plays,
}
}

View File

@ -30,10 +30,10 @@ namespace osu.Game.Overlays.Direct
{
Search,
[Description("Newest Maps")]
NewestMaps,
NewestMaps = DirectSortCriteria.Ranked,
[Description("Top Rated")]
TopRated,
TopRated = DirectSortCriteria.Rating,
[Description("Most Played")]
MostPlayed
MostPlayed = DirectSortCriteria.Plays,
}
}

View File

@ -5,21 +5,28 @@ using System.Collections.Generic;
using System.Linq;
using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Threading;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Overlays.Direct;
using osu.Game.Overlays.SearchableList;
using OpenTK.Graphics;
namespace osu.Game.Overlays
{
public class DirectOverlay : SearchableListOverlay<DirectTab, DirectSortCritera, RankStatus>
public class DirectOverlay : SearchableListOverlay<DirectTab, DirectSortCriteria, RankStatus>
{
private const float panel_padding = 10f;
private APIAccess api;
private RulesetDatabase rulesets;
private readonly FillFlowContainer resultCountsContainer;
private readonly OsuSpriteText resultCountsText;
private readonly FillFlowContainer<DirectPanel> panels;
@ -29,7 +36,7 @@ namespace osu.Game.Overlays
protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"3f5265");
protected override SearchableListHeader<DirectTab> CreateHeader() => new Header();
protected override SearchableListFilterControl<DirectSortCritera, RankStatus> CreateFilterControl() => new FilterControl();
protected override SearchableListFilterControl<DirectSortCriteria, RankStatus> CreateFilterControl() => new FilterControl();
private IEnumerable<BeatmapSetInfo> beatmapSets;
public IEnumerable<BeatmapSetInfo> BeatmapSets
@ -40,6 +47,17 @@ namespace osu.Game.Overlays
if (beatmapSets?.Equals(value) ?? false) return;
beatmapSets = value;
if (BeatmapSets == null)
{
foreach (var p in panels.Children)
{
p.FadeOut(200);
p.Expire();
}
return;
}
recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value);
}
}
@ -98,22 +116,60 @@ namespace osu.Game.Overlays
},
};
Header.Tabs.Current.ValueChanged += tab => { if (tab != DirectTab.Search) Filter.Search.Text = string.Empty; };
Filter.Search.Current.ValueChanged += text => { if (text != string.Empty) Header.Tabs.Current.Value = DirectTab.Search; };
((FilterControl)Filter).Ruleset.ValueChanged += ruleset => Scheduler.AddOnce(updateSearch);
Filter.DisplayStyleControl.DisplayStyle.ValueChanged += recreatePanels;
Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += rankStatus => Scheduler.AddOnce(updateSearch);
Header.Tabs.Current.ValueChanged += tab =>
{
if (tab != DirectTab.Search)
{
currentQuery.Value = string.Empty;
Filter.Tabs.Current.Value = (DirectSortCriteria)Header.Tabs.Current.Value;
Scheduler.AddOnce(updateSearch);
}
};
currentQuery.ValueChanged += v =>
{
queryChangedDebounce?.Cancel();
if (string.IsNullOrEmpty(v))
Scheduler.AddOnce(updateSearch);
else
{
BeatmapSets = null;
ResultAmounts = null;
queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500);
}
};
currentQuery.BindTo(Filter.Search.Current);
Filter.Tabs.Current.ValueChanged += sortCriteria =>
{
if (Header.Tabs.Current.Value != DirectTab.Search && sortCriteria != (DirectSortCriteria)Header.Tabs.Current.Value)
Header.Tabs.Current.Value = DirectTab.Search;
Scheduler.AddOnce(updateSearch);
};
updateResultCounts();
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OsuColour colours, APIAccess api, RulesetDatabase rulesets)
{
this.api = api;
this.rulesets = rulesets;
resultCountsContainer.Colour = colours.Yellow;
}
private void updateResultCounts()
{
resultCountsContainer.FadeTo(ResultAmounts == null ? 0f : 1f, 200, EasingTypes.Out);
resultCountsContainer.FadeTo(ResultAmounts == null ? 0f : 1f, 200, EasingTypes.OutQuint);
if (ResultAmounts == null) return;
resultCountsText.Text = pluralize("Artist", ResultAmounts.Artists) + ", " +
@ -129,9 +185,68 @@ namespace osu.Game.Overlays
private void recreatePanels(PanelDisplayStyle displayStyle)
{
if (BeatmapSets == null) return;
panels.Children = BeatmapSets.Select(b => displayStyle == PanelDisplayStyle.Grid ? (DirectPanel)new DirectGridPanel(b) { Width = 400 } : new DirectListPanel(b));
panels.ChildrenEnumerable = BeatmapSets.Select<BeatmapSetInfo, DirectPanel>(b =>
{
switch (displayStyle)
{
case PanelDisplayStyle.Grid:
return new DirectGridPanel(b) { Width = 400 };
default:
return new DirectListPanel(b);
}
});
}
private GetBeatmapSetsRequest getSetsRequest;
private readonly Bindable<string> currentQuery = new Bindable<string>();
private ScheduledDelegate queryChangedDebounce;
private void updateSearch()
{
queryChangedDebounce?.Cancel();
if (!IsLoaded) return;
BeatmapSets = null;
ResultAmounts = null;
getSetsRequest?.Cancel();
if (api == null) return;
if (Header.Tabs.Current.Value == DirectTab.Search && (Filter.Search.Text == string.Empty || currentQuery == string.Empty)) return;
getSetsRequest = new GetBeatmapSetsRequest(currentQuery,
((FilterControl)Filter).Ruleset.Value,
Filter.DisplayStyleControl.Dropdown.Current.Value,
Filter.Tabs.Current.Value); //todo: sort direction (?)
getSetsRequest.Success += r =>
{
BeatmapSets = r?.Select(response => response.ToBeatmapSet(rulesets));
if (BeatmapSets == null) return;
var artists = new List<string>();
var songs = new List<string>();
var tags = new List<string>();
foreach (var s in BeatmapSets)
{
artists.Add(s.Metadata.Artist);
songs.Add(s.Metadata.Title);
tags.AddRange(s.Metadata.Tags.Split(' '));
}
ResultAmounts = new ResultCounts(distinctCount(artists), distinctCount(songs), distinctCount(tags));
};
api.Queue(getSetsRequest);
}
private int distinctCount(List<string> list) => list.Distinct().ToArray().Length;
public class ResultCounts
{
public readonly int Artists;

View File

@ -75,7 +75,7 @@ namespace osu.Game.Overlays
private void updatePosition(float position, bool easing = true)
{
position = MathHelper.Clamp(position, 0, 1);
Fill.TransformTo(() => Fill.Width, position, easing ? 200 : 0, EasingTypes.OutQuint, new TransformSeek());
Fill.TransformTo(position, easing ? 200 : 0, EasingTypes.OutQuint, new TransformSeek());
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
@ -100,11 +100,8 @@ namespace osu.Game.Overlays
private class TransformSeek : TransformFloat<Drawable>
{
public override void Apply(Drawable d)
{
base.Apply(d);
d.Width = CurrentValue;
}
public override void Apply(Drawable d) => d.Width = CurrentValue;
public override void ReadIntoStartValue(Drawable d) => StartValue = d.Width;
}
}
}

View File

@ -8,10 +8,11 @@ using osu.Game.Graphics;
using osu.Game.Overlays.Settings.Sections.General;
using OpenTK.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays
{
internal class LoginOverlay : FocusedOverlayContainer
internal class LoginOverlay : OsuFocusedOverlayContainer
{
private LoginSettings settingsSection;

View File

@ -0,0 +1,304 @@
// 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;
using OpenTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Sprites;
using osu.Game.Users;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Overlays.MedalSplash;
using osu.Framework.Allocation;
using osu.Framework.Audio.Sample;
using osu.Framework.Audio;
using osu.Framework.Graphics.Textures;
using osu.Framework.Input;
using OpenTK.Input;
using System.Linq;
using osu.Framework.Graphics.Shapes;
using System;
using osu.Framework.MathUtils;
namespace osu.Game.Overlays
{
public class MedalOverlay : FocusedOverlayContainer
{
public const float DISC_SIZE = 400;
private const float border_width = 5;
private readonly Medal medal;
private readonly Box background;
private readonly Container backgroundStrip, particleContainer;
private readonly BackgroundStrip leftStrip, rightStrip;
private readonly CircularContainer disc;
private readonly Sprite innerSpin, outerSpin;
private DrawableMedal drawableMedal;
private SampleChannel getSample;
public MedalOverlay(Medal medal)
{
this.medal = medal;
RelativeSizeAxes = Axes.Both;
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(60),
},
outerSpin = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(DISC_SIZE + 500),
Alpha = 0f,
},
backgroundStrip = new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
Height = border_width,
Alpha = 0f,
Children = new[]
{
new Container
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.CentreRight,
Width = 0.5f,
Padding = new MarginPadding { Right = DISC_SIZE / 2 },
Children = new[]
{
leftStrip = new BackgroundStrip(0f, 1f)
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
},
},
},
new Container
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.CentreLeft,
Width = 0.5f,
Padding = new MarginPadding { Left = DISC_SIZE / 2 },
Children = new[]
{
rightStrip = new BackgroundStrip(1f, 0f),
},
},
},
},
particleContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Alpha = 0f,
},
disc = new CircularContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Alpha = 0f,
Masking = true,
AlwaysPresent = true,
BorderColour = Color4.White,
BorderThickness = border_width,
Size = new Vector2(DISC_SIZE),
Scale = new Vector2(0.8f),
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex(@"05262f"),
},
new Triangles
{
RelativeSizeAxes = Axes.Both,
TriangleScale = 2,
ColourDark = OsuColour.FromHex(@"04222b"),
ColourLight = OsuColour.FromHex(@"052933"),
},
innerSpin = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(1.05f),
Alpha = 0.25f,
},
},
},
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, TextureStore textures, AudioManager audio)
{
getSample = audio.Sample.Get(@"MedalSplash/medal-get");
innerSpin.Texture = outerSpin.Texture = textures.Get(@"MedalSplash/disc-spin");
disc.EdgeEffect = leftStrip.EdgeEffect = rightStrip.EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Colour = colours.Blue.Opacity(0.5f),
Radius = 50,
};
disc.Add(drawableMedal = new DrawableMedal(medal)
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
});
}
protected override void LoadComplete()
{
base.LoadComplete();
Show();
}
protected override void Update()
{
base.Update();
particleContainer.Add(new MedalParticle(RNG.Next(0, 359)));
}
protected override bool OnClick(InputState state)
{
dismiss();
return true;
}
protected override void OnFocusLost(InputState state)
{
if (state.Keyboard.Keys.Contains(Key.Escape)) dismiss();
}
private const double initial_duration = 400;
private const double step_duration = 900;
protected override void PopIn()
{
base.PopIn();
FadeIn(200);
background.FlashColour(Color4.White.Opacity(0.25f), 400);
getSample.Play();
using (innerSpin.BeginLoopedSequence())
innerSpin.RotateTo(360, 20000);
using (outerSpin.BeginLoopedSequence())
outerSpin.RotateTo(360, 40000);
using (BeginDelayedSequence(200, true))
{
disc.FadeIn(initial_duration);
particleContainer.FadeIn(initial_duration);
outerSpin.FadeTo(0.1f, initial_duration * 2);
disc.ScaleTo(1f, initial_duration * 2, EasingTypes.OutElastic);
using (BeginDelayedSequence(initial_duration + 200, true))
{
backgroundStrip.FadeIn(step_duration);
leftStrip.ResizeWidthTo(1f, step_duration, EasingTypes.OutQuint);
rightStrip.ResizeWidthTo(1f, step_duration, EasingTypes.OutQuint);
Schedule(() => { if (drawableMedal.State != DisplayState.Full) drawableMedal.State = DisplayState.Icon; });
using (BeginDelayedSequence(step_duration, true))
{
Schedule(() => { if (drawableMedal.State != DisplayState.Full) drawableMedal.State = DisplayState.MedalUnlocked; });
using (BeginDelayedSequence(step_duration, true))
Schedule(() => { if (drawableMedal.State != DisplayState.Full) drawableMedal.State = DisplayState.Full; });
}
}
}
}
protected override void PopOut()
{
base.PopOut();
FadeOut(200);
}
private void dismiss()
{
if (drawableMedal.State != DisplayState.Full)
{
// if we haven't yet, play out the animation fully
drawableMedal.State = DisplayState.Full;
Flush(true);
return;
}
Hide();
Expire();
}
private class BackgroundStrip : Container
{
public BackgroundStrip(float start, float end)
{
RelativeSizeAxes = Axes.Both;
Width = 0f;
ColourInfo = ColourInfo.GradientHorizontal(Color4.White.Opacity(start), Color4.White.Opacity(end));
Masking = true;
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.White,
}
};
}
}
private class MedalParticle : CircularContainer
{
private readonly float direction;
private Vector2 positionForOffset(float offset) => new Vector2((float)(offset * Math.Sin(direction)), (float)(offset * Math.Cos(direction)));
public MedalParticle(float direction)
{
this.direction = direction;
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Position = positionForOffset(DISC_SIZE / 2);
Masking = true;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Colour = colours.Blue.Opacity(0.5f),
Radius = 5,
};
MoveTo(positionForOffset(DISC_SIZE / 2 + 200), 500);
FadeOut(500);
Expire();
}
}
}
}

View File

@ -0,0 +1,183 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework;
using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Users;
namespace osu.Game.Overlays.MedalSplash
{
public class DrawableMedal : Container, IStateful<DisplayState>
{
private const float scale_when_unlocked = 0.76f;
private const float scale_when_full = 0.6f;
private readonly Medal medal;
private readonly Container medalContainer;
private readonly Sprite medalSprite, medalGlow;
private readonly OsuSpriteText unlocked, name;
private readonly TextFlowContainer description;
private readonly FillFlowContainer infoFlow;
private DisplayState state;
public DrawableMedal(Medal medal)
{
this.medal = medal;
Position = new Vector2(0f, MedalOverlay.DISC_SIZE / 2);
Children = new Drawable[]
{
medalContainer = new Container
{
Anchor = Anchor.TopCentre,
Origin = Anchor.Centre,
AutoSizeAxes = Axes.Both,
Alpha = 0f,
Children = new Drawable[]
{
medalSprite = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(0.81f),
},
medalGlow = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
},
},
unlocked = new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = "Medal Unlocked".ToUpper(),
TextSize = 24,
Font = @"Exo2.0-Light",
Alpha = 0f,
Scale = new Vector2(1f / scale_when_unlocked),
},
infoFlow = new FillFlowContainer
{
Anchor = Anchor.TopCentre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Width = 0.6f,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0f, 5f),
Children = new Drawable[]
{
name = new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = medal.Name,
TextSize = 20,
Font = @"Exo2.0-Bold",
Alpha = 0f,
Scale = new Vector2(1f / scale_when_full),
},
description = new TextFlowContainer
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Alpha = 0f,
Scale = new Vector2(1f / scale_when_full),
},
},
},
};
description.AddText(medal.Description, s =>
{
s.Anchor = Anchor.TopCentre;
s.Origin = Anchor.TopCentre;
s.TextSize = 16;
});
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, TextureStore textures)
{
medalSprite.Texture = textures.Get(medal.ImageUrl);
medalGlow.Texture = textures.Get(@"MedalSplash/medal-glow");
description.Colour = colours.BlueLight;
unlocked.Position = new Vector2(0f, medalContainer.Size.Y / 2 + 10);
infoFlow.Position = new Vector2(0f, unlocked.Position.Y + 90);
}
protected override void LoadComplete()
{
base.LoadComplete();
updateState();
}
public DisplayState State
{
get { return state; }
set
{
if (state == value) return;
state = value;
updateState();
}
}
private void updateState()
{
if (!IsLoaded) return;
const double duration = 900;
switch (state)
{
case DisplayState.None:
medalContainer.ScaleTo(0);
break;
case DisplayState.Icon:
medalContainer.ScaleTo(1, duration, EasingTypes.OutElastic);
medalContainer.FadeIn(duration);
break;
case DisplayState.MedalUnlocked:
medalContainer.ScaleTo(1);
medalContainer.Show();
ScaleTo(scale_when_unlocked, duration, EasingTypes.OutExpo);
MoveToY(MedalOverlay.DISC_SIZE / 2 - 30, duration, EasingTypes.OutExpo);
unlocked.FadeInFromZero(duration);
break;
case DisplayState.Full:
medalContainer.ScaleTo(1);
medalContainer.Show();
ScaleTo(scale_when_full, duration, EasingTypes.OutExpo);
MoveToY(MedalOverlay.DISC_SIZE / 2 - 60, duration, EasingTypes.OutExpo);
name.FadeInFromZero(duration + 100);
description.FadeInFromZero(duration * 2);
break;
}
}
}
public enum DisplayState
{
None,
Icon,
MedalUnlocked,
Full,
}
}

View File

@ -151,8 +151,8 @@ namespace osu.Game.Overlays.Mods
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
sampleOn = audio.Sample.Get(@"Checkbox/check-on");
sampleOff = audio.Sample.Get(@"Checkbox/check-off");
sampleOn = audio.Sample.Get(@"UI/check-on");
sampleOff = audio.Sample.Get(@"UI/check-off");
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
@ -171,7 +171,7 @@ namespace osu.Game.Overlays.Mods
public void SelectNext()
{
(++SelectedIndex == -1 ? sampleOff : sampleOn).Play();
(++SelectedIndex == Mods.Length ? sampleOff : sampleOn).Play();
Action?.Invoke(SelectedMod);
}
@ -199,7 +199,7 @@ namespace osu.Game.Overlays.Mods
iconsContainer.Clear();
if (Mods.Length > 1)
{
iconsContainer.Add(new[]
iconsContainer.AddRange(new[]
{
backgroundIcon = new ModIcon(Mods[1])
{

View File

@ -7,6 +7,7 @@ using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Database;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.Music
{
@ -49,7 +50,7 @@ namespace osu.Game.Overlays.Music
{
Children = new Drawable[]
{
new ScrollContainer
new OsuScrollContainer
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]

View File

@ -24,10 +24,11 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Overlays.Music;
using osu.Game.Graphics.UserInterface;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays
{
public class MusicController : FocusedOverlayContainer
public class MusicController : OsuFocusedOverlayContainer
{
private const float player_height = 130;
@ -64,6 +65,9 @@ namespace osu.Game.Overlays
{
Width = 400;
Margin = new MarginPadding(10);
// required to let MusicController handle beatmap cycling.
AlwaysPresent = true;
}
protected override bool OnDragStart(InputState state) => true;
@ -283,12 +287,16 @@ namespace osu.Game.Overlays
private void prev()
{
if (beatmapBacking.Disabled) return;
queuedDirection = TransformDirection.Prev;
playlist.PlayPrevious();
}
private void next()
{
if (beatmapBacking.Disabled) return;
queuedDirection = TransformDirection.Next;
playlist.PlayNext();
}
@ -432,6 +440,7 @@ namespace osu.Game.Overlays
{
sprite = new Sprite
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(150),
FillMode = FillMode.Fill,
},

View File

@ -9,10 +9,11 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Overlays.Notifications;
using OpenTK.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays
{
public class NotificationManager : FocusedOverlayContainer
public class NotificationManager : OsuFocusedOverlayContainer
{
private const float width = 320;
@ -35,7 +36,7 @@ namespace osu.Game.Overlays
Colour = Color4.Black,
Alpha = 0.6f,
},
scrollContainer = new ScrollContainer
scrollContainer = new OsuScrollContainer
{
RelativeSizeAxes = Axes.Both,
Margin = new MarginPadding { Top = Toolbar.Toolbar.HEIGHT },

View File

@ -7,12 +7,12 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Input;
using osu.Game.Graphics;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.Notifications
{
@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Notifications
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
AddInternal(new Drawable[]
AddRangeInternal(new Drawable[]
{
Light = new NotificationLight
{
@ -152,7 +152,7 @@ namespace osu.Game.Overlays.Notifications
Expire();
}
private class CloseButton : ClickableContainer
private class CloseButton : OsuClickableContainer
{
private Color4 hoverColour;
@ -202,6 +202,8 @@ namespace osu.Game.Overlays.Notifications
get { return pulsate; }
set
{
if (pulsate == value) return;
pulsate = value;
pulsateLayer.ClearTransforms();
@ -210,25 +212,12 @@ namespace osu.Game.Overlays.Notifications
if (pulsate)
{
const float length = 1000;
pulsateLayer.Transforms.Add(new TransformAlpha
using (pulsateLayer.BeginLoopedSequence(length / 2))
{
StartTime = Time.Current,
EndTime = Time.Current + length,
StartValue = 1,
EndValue = 0.4f,
Easing = EasingTypes.In
});
pulsateLayer.Transforms.Add(new TransformAlpha
{
StartTime = Time.Current + length,
EndTime = Time.Current + length * 2,
StartValue = 0.4f,
EndValue = 1,
Easing = EasingTypes.Out
});
//todo: figure why we can't add arbitrary delays at the end of loop.
pulsateLayer.Loop(length * 2);
pulsateLayer.FadeTo(0.4f, length, EasingTypes.In);
using (pulsateLayer.BeginDelayedSequence(length))
pulsateLayer.FadeTo(1, length, EasingTypes.Out);
}
}
}
}

View File

@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using OpenTK;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.Notifications
{
@ -68,7 +69,7 @@ namespace osu.Game.Overlays.Notifications
Left = 20,
};
AddInternal(new Drawable[]
AddRangeInternal(new Drawable[]
{
new Container
{
@ -131,7 +132,7 @@ namespace osu.Game.Overlays.Notifications
countText.Text = notifications.Children.Count(c => c.Alpha > 0.99f).ToString();
}
private class ClearAllButton : ClickableContainer
private class ClearAllButton : OsuClickableContainer
{
private readonly OsuSpriteText text;

View File

@ -90,7 +90,7 @@ namespace osu.Game.Overlays.Notifications
private ProgressNotificationState state;
protected virtual Notification CreateCompletionNotification() => new ProgressCompletionNotification()
protected virtual Notification CreateCompletionNotification() => new ProgressCompletionNotification
{
Activated = CompletionClickAction,
Text = $"Task \"{Text}\" has completed!"

View File

@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Notifications
public SimpleNotification()
{
IconContent.Add(new Drawable[]
IconContent.AddRange(new Drawable[]
{
IconBackgound = new Box
{

View File

@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Extensions;
@ -182,7 +181,7 @@ namespace osu.Game.Overlays
textLine2.Origin = optionCount > 0 ? Anchor.BottomCentre : Anchor.Centre;
textLine2.Y = optionCount > 0 ? 0 : 5;
if (optionLights.Children.Count() != optionCount)
if (optionLights.Children.Count != optionCount)
{
optionLights.Clear();
for (int i = 0; i < optionCount; i++)
@ -190,7 +189,7 @@ namespace osu.Game.Overlays
}
for (int i = 0; i < optionCount; i++)
optionLights.Children.Skip(i).First().Glowing = i == selectedOption;
optionLights.Children[i].Glowing = i == selectedOption;
});
}
@ -261,8 +260,6 @@ namespace osu.Game.Overlays
Radius = 8,
};
FadeEdgeEffectTo(0);
updateGlow();
Flush(true);
}

View File

@ -6,6 +6,7 @@ using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.SearchableList
{
@ -52,7 +53,7 @@ namespace osu.Game.Overlays.SearchableList
DisplayStyle.Value = PanelDisplayStyle.Grid;
}
private class DisplayStyleToggleButton : ClickableContainer
private class DisplayStyleToggleButton : OsuClickableContainer
{
private readonly TextAwesome icon;
private readonly PanelDisplayStyle style;

View File

@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
@ -29,8 +28,6 @@ namespace osu.Game.Overlays.SearchableList
protected abstract T DefaultTab { get; }
protected virtual Drawable CreateSupplementaryControls() => null;
public override bool Contains(Vector2 screenSpacePos) => base.Contains(screenSpacePos) || DisplayStyleControl.Dropdown.Contains(screenSpacePos);
protected SearchableListFilterControl()
{
if (!typeof(T).IsEnum)
@ -123,6 +120,7 @@ namespace osu.Game.Overlays.SearchableList
{
protected override Color4 BackgroundUnfocused => backgroundColour;
protected override Color4 BackgroundFocused => backgroundColour;
protected override bool AllowCommit => true;
private Color4 backgroundColour;

View File

@ -7,6 +7,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.SearchableList
{
@ -60,7 +61,7 @@ namespace osu.Game.Overlays.SearchableList
RelativeSizeAxes = Axes.Both,
Children = new[]
{
new ScrollContainer
new OsuScrollContainer
{
RelativeSizeAxes = Axes.Both,
ScrollbarVisible = false,

View File

@ -34,7 +34,7 @@ namespace osu.Game.Overlays.SearchableList
{
public SlimMenu()
{
Background.Colour = Color4.Black.Opacity(0.25f);
Background.Colour = Color4.Black.Opacity(0.7f);
}
}
}

View File

@ -1,9 +1,13 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Overlays.Settings.Sections.Gameplay;
using osu.Game.Rulesets;
using System.Linq;
namespace osu.Game.Overlays.Settings.Sections
{
@ -20,5 +24,16 @@ namespace osu.Game.Overlays.Settings.Sections
new SongSelectSettings(),
};
}
[BackgroundDependencyLoader]
private void load(RulesetDatabase rulesets)
{
foreach(Ruleset ruleset in rulesets.AllRulesets.Select(info => info.CreateInstance()))
{
SettingsSubsection section = ruleset.CreateSettings();
if (section != null)
Add(section);
}
}
}
}

View File

@ -1,32 +1,10 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Configuration;
namespace osu.Game.Overlays.Settings.Sections.Graphics
{
public class DetailSettings : SettingsSubsection
{
protected override string Header => "Detail Settings";
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
Children = new Drawable[]
{
new SettingsCheckbox
{
LabelText = "Snaking in sliders",
Bindable = config.GetBindable<bool>(OsuSetting.SnakingInSliders)
},
new SettingsCheckbox
{
LabelText = "Snaking out sliders",
Bindable = config.GetBindable<bool>(OsuSetting.SnakingOutSliders)
},
};
}
}
}

View File

@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Settings
if (text == null)
{
// construct lazily for cases where the label is not needed (may be provided by the Control).
Add(text = new OsuSpriteText() { Depth = 1 });
Add(text = new OsuSpriteText { Depth = 1 });
}
text.Text = value;

View File

@ -44,7 +44,7 @@ namespace osu.Game.Overlays.Settings
const int header_size = 26;
const int header_margin = 25;
const int border_size = 2;
AddInternal(new Drawable[]
AddRangeInternal(new Drawable[]
{
new Box
{

View File

@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Settings
where T : struct, IEquatable<T>
where U : SliderBar<T>, new()
{
protected override Drawable CreateControl() => new U()
protected override Drawable CreateControl() => new U
{
Margin = new MarginPadding { Top = 5, Bottom = 5 },
RelativeSizeAxes = Axes.X

View File

@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Settings
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Direction = FillDirection.Vertical;
AddInternal(new Drawable[]
AddRangeInternal(new Drawable[]
{
new OsuSpriteText
{

View File

@ -1,6 +1,8 @@
// 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.Linq;
using osu.Framework;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics;
@ -12,7 +14,7 @@ using osu.Game.Overlays.Toolbar;
namespace osu.Game.Overlays.Settings
{
public class Sidebar : Container
public class Sidebar : Container, IStateful<ExpandedState>
{
private readonly FillFlowContainer content;
internal const float DEFAULT_WIDTH = ToolbarButton.WIDTH;
@ -47,24 +49,29 @@ namespace osu.Game.Overlays.Settings
}
private ScheduledDelegate expandEvent;
private ExpandedState state;
protected override bool OnHover(InputState state)
{
expandEvent = Scheduler.AddDelayed(() =>
{
expandEvent = null;
ResizeTo(new Vector2(EXPANDED_WIDTH, Height), 150, EasingTypes.OutQuad);
}, 750);
queueExpandIfHovering();
return true;
}
protected override void OnHoverLost(InputState state)
{
expandEvent?.Cancel();
ResizeTo(new Vector2(DEFAULT_WIDTH, Height), 150, EasingTypes.OutQuad);
lastHoveredButton = null;
State = ExpandedState.Contracted;
base.OnHoverLost(state);
}
protected override bool OnMouseMove(InputState state)
{
queueExpandIfHovering();
return base.OnMouseMove(state);
}
private class SidebarScrollContainer : ScrollContainer
{
public SidebarScrollContainer()
@ -74,5 +81,52 @@ namespace osu.Game.Overlays.Settings
RelativeSizeAxes = Axes.Both;
}
}
public ExpandedState State
{
get { return state; }
set
{
if (state == value) return;
state = value;
switch (state)
{
default:
ResizeTo(new Vector2(DEFAULT_WIDTH, Height), 500, EasingTypes.OutQuint);
break;
case ExpandedState.Expanded:
ResizeTo(new Vector2(EXPANDED_WIDTH, Height), 500, EasingTypes.OutQuint);
break;
}
}
}
private Drawable lastHoveredButton;
private Drawable hoveredButton => content.Children.FirstOrDefault(c => c.IsHovered);
private void queueExpandIfHovering()
{
// only expand when we hover a different button.
if (lastHoveredButton == hoveredButton) return;
if (!IsHovered) return;
if (State != ExpandedState.Expanded)
{
expandEvent?.Cancel();
expandEvent = Scheduler.AddDelayed(() => State = ExpandedState.Expanded, 750);
}
lastHoveredButton = hoveredButton;
}
}
public enum ExpandedState
{
Contracted,
Expanded,
}
}

View File

@ -1,6 +1,7 @@
// 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 System.Linq;
using OpenTK.Graphics;
using osu.Framework.Allocation;
@ -15,7 +16,7 @@ using osu.Game.Overlays.Settings.Sections;
namespace osu.Game.Overlays
{
public class SettingsOverlay : FocusedOverlayContainer
public class SettingsOverlay : OsuFocusedOverlayContainer
{
internal const float CONTENT_MARGINS = 10;
@ -35,6 +36,8 @@ namespace osu.Game.Overlays
private SearchTextBox searchTextBox;
private Func<float> getToolbarHeight;
public SettingsOverlay()
{
RelativeSizeAxes = Axes.Y;
@ -93,7 +96,11 @@ namespace osu.Game.Overlays
new SidebarButton
{
Section = section,
Action = sectionsContainer.ScrollContainer.ScrollIntoView,
Action = s =>
{
sectionsContainer.ScrollTo(s);
sidebar.State = ExpandedState.Contracted;
},
}
).ToArray()
}
@ -111,7 +118,7 @@ namespace osu.Game.Overlays
searchTextBox.Current.ValueChanged += newValue => sectionsContainer.SearchContainer.SearchTerm = newValue;
sectionsContainer.Padding = new MarginPadding { Top = game?.Toolbar.DrawHeight ?? 0 };
getToolbarHeight = () => game?.ToolbarOffset ?? 0;
}
protected override void PopIn()
@ -148,6 +155,14 @@ namespace osu.Game.Overlays
base.OnFocus(state);
}
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
sectionsContainer.Margin = new MarginPadding { Left = sidebar.DrawWidth };
sectionsContainer.Padding = new MarginPadding { Top = getToolbarHeight() };
}
private class SettingsSectionsContainer : SectionsContainer
{
public SearchContainer SearchContainer;

View File

@ -44,7 +44,7 @@ namespace osu.Game.Overlays
panelFlow.Clear();
else
{
panelFlow.Children = users.Select(u =>
panelFlow.ChildrenEnumerable = users.Select(u =>
{
var p = new UserPanel(u) { Width = 300 };
p.Status.BindTo(u.Status);

View File

@ -1,10 +1,6 @@
// 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.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -16,10 +12,11 @@ using osu.Game.Graphics.Sprites;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.Toolbar
{
public class ToolbarButton : Container
public class ToolbarButton : OsuClickableContainer
{
public const float WIDTH = Toolbar.HEIGHT * 1.4f;
@ -58,7 +55,6 @@ namespace osu.Game.Overlays.Toolbar
protected virtual Anchor TooltipAnchor => Anchor.TopLeft;
public Action Action;
protected TextAwesome DrawableIcon;
protected SpriteText DrawableText;
protected Box HoverBackground;
@ -66,7 +62,6 @@ namespace osu.Game.Overlays.Toolbar
private readonly SpriteText tooltip1;
private readonly SpriteText tooltip2;
protected FillFlowContainer Flow;
private SampleChannel sampleClick;
public ToolbarButton()
{
@ -136,27 +131,19 @@ namespace osu.Game.Overlays.Toolbar
};
}
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
sampleClick = audio.Sample.Get(@"Menu/menuclick");
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => true;
protected override bool OnClick(InputState state)
{
Action?.Invoke();
sampleClick.Play();
HoverBackground.FlashColour(Color4.White.Opacity(100), 500, EasingTypes.OutQuint);
return true;
return base.OnClick(state);
}
protected override bool OnHover(InputState state)
{
HoverBackground.FadeIn(200);
tooltipContainer.FadeIn(100);
return false;
return base.OnHover(state);
}
protected override void OnHoverLost(InputState state)

View File

@ -113,8 +113,11 @@ namespace osu.Game.Overlays.Toolbar
{
base.UpdateAfterChildren();
if (!activeMode.EnsureValid())
activeMode.Refresh(() => modeButtonLine.MoveToX(activeButton.DrawPosition.X, 200, EasingTypes.OutQuint));
if (!activeMode.IsValid)
{
modeButtonLine.MoveToX(activeButton.DrawPosition.X, 200, EasingTypes.OutQuint);
activeMode.Validate();
}
}
}
}

View File

@ -8,10 +8,11 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics;
using System;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays
{
public abstract class WaveOverlayContainer : FocusedOverlayContainer
public abstract class WaveOverlayContainer : OsuFocusedOverlayContainer
{
protected const float APPEAR_DURATION = 800;
protected const float DISAPPEAR_DURATION = 500;