1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-28 12:23:21 +08:00

Merge branch 'master' into opaque-toolbar

This commit is contained in:
Dan Balasescu 2020-07-09 15:00:17 +09:00 committed by GitHub
commit fcf3d1ca89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 460 additions and 143 deletions

View File

@ -4,6 +4,7 @@
using osu.Framework.Bindables;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Judgements;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Osu.Objects
@ -24,6 +25,13 @@ namespace osu.Game.Rulesets.Osu.Objects
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
public override Judgement CreateJudgement() => new SliderRepeat.SliderRepeatJudgement();
public override Judgement CreateJudgement() => new SliderTailJudgement();
public class SliderTailJudgement : OsuJudgement
{
protected override int NumericResultFor(HitResult result) => 0;
public override bool AffectsCombo => false;
}
}
}

View File

@ -0,0 +1,52 @@
// 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 osu.Framework.Graphics.Containers;
using osu.Framework.Graphics;
using osu.Game.Overlays.News;
using osu.Game.Online.API.Requests.Responses;
using osu.Framework.Allocation;
using osu.Game.Overlays;
using osuTK;
using System;
namespace osu.Game.Tests.Visual.Online
{
public class TestSceneNewsCard : OsuTestScene
{
[Cached]
private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Purple);
public TestSceneNewsCard()
{
Add(new FillFlowContainer<NewsCard>
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Direction = FillDirection.Vertical,
Width = 500,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(0, 20),
Children = new[]
{
new NewsCard(new APINewsPost
{
Title = "This post has an image which starts with \"/\" and has many authors!",
Preview = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
Author = "someone, someone1, someone2, someone3, someone4",
FirstImage = "/help/wiki/shared/news/banners/monthly-beatmapping-contest.png",
PublishedAt = DateTimeOffset.Now
}),
new NewsCard(new APINewsPost
{
Title = "This post has a full-url image! (HTML entity: &amp;)",
Preview = "boom (HTML entity: &amp;)",
Author = "user (HTML entity: &amp;)",
FirstImage = "https://assets.ppy.sh/artists/88/header.jpg",
PublishedAt = DateTimeOffset.Now
})
}
});
}
}
}

View File

@ -0,0 +1,78 @@
// 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.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Sprites;
using osuTK;
namespace osu.Game.Graphics
{
public class DateTooltip : VisibilityContainer, ITooltip
{
private readonly OsuSpriteText dateText, timeText;
private readonly Box background;
public DateTooltip()
{
AutoSizeAxes = Axes.Both;
Masking = true;
CornerRadius = 5;
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both
},
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Padding = new MarginPadding(10),
Children = new Drawable[]
{
dateText = new OsuSpriteText
{
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold),
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
},
timeText = new OsuSpriteText
{
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular),
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
}
}
},
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
background.Colour = colours.GreySeafoamDarker;
timeText.Colour = colours.BlueLighter;
}
protected override void PopIn() => this.FadeIn(200, Easing.OutQuint);
protected override void PopOut() => this.FadeOut(200, Easing.OutQuint);
public bool SetContent(object content)
{
if (!(content is DateTimeOffset date))
return false;
dateText.Text = $"{date:d MMMM yyyy} ";
timeText.Text = $"{date:HH:mm:ss \"UTC\"z}";
return true;
}
public void Move(Vector2 pos) => Position = pos;
}
}

View File

@ -4,12 +4,9 @@
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Sprites;
using osu.Game.Utils;
using osuTK;
namespace osu.Game.Graphics
{
@ -81,69 +78,5 @@ namespace osu.Game.Graphics
public ITooltip GetCustomTooltip() => new DateTooltip();
public object TooltipContent => Date;
private class DateTooltip : VisibilityContainer, ITooltip
{
private readonly OsuSpriteText dateText, timeText;
private readonly Box background;
public DateTooltip()
{
AutoSizeAxes = Axes.Both;
Masking = true;
CornerRadius = 5;
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both
},
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Padding = new MarginPadding(10),
Children = new Drawable[]
{
dateText = new OsuSpriteText
{
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold),
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
},
timeText = new OsuSpriteText
{
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular),
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
}
}
},
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
background.Colour = colours.GreySeafoamDarker;
timeText.Colour = colours.BlueLighter;
}
protected override void PopIn() => this.FadeIn(200, Easing.OutQuint);
protected override void PopOut() => this.FadeOut(200, Easing.OutQuint);
public bool SetContent(object content)
{
if (!(content is DateTimeOffset date))
return false;
dateText.Text = $"{date:d MMMM yyyy} ";
timeText.Text = $"{date:HH:mm:ss \"UTC\"z}";
return true;
}
public void Move(Vector2 pos) => Position = pos;
}
}
}

View File

@ -23,6 +23,8 @@ namespace osu.Game.Graphics.UserInterface
{
private Color4 accentColour;
public const float HORIZONTAL_SPACING = 10;
public virtual Color4 AccentColour
{
get => accentColour;
@ -54,7 +56,7 @@ namespace osu.Game.Graphics.UserInterface
public OsuTabControl()
{
TabContainer.Spacing = new Vector2(10f, 0f);
TabContainer.Spacing = new Vector2(HORIZONTAL_SPACING, 0f);
AddInternal(strip = new Box
{

View File

@ -55,6 +55,9 @@ namespace osu.Game.Input
RulesetID = rulesetId,
Variant = variant
});
// required to ensure stable insert order (https://github.com/dotnet/efcore/issues/11686)
usage.Context.SaveChanges();
}
}
}

View File

@ -0,0 +1,57 @@
// 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 Newtonsoft.Json;
using System;
using System.Net;
namespace osu.Game.Online.API.Requests.Responses
{
public class APINewsPost
{
[JsonProperty("id")]
public long Id { get; set; }
private string author;
[JsonProperty("author")]
public string Author
{
get => author;
set => author = WebUtility.HtmlDecode(value);
}
[JsonProperty("edit_url")]
public string EditUrl { get; set; }
[JsonProperty("first_image")]
public string FirstImage { get; set; }
[JsonProperty("published_at")]
public DateTimeOffset PublishedAt { get; set; }
[JsonProperty("updated_at")]
public DateTimeOffset UpdatedAt { get; set; }
[JsonProperty("slug")]
public string Slug { get; set; }
private string title;
[JsonProperty("title")]
public string Title
{
get => title;
set => title = WebUtility.HtmlDecode(value);
}
private string preview;
[JsonProperty("preview")]
public string Preview
{
get => preview;
set => preview = WebUtility.HtmlDecode(value);
}
}
}

View File

@ -0,0 +1,198 @@
// 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.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Input.Events;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Overlays.News
{
public class NewsCard : CompositeDrawable
{
[Resolved]
private OverlayColourProvider colourProvider { get; set; }
private readonly APINewsPost post;
private Box background;
private TextFlowContainer main;
public NewsCard(APINewsPost post)
{
this.post = post;
}
[BackgroundDependencyLoader]
private void load()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Masking = true;
CornerRadius = 6;
NewsBackground bg;
InternalChildren = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background4
},
new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.X,
Height = 160,
Masking = true,
CornerRadius = 6,
Children = new Drawable[]
{
new DelayedLoadWrapper(bg = new NewsBackground(post.FirstImage)
{
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fill,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Alpha = 0
})
{
RelativeSizeAxes = Axes.Both
},
new DateContainer(post.PublishedAt)
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Margin = new MarginPadding
{
Top = 10,
Right = 15
}
}
}
},
new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding
{
Horizontal = 15,
Vertical = 10
},
Child = main = new TextFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
}
}
}
},
new HoverClickSounds()
};
bg.OnLoadComplete += d => d.FadeIn(250, Easing.In);
main.AddParagraph(post.Title, t => t.Font = OsuFont.GetFont(size: 20, weight: FontWeight.SemiBold));
main.AddParagraph(post.Preview, t => t.Font = OsuFont.GetFont(size: 12)); // Should use sans-serif font
main.AddParagraph("by ", t => t.Font = OsuFont.GetFont(size: 12));
main.AddText(post.Author, t => t.Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold));
}
protected override bool OnHover(HoverEvent e)
{
background.FadeColour(colourProvider.Background3, 200, Easing.OutQuint);
return true;
}
protected override void OnHoverLost(HoverLostEvent e)
{
background.FadeColour(colourProvider.Background4, 200, Easing.OutQuint);
base.OnHoverLost(e);
}
[LongRunningLoad]
private class NewsBackground : Sprite
{
private readonly string sourceUrl;
public NewsBackground(string sourceUrl)
{
this.sourceUrl = sourceUrl;
}
[BackgroundDependencyLoader]
private void load(LargeTextureStore store)
{
Texture = store.Get(createUrl(sourceUrl));
}
private string createUrl(string source)
{
if (string.IsNullOrEmpty(source))
return "Headers/news";
if (source.StartsWith('/'))
return "https://osu.ppy.sh" + source;
return source;
}
}
private class DateContainer : CircularContainer, IHasCustomTooltip
{
public ITooltip GetCustomTooltip() => new DateTooltip();
public object TooltipContent => date;
private readonly DateTimeOffset date;
public DateContainer(DateTimeOffset date)
{
this.date = date;
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
AutoSizeAxes = Axes.Both;
Masking = true;
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background6.Opacity(0.5f)
},
new OsuSpriteText
{
Text = date.ToString("d MMM yyyy").ToUpper(),
Font = OsuFont.GetFont(size: 10, weight: FontWeight.SemiBold),
Margin = new MarginPadding
{
Horizontal = 20,
Vertical = 5
}
}
};
}
}
}
}

View File

@ -51,7 +51,7 @@ namespace osu.Game.Screens.Menu
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.Solid.Poo,
Icon = FontAwesome.Solid.Flask,
Size = new Vector2(icon_size),
Y = icon_y,
},

View File

@ -95,22 +95,22 @@ namespace osu.Game.Screens.Multi
{
new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Font = OsuFont.GetFont(size: 24),
Text = "Multiplayer"
},
dot = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Font = OsuFont.GetFont(size: 24),
Text = "·"
},
pageTitle = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Font = OsuFont.GetFont(size: 24),
Text = "Lounge"
}

View File

@ -2,21 +2,20 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Select.Filter;
using Container = osu.Framework.Graphics.Containers.Container;
using osu.Framework.Graphics.Shapes;
using osu.Game.Configuration;
using osu.Game.Rulesets;
using osu.Framework.Input.Events;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osu.Game.Screens.Select.Filter;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Screens.Select
{
@ -26,9 +25,7 @@ namespace osu.Game.Screens.Select
public Action<FilterCriteria> FilterChanged;
private readonly OsuTabControl<SortMode> sortTabs;
private readonly TabControl<GroupMode> groupTabs;
private OsuTabControl<SortMode> sortTabs;
private Bindable<SortMode> sortMode;
@ -56,19 +53,39 @@ namespace osu.Game.Screens.Select
return criteria;
}
private readonly SeekLimitedSearchTextBox searchTextBox;
private SeekLimitedSearchTextBox searchTextBox;
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) =>
base.ReceivePositionalInputAt(screenSpacePos) || groupTabs.ReceivePositionalInputAt(screenSpacePos) || sortTabs.ReceivePositionalInputAt(screenSpacePos);
base.ReceivePositionalInputAt(screenSpacePos) || sortTabs.ReceivePositionalInputAt(screenSpacePos);
public FilterControl()
[BackgroundDependencyLoader(permitNulls: true)]
private void load(OsuColour colours, IBindable<RulesetInfo> parentRuleset, OsuConfigManager config)
{
config.BindWith(OsuSetting.ShowConvertedBeatmaps, showConverted);
showConverted.ValueChanged += _ => updateCriteria();
config.BindWith(OsuSetting.DisplayStarsMinimum, minimumStars);
minimumStars.ValueChanged += _ => updateCriteria();
config.BindWith(OsuSetting.DisplayStarsMaximum, maximumStars);
maximumStars.ValueChanged += _ => updateCriteria();
ruleset.BindTo(parentRuleset);
ruleset.BindValueChanged(_ => updateCriteria());
sortMode = config.GetBindable<SortMode>(OsuSetting.SongSelectSortingMode);
groupMode = config.GetBindable<GroupMode>(OsuSetting.SongSelectGroupingMode);
groupMode.BindValueChanged(_ => updateCriteria());
sortMode.BindValueChanged(_ => updateCriteria());
Children = new Drawable[]
{
Background = new Box
new Box
{
Colour = Color4.Black,
Alpha = 0.8f,
Width = 2,
RelativeSizeAxes = Axes.Both,
},
new Container
@ -96,33 +113,35 @@ namespace osu.Game.Screens.Select
Direction = FillDirection.Horizontal,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(OsuTabControl<SortMode>.HORIZONTAL_SPACING, 0),
Children = new Drawable[]
{
groupTabs = new OsuTabControl<GroupMode>
new OsuTabControlCheckbox
{
RelativeSizeAxes = Axes.X,
Height = 24,
Width = 0.5f,
AutoSort = true,
Text = "Show converted",
Current = config.GetBindable<bool>(OsuSetting.ShowConvertedBeatmaps),
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
},
//spriteText = new OsuSpriteText
//{
// Font = @"Exo2.0-Bold",
// Text = "Sort results by",
// Size = 14,
// Margin = new MarginPadding
// {
// Top = 5,
// Bottom = 5
// },
//},
sortTabs = new OsuTabControl<SortMode>
{
RelativeSizeAxes = Axes.X,
Width = 0.5f,
Height = 24,
AutoSort = true,
}
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
AccentColour = colours.GreenLight,
Current = { BindTarget = sortMode }
},
new OsuSpriteText
{
Text = "Sort by",
Font = OsuFont.GetFont(size: 14),
Margin = new MarginPadding(5),
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
},
}
},
}
@ -131,8 +150,7 @@ namespace osu.Game.Screens.Select
searchTextBox.Current.ValueChanged += _ => FilterChanged?.Invoke(CreateCriteria());
groupTabs.PinItem(GroupMode.All);
groupTabs.PinItem(GroupMode.RecentlyPlayed);
updateCriteria();
}
public void Deactivate()
@ -156,37 +174,6 @@ namespace osu.Game.Screens.Select
private readonly Bindable<double> minimumStars = new BindableDouble();
private readonly Bindable<double> maximumStars = new BindableDouble();
public readonly Box Background;
[BackgroundDependencyLoader(permitNulls: true)]
private void load(OsuColour colours, IBindable<RulesetInfo> parentRuleset, OsuConfigManager config)
{
sortTabs.AccentColour = colours.GreenLight;
config.BindWith(OsuSetting.ShowConvertedBeatmaps, showConverted);
showConverted.ValueChanged += _ => updateCriteria();
config.BindWith(OsuSetting.DisplayStarsMinimum, minimumStars);
minimumStars.ValueChanged += _ => updateCriteria();
config.BindWith(OsuSetting.DisplayStarsMaximum, maximumStars);
maximumStars.ValueChanged += _ => updateCriteria();
ruleset.BindTo(parentRuleset);
ruleset.BindValueChanged(_ => updateCriteria());
sortMode = config.GetBindable<SortMode>(OsuSetting.SongSelectSortingMode);
groupMode = config.GetBindable<GroupMode>(OsuSetting.SongSelectGroupingMode);
sortTabs.Current.BindTo(sortMode);
groupTabs.Current.BindTo(groupMode);
groupMode.BindValueChanged(_ => updateCriteria());
sortMode.BindValueChanged(_ => updateCriteria());
updateCriteria();
}
private void updateCriteria() => FilterChanged?.Invoke(CreateCriteria());
protected override bool OnClick(ClickEvent e) => true;

View File

@ -173,7 +173,6 @@ namespace osu.Game.Screens.Select
RelativeSizeAxes = Axes.X,
Height = FilterControl.HEIGHT,
FilterChanged = ApplyFilterToCarousel,
Background = { Width = 2 },
},
new GridContainer // used for max width implementation
{