mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 20:22:55 +08:00
Merge branch 'master' into new-option-search
This commit is contained in:
commit
815379646c
@ -1 +1 @@
|
||||
Subproject commit a1a62c14a51654c933c5b077c725d566f167145b
|
||||
Subproject commit e1ac6316aa3862efb8e79e585a7b4c901a4e1b3c
|
@ -18,10 +18,14 @@ namespace osu.Desktop.VisualTests.Tests
|
||||
private SongProgress progress;
|
||||
private SongProgressGraph graph;
|
||||
|
||||
private StopwatchClock clock;
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
|
||||
clock = new StopwatchClock(true);
|
||||
|
||||
Add(progress = new SongProgress
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
@ -55,6 +59,9 @@ namespace osu.Desktop.VisualTests.Tests
|
||||
|
||||
progress.Objects = objects;
|
||||
graph.Objects = objects;
|
||||
|
||||
progress.AudioClock = clock;
|
||||
progress.OnSeek = pos => clock.Seek(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Screens.Select;
|
||||
|
||||
namespace osu.Game.Configuration
|
||||
@ -19,6 +20,8 @@ namespace osu.Game.Configuration
|
||||
Set(OsuConfig.DisplayStarsMinimum, 0.0, 0, 10);
|
||||
Set(OsuConfig.DisplayStarsMaximum, 10.0, 0, 10);
|
||||
|
||||
Set(OsuConfig.ChatDisplayHeight, ChatOverlay.DEFAULT_HEIGHT, 0.2, 1);
|
||||
|
||||
// Online settings
|
||||
|
||||
Set(OsuConfig.Username, string.Empty);
|
||||
@ -102,6 +105,7 @@ namespace osu.Game.Configuration
|
||||
DisplayStarsMaximum,
|
||||
SnakingInSliders,
|
||||
SnakingOutSliders,
|
||||
ShowFpsDisplay
|
||||
ShowFpsDisplay,
|
||||
ChatDisplayHeight
|
||||
}
|
||||
}
|
||||
|
@ -85,5 +85,7 @@ namespace osu.Game.Graphics
|
||||
public readonly Color4 Red = FromHex(@"ed1121");
|
||||
public readonly Color4 RedDark = FromHex(@"ba0011");
|
||||
public readonly Color4 RedDarker = FromHex(@"870000");
|
||||
|
||||
public readonly Color4 ChatBlue = FromHex(@"17292e");
|
||||
}
|
||||
}
|
||||
|
@ -25,15 +25,15 @@ namespace osu.Game.Graphics.UserInterface
|
||||
|
||||
protected override bool InternalContains(Vector2 screenSpacePos) => base.InternalContains(screenSpacePos) || Dropdown.Contains(screenSpacePos);
|
||||
|
||||
private bool isEnumType => typeof(T).IsEnum;
|
||||
|
||||
public OsuTabControl()
|
||||
{
|
||||
TabContainer.Spacing = new Vector2(10f, 0f);
|
||||
|
||||
if (!typeof(T).IsEnum)
|
||||
throw new InvalidOperationException("OsuTabControl only supports enums as the generic type argument");
|
||||
|
||||
foreach (var val in (T[])Enum.GetValues(typeof(T)))
|
||||
AddItem(val);
|
||||
if (isEnumType)
|
||||
foreach (var val in (T[])Enum.GetValues(typeof(T)))
|
||||
AddItem(val);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -136,7 +136,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
Margin = new MarginPadding { Top = 5, Bottom = 5 },
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Text = (value as Enum)?.GetDescription(),
|
||||
Text = (value as Enum)?.GetDescription() ?? value.ToString(),
|
||||
TextSize = 14,
|
||||
Font = @"Exo2.0-Bold", // Font should only turn bold when active?
|
||||
},
|
||||
|
@ -1,26 +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 System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input;
|
||||
|
||||
namespace osu.Game.Input
|
||||
{
|
||||
public class GlobalHotkeys : Drawable
|
||||
{
|
||||
public Func<InputState, KeyDownEventArgs, bool> Handler;
|
||||
|
||||
public override bool HandleInput => true;
|
||||
|
||||
public GlobalHotkeys()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||
{
|
||||
return Handler(state, args);
|
||||
}
|
||||
}
|
||||
}
|
@ -72,21 +72,28 @@ namespace osu.Game.Online.API
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly object access_token_retrieval_lock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Should be run before any API request to make sure we have a valid key.
|
||||
/// </summary>
|
||||
private bool ensureAccessToken()
|
||||
{
|
||||
//todo: we need to mutex this to ensure only one authentication request is running at a time.
|
||||
|
||||
//If we already have a valid access token, let's use it.
|
||||
// if we already have a valid access token, let's use it.
|
||||
if (accessTokenValid) return true;
|
||||
|
||||
//If not, let's try using our refresh token to request a new access token.
|
||||
if (!string.IsNullOrEmpty(Token?.RefreshToken))
|
||||
AuthenticateWithRefresh(Token.RefreshToken);
|
||||
// we want to ensure only a single authentication update is happening at once.
|
||||
lock (access_token_retrieval_lock)
|
||||
{
|
||||
// re-check if valid, in case another request completed and revalidated our access.
|
||||
if (accessTokenValid) return true;
|
||||
|
||||
return accessTokenValid;
|
||||
// if not, let's try using our refresh token to request a new access token.
|
||||
if (!string.IsNullOrEmpty(Token?.RefreshToken))
|
||||
AuthenticateWithRefresh(Token.RefreshToken);
|
||||
|
||||
return accessTokenValid;
|
||||
}
|
||||
}
|
||||
|
||||
private bool accessTokenValid => Token?.IsValid ?? false;
|
||||
|
@ -41,13 +41,13 @@ namespace osu.Game.Online.API
|
||||
[JsonProperty(@"refresh_token")]
|
||||
public string RefreshToken;
|
||||
|
||||
public override string ToString() => $@"{AccessToken}/{AccessTokenExpiry.ToString(NumberFormatInfo.InvariantInfo)}/{RefreshToken}";
|
||||
public override string ToString() => $@"{AccessToken}|{AccessTokenExpiry.ToString(NumberFormatInfo.InvariantInfo)}|{RefreshToken}";
|
||||
|
||||
public static OAuthToken Parse(string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] parts = value.Split('/');
|
||||
string[] parts = value.Split('|');
|
||||
return new OAuthToken
|
||||
{
|
||||
AccessToken = parts[0],
|
||||
|
@ -27,6 +27,8 @@ namespace osu.Game.Online.Chat
|
||||
|
||||
//internal bool Joined;
|
||||
|
||||
public bool ReadOnly => Name != "#lazer";
|
||||
|
||||
public const int MAX_HISTORY = 300;
|
||||
|
||||
[JsonConstructor]
|
||||
@ -53,5 +55,7 @@ namespace osu.Game.Online.Chat
|
||||
if (messageCount > MAX_HISTORY)
|
||||
Messages.RemoveRange(0, messageCount - MAX_HISTORY);
|
||||
}
|
||||
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Input;
|
||||
using OpenTK.Input;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Graphics.UserInterface.Volume;
|
||||
@ -161,7 +160,7 @@ namespace osu.Game
|
||||
});
|
||||
|
||||
//overlay elements
|
||||
LoadComponentAsync(chat = new ChatOverlay { Depth = 0 }, overlayContent.Add);
|
||||
LoadComponentAsync(chat = new ChatOverlay { Depth = -1 }, mainContent.Add);
|
||||
LoadComponentAsync(options = new OptionsOverlay { Depth = -1 }, overlayContent.Add);
|
||||
LoadComponentAsync(musicController = new MusicController
|
||||
{
|
||||
@ -321,8 +320,7 @@ namespace osu.Game
|
||||
{
|
||||
base.UpdateAfterChildren();
|
||||
|
||||
if (intro?.ChildScreen != null)
|
||||
intro.ChildScreen.Padding = new MarginPadding { Top = Toolbar.Position.Y + Toolbar.DrawHeight };
|
||||
mainContent.Padding = new MarginPadding { Top = Toolbar.Position.Y + Toolbar.DrawHeight };
|
||||
|
||||
Cursor.State = currentScreen?.HasLocalCursorDisplayed == false ? Visibility.Visible : Visibility.Hidden;
|
||||
}
|
||||
|
@ -6,10 +6,11 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Chat;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Online.Chat.Drawables
|
||||
namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
public class ChatLine : Container
|
||||
{
|
||||
@ -62,7 +63,10 @@ namespace osu.Game.Online.Chat.Drawables
|
||||
return username_colours[message.UserId % username_colours.Length];
|
||||
}
|
||||
|
||||
private const float padding = 200;
|
||||
public const float LEFT_PADDING = message_padding + padding * 2;
|
||||
|
||||
private const float padding = 15;
|
||||
private const float message_padding = 200;
|
||||
private const float text_size = 20;
|
||||
|
||||
public ChatLine(Message message)
|
||||
@ -72,13 +76,13 @@ namespace osu.Game.Online.Chat.Drawables
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
Padding = new MarginPadding { Left = 15, Right = 15 };
|
||||
Padding = new MarginPadding { Left = padding, Right = padding };
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Size = new Vector2(padding, text_size),
|
||||
Size = new Vector2(message_padding, text_size),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
@ -106,7 +110,7 @@ namespace osu.Game.Online.Chat.Drawables
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Left = padding + 15 },
|
||||
Padding = new MarginPadding { Left = message_padding + padding },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
182
osu.Game/Overlays/Chat/ChatTabControl.cs
Normal file
182
osu.Game/Overlays/Chat/ChatTabControl.cs
Normal file
@ -0,0 +1,182 @@
|
||||
// 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.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Chat;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
public class ChatTabControl : OsuTabControl<Channel>
|
||||
{
|
||||
protected override TabItem<Channel> CreateTabItem(Channel value) => new ChannelTabItem(value);
|
||||
|
||||
private const float shear_width = 10;
|
||||
|
||||
public ChatTabControl()
|
||||
{
|
||||
TabContainer.Margin = new MarginPadding { Left = 50 };
|
||||
TabContainer.Spacing = new Vector2(-shear_width, 0);
|
||||
TabContainer.Masking = false;
|
||||
|
||||
AddInternal(new TextAwesome
|
||||
{
|
||||
Icon = FontAwesome.fa_comments,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
TextSize = 20,
|
||||
Padding = new MarginPadding(10),
|
||||
});
|
||||
}
|
||||
|
||||
private class ChannelTabItem : TabItem<Channel>
|
||||
{
|
||||
private Color4 backgroundInactive;
|
||||
private Color4 backgroundHover;
|
||||
private Color4 backgroundActive;
|
||||
|
||||
private readonly SpriteText text;
|
||||
private readonly Box box;
|
||||
private readonly Box highlightBox;
|
||||
|
||||
public override bool Active
|
||||
{
|
||||
get { return base.Active; }
|
||||
set
|
||||
{
|
||||
if (Active == value) return;
|
||||
|
||||
base.Active = value;
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateState()
|
||||
{
|
||||
if (Active)
|
||||
fadeActive();
|
||||
else
|
||||
fadeInactive();
|
||||
}
|
||||
|
||||
private const float transition_length = 400;
|
||||
|
||||
private void fadeActive()
|
||||
{
|
||||
ResizeTo(new Vector2(Width, 1.1f), transition_length, EasingTypes.OutQuint);
|
||||
|
||||
box.FadeColour(backgroundActive, transition_length, EasingTypes.OutQuint);
|
||||
highlightBox.FadeIn(transition_length, EasingTypes.OutQuint);
|
||||
text.Font = @"Exo2.0-Bold";
|
||||
}
|
||||
|
||||
private void fadeInactive()
|
||||
{
|
||||
ResizeTo(new Vector2(Width, 1), transition_length, EasingTypes.OutQuint);
|
||||
|
||||
box.FadeColour(backgroundInactive, transition_length, EasingTypes.OutQuint);
|
||||
highlightBox.FadeOut(transition_length, EasingTypes.OutQuint);
|
||||
text.Font = @"Exo2.0-Regular";
|
||||
}
|
||||
|
||||
protected override bool OnHover(InputState state)
|
||||
{
|
||||
if (!Active)
|
||||
box.FadeColour(backgroundHover, transition_length, EasingTypes.OutQuint);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(InputState state)
|
||||
{
|
||||
updateState();
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
backgroundActive = colours.ChatBlue;
|
||||
backgroundInactive = colours.Gray4;
|
||||
backgroundHover = colours.Gray7;
|
||||
|
||||
highlightBox.Colour = colours.Yellow;
|
||||
|
||||
updateState();
|
||||
}
|
||||
|
||||
public ChannelTabItem(Channel value) : base(value)
|
||||
{
|
||||
Width = 150;
|
||||
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
|
||||
Anchor = Anchor.BottomLeft;
|
||||
Origin = Anchor.BottomLeft;
|
||||
|
||||
Shear = new Vector2(shear_width / ChatOverlay.TAB_AREA_HEIGHT, 0);
|
||||
|
||||
Masking = true;
|
||||
EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 10,
|
||||
Colour = Color4.Black.Opacity(0.2f),
|
||||
};
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
box = new Box
|
||||
{
|
||||
EdgeSmoothness = new Vector2(1, 0),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
highlightBox = new Box
|
||||
{
|
||||
Width = 5,
|
||||
Alpha = 0,
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
EdgeSmoothness = new Vector2(1, 0),
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Shear = new Vector2(-shear_width / ChatOverlay.TAB_AREA_HEIGHT, 0),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TextAwesome
|
||||
{
|
||||
Icon = FontAwesome.fa_hashtag,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Colour = Color4.Black,
|
||||
X = -10,
|
||||
Alpha = 0.2f,
|
||||
TextSize = ChatOverlay.TAB_AREA_HEIGHT,
|
||||
},
|
||||
text = new OsuSpriteText
|
||||
{
|
||||
Margin = new MarginPadding(5),
|
||||
Origin = Anchor.CentreLeft,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Text = value.ToString(),
|
||||
TextSize = 18,
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,32 +7,24 @@ using System.Linq;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Chat;
|
||||
|
||||
namespace osu.Game.Online.Chat.Drawables
|
||||
namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
public class DrawableChannel : Container
|
||||
{
|
||||
private readonly Channel channel;
|
||||
public readonly Channel Channel;
|
||||
private readonly FillFlowContainer flow;
|
||||
private readonly ScrollContainer scroll;
|
||||
|
||||
public DrawableChannel(Channel channel)
|
||||
{
|
||||
this.channel = channel;
|
||||
Channel = channel;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = channel.Name,
|
||||
TextSize = 50,
|
||||
Alpha = 0.3f,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
},
|
||||
scroll = new ScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@ -56,14 +48,14 @@ namespace osu.Game.Online.Chat.Drawables
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
newMessagesArrived(channel.Messages);
|
||||
newMessagesArrived(Channel.Messages);
|
||||
scrollToEnd();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
channel.NewMessagesArrived -= newMessagesArrived;
|
||||
Channel.NewMessagesArrived -= newMessagesArrived;
|
||||
}
|
||||
|
||||
private void newMessagesArrived(IEnumerable<Message> newMessages)
|
||||
@ -93,4 +85,4 @@ namespace osu.Game.Online.Chat.Drawables
|
||||
|
||||
private void scrollToEnd() => Scheduler.AddDelayed(() => scroll.ScrollToEnd(), 50);
|
||||
}
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ using System.Diagnostics;
|
||||
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.Graphics.Sprites;
|
||||
@ -15,24 +16,24 @@ using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Online.Chat.Drawables;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Overlays.Chat;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
public class ChatOverlay : FocusedOverlayContainer, IOnlineComponent
|
||||
{
|
||||
private const float textbox_height = 40;
|
||||
private const float textbox_height = 60;
|
||||
|
||||
private ScheduledDelegate messageRequest;
|
||||
|
||||
private readonly Container content;
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
private readonly Container currentChannelContainer;
|
||||
|
||||
private readonly FocusedTextBox inputTextBox;
|
||||
|
||||
@ -40,50 +41,114 @@ namespace osu.Game.Overlays
|
||||
|
||||
private const int transition_length = 500;
|
||||
|
||||
public const float DEFAULT_HEIGHT = 0.4f;
|
||||
|
||||
public const float TAB_AREA_HEIGHT = 50;
|
||||
|
||||
private GetMessagesRequest fetchReq;
|
||||
|
||||
private readonly ChatTabControl channelTabs;
|
||||
|
||||
private readonly Box chatBackground;
|
||||
private readonly Box tabBackground;
|
||||
|
||||
private Bindable<double> chatHeight;
|
||||
|
||||
public ChatOverlay()
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Size = new Vector2(1, 300);
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
RelativePositionAxes = Axes.Both;
|
||||
Size = new Vector2(1, DEFAULT_HEIGHT);
|
||||
Anchor = Anchor.BottomLeft;
|
||||
Origin = Anchor.BottomLeft;
|
||||
|
||||
AddInternal(new Drawable[]
|
||||
const float padding = 5;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
new Container
|
||||
{
|
||||
Depth = float.MaxValue,
|
||||
Name = @"chat area",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
Alpha = 0.9f,
|
||||
},
|
||||
content = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Top = 5, Bottom = textbox_height + 5 },
|
||||
Padding = new MarginPadding { Top = TAB_AREA_HEIGHT },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
chatBackground = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
currentChannelContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding
|
||||
{
|
||||
Top = padding,
|
||||
Bottom = textbox_height + padding
|
||||
},
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = textbox_height,
|
||||
Padding = new MarginPadding
|
||||
{
|
||||
Top = padding * 2,
|
||||
Bottom = padding * 2,
|
||||
Left = ChatLine.LEFT_PADDING + padding * 2,
|
||||
Right = padding * 2,
|
||||
},
|
||||
Children = new Drawable[]
|
||||
{
|
||||
inputTextBox = new FocusedTextBox
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Height = 1,
|
||||
PlaceholderText = "type your message",
|
||||
Exit = () => State = Visibility.Hidden,
|
||||
OnCommit = postMessage,
|
||||
HoldFocus = true,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Name = @"tabs area",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = textbox_height,
|
||||
Padding = new MarginPadding(5),
|
||||
Height = TAB_AREA_HEIGHT,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
inputTextBox = new FocusedTextBox
|
||||
tabBackground = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Height = 1,
|
||||
PlaceholderText = "type your message",
|
||||
Exit = () => State = Visibility.Hidden,
|
||||
OnCommit = postMessage,
|
||||
HoldFocus = true,
|
||||
}
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
channelTabs = new ChatTabControl
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
channelTabs.Current.ValueChanged += newChannel => CurrentChannel = newChannel;
|
||||
}
|
||||
|
||||
protected override bool OnDragStart(InputState state)
|
||||
{
|
||||
if (channelTabs.Hovering)
|
||||
return true;
|
||||
|
||||
return base.OnDragStart(state);
|
||||
}
|
||||
|
||||
protected override bool OnDrag(InputState state)
|
||||
{
|
||||
chatHeight.Value = Height - state.Mouse.Delta.Y / Parent.DrawSize.Y;
|
||||
return base.OnDrag(state);
|
||||
}
|
||||
|
||||
public void APIStateChanged(APIAccess api, APIState state)
|
||||
@ -117,7 +182,7 @@ namespace osu.Game.Overlays
|
||||
|
||||
protected override void PopOut()
|
||||
{
|
||||
MoveToY(DrawSize.Y, transition_length, EasingTypes.InSine);
|
||||
MoveToY(Height, transition_length, EasingTypes.InSine);
|
||||
FadeOut(transition_length, EasingTypes.InSine);
|
||||
|
||||
inputTextBox.HoldFocus = false;
|
||||
@ -125,19 +190,33 @@ namespace osu.Game.Overlays
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(APIAccess api)
|
||||
private void load(APIAccess api, OsuConfigManager config, OsuColour colours)
|
||||
{
|
||||
this.api = api;
|
||||
api.Register(this);
|
||||
|
||||
chatHeight = config.GetBindable<double>(OsuConfig.ChatDisplayHeight);
|
||||
chatHeight.ValueChanged += h =>
|
||||
{
|
||||
Height = (float)h;
|
||||
tabBackground.FadeTo(Height == 1 ? 1 : 0.8f, 200);
|
||||
};
|
||||
chatHeight.TriggerChange();
|
||||
|
||||
chatBackground.Colour = colours.ChatBlue;
|
||||
}
|
||||
|
||||
private long? lastMessageId;
|
||||
|
||||
private List<Channel> careChannels;
|
||||
|
||||
private readonly List<DrawableChannel> loadedChannels = new List<DrawableChannel>();
|
||||
|
||||
private void initializeChannels()
|
||||
{
|
||||
Clear();
|
||||
currentChannelContainer.Clear();
|
||||
|
||||
loadedChannels.Clear();
|
||||
|
||||
careChannels = new List<Channel>();
|
||||
|
||||
@ -160,25 +239,67 @@ namespace osu.Game.Overlays
|
||||
Scheduler.Add(delegate
|
||||
{
|
||||
loading.FadeOut(100);
|
||||
|
||||
addChannel(channels.Find(c => c.Name == @"#lazer"));
|
||||
addChannel(channels.Find(c => c.Name == @"#osu"));
|
||||
addChannel(channels.Find(c => c.Name == @"#lobby"));
|
||||
});
|
||||
|
||||
messageRequest = Scheduler.AddDelayed(fetchNewMessages, 1000, true);
|
||||
messageRequest = Scheduler.AddDelayed(() => fetchNewMessages(), 1000, true);
|
||||
};
|
||||
|
||||
api.Queue(req);
|
||||
}
|
||||
|
||||
private Channel currentChannel;
|
||||
|
||||
protected Channel CurrentChannel
|
||||
{
|
||||
get
|
||||
{
|
||||
return currentChannel;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (currentChannel == value) return;
|
||||
|
||||
if (currentChannel != null)
|
||||
currentChannelContainer.Clear(false);
|
||||
|
||||
currentChannel = value;
|
||||
|
||||
var loaded = loadedChannels.Find(d => d.Channel == value);
|
||||
if (loaded == null)
|
||||
loadedChannels.Add(loaded = new DrawableChannel(currentChannel));
|
||||
|
||||
inputTextBox.Current.Disabled = currentChannel.ReadOnly;
|
||||
|
||||
currentChannelContainer.Add(loaded);
|
||||
|
||||
channelTabs.Current.Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private void addChannel(Channel channel)
|
||||
{
|
||||
Add(new DrawableChannel(channel));
|
||||
if (channel == null) return;
|
||||
|
||||
careChannels.Add(channel);
|
||||
channelTabs.AddItem(channel);
|
||||
|
||||
// we need to get a good number of messages initially for each channel we care about.
|
||||
fetchNewMessages(channel);
|
||||
|
||||
if (CurrentChannel == null)
|
||||
CurrentChannel = channel;
|
||||
}
|
||||
|
||||
private void fetchNewMessages()
|
||||
private void fetchNewMessages(Channel specificChannel = null)
|
||||
{
|
||||
if (fetchReq != null) return;
|
||||
|
||||
fetchReq = new GetMessagesRequest(careChannels, lastMessageId);
|
||||
fetchReq = new GetMessagesRequest(specificChannel != null ? new List<Channel> { specificChannel } : careChannels, lastMessageId);
|
||||
fetchReq.Success += delegate (List<Message> messages)
|
||||
{
|
||||
var ids = messages.Where(m => m.TargetType == TargetType.Channel).Select(m => m.TargetId).Distinct();
|
||||
@ -207,8 +328,6 @@ namespace osu.Game.Overlays
|
||||
|
||||
if (!string.IsNullOrEmpty(postText) && api.LocalUser.Value != null)
|
||||
{
|
||||
var currentChannel = careChannels.FirstOrDefault();
|
||||
|
||||
if (currentChannel == null) return;
|
||||
|
||||
var message = new Message
|
||||
|
@ -7,6 +7,7 @@ using osu.Framework.Screens;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Screens
|
||||
{
|
||||
@ -96,6 +97,9 @@ namespace osu.Game.Screens
|
||||
}
|
||||
else if (bg != null)
|
||||
{
|
||||
// this makes up for the fact our padding changes when the global toolbar is visible.
|
||||
bg.Scale = new Vector2(1.06f);
|
||||
|
||||
AddInternal(new ParallaxContainer
|
||||
{
|
||||
Depth = float.MaxValue,
|
||||
|
@ -28,10 +28,12 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private readonly SongProgressBar bar;
|
||||
private readonly SongProgressGraph graph;
|
||||
private readonly SongProgressInfo info;
|
||||
|
||||
public Action<double> OnSeek;
|
||||
|
||||
public IClock AudioClock;
|
||||
private IClock audioClock;
|
||||
public IClock AudioClock { set { audioClock = info.AudioClock = value; } }
|
||||
|
||||
private double lastHitTime => ((objects.Last() as IHasEndTime)?.EndTime ?? objects.Last().StartTime) + 1;
|
||||
|
||||
@ -44,6 +46,9 @@ namespace osu.Game.Screens.Play
|
||||
set
|
||||
{
|
||||
graph.Objects = objects = value;
|
||||
|
||||
info.StartTime = firstHitTime;
|
||||
info.EndTime = lastHitTime;
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,6 +67,14 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
info = new SongProgressInfo
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Margin = new MarginPadding { Bottom = bottom_bar_height + graph_height },
|
||||
},
|
||||
graph = new SongProgressGraph
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
@ -130,10 +143,13 @@ namespace osu.Game.Screens.Play
|
||||
if (objects == null)
|
||||
return;
|
||||
|
||||
double progress = ((AudioClock?.CurrentTime ?? Time.Current) - firstHitTime) / lastHitTime;
|
||||
double progress = ((audioClock?.CurrentTime ?? Time.Current) - firstHitTime) / (lastHitTime - firstHitTime);
|
||||
|
||||
bar.UpdatePosition((float)progress);
|
||||
graph.Progress = (int)(graph.ColumnCount * progress);
|
||||
if(progress < 1)
|
||||
{
|
||||
bar.UpdatePosition((float)progress);
|
||||
graph.Progress = (int)(graph.ColumnCount * progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,12 +20,13 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
const int granularity = 200;
|
||||
|
||||
var firstHit = objects.First().StartTime;
|
||||
var lastHit = (objects.Last() as IHasEndTime)?.EndTime ?? 0;
|
||||
|
||||
if (lastHit == 0)
|
||||
lastHit = objects.Last().StartTime;
|
||||
|
||||
var interval = (lastHit + 1) / granularity;
|
||||
var interval = (lastHit - firstHit + 1) / granularity;
|
||||
|
||||
var values = new int[granularity];
|
||||
|
||||
@ -33,8 +34,8 @@ namespace osu.Game.Screens.Play
|
||||
{
|
||||
IHasEndTime end = h as IHasEndTime;
|
||||
|
||||
int startRange = (int)(h.StartTime / interval);
|
||||
int endRange = (int)((end?.EndTime > 0 ? end.EndTime : h.StartTime) / interval);
|
||||
int startRange = (int)((h.StartTime - firstHit)/ interval);
|
||||
int endRange = (int)(((end?.EndTime > 0 ? end.EndTime : h.StartTime) - firstHit) / interval);
|
||||
for (int i = startRange; i <= endRange; i++)
|
||||
values[i]++;
|
||||
}
|
||||
|
96
osu.Game/Screens/Play/SongProgressInfo.cs
Normal file
96
osu.Game/Screens/Play/SongProgressInfo.cs
Normal file
@ -0,0 +1,96 @@
|
||||
// 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.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using System;
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
public class SongProgressInfo : Container
|
||||
{
|
||||
private OsuSpriteText timeCurrent;
|
||||
private OsuSpriteText timeLeft;
|
||||
private OsuSpriteText progress;
|
||||
|
||||
private double startTime;
|
||||
private double endTime;
|
||||
|
||||
private int? previousPercent;
|
||||
private int? previousSecond;
|
||||
|
||||
private double songLength => endTime - startTime;
|
||||
|
||||
private const int margin = 10;
|
||||
|
||||
public IClock AudioClock;
|
||||
|
||||
public double StartTime { set { startTime = value; } }
|
||||
public double EndTime { set { endTime = value; } }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
timeCurrent = new OsuSpriteText
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Colour = colours.BlueLighter,
|
||||
Font = @"Venera",
|
||||
Margin = new MarginPadding
|
||||
{
|
||||
Left = margin,
|
||||
},
|
||||
},
|
||||
progress = new OsuSpriteText
|
||||
{
|
||||
Origin = Anchor.BottomCentre,
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Colour = colours.BlueLighter,
|
||||
Font = @"Venera",
|
||||
},
|
||||
timeLeft = new OsuSpriteText
|
||||
{
|
||||
Origin = Anchor.BottomRight,
|
||||
Anchor = Anchor.BottomRight,
|
||||
Colour = colours.BlueLighter,
|
||||
Font = @"Venera",
|
||||
Margin = new MarginPadding
|
||||
{
|
||||
Right = margin,
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
double songCurrentTime = AudioClock.CurrentTime - startTime;
|
||||
int currentPercent = Math.Max(0, Math.Min(100, (int)(songCurrentTime / songLength * 100)));
|
||||
int currentSecond = (int)Math.Floor(songCurrentTime / 1000.0);
|
||||
|
||||
if (currentPercent != previousPercent)
|
||||
{
|
||||
progress.Text = currentPercent.ToString() + @"%";
|
||||
previousPercent = currentPercent;
|
||||
}
|
||||
|
||||
if (currentSecond != previousSecond && songCurrentTime < songLength)
|
||||
{
|
||||
timeCurrent.Text = TimeSpan.FromSeconds(currentSecond).ToString(songCurrentTime < 0 ? @"\-m\:ss" : @"m\:ss");
|
||||
timeLeft.Text = TimeSpan.FromMilliseconds(endTime - AudioClock.CurrentTime).ToString(@"\-m\:ss");
|
||||
|
||||
previousSecond = currentSecond;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -75,6 +75,7 @@
|
||||
<Compile Include="Beatmaps\Drawables\BeatmapBackgroundSprite.cs" />
|
||||
<Compile Include="Beatmaps\DifficultyCalculator.cs" />
|
||||
<Compile Include="Online\API\Requests\PostMessageRequest.cs" />
|
||||
<Compile Include="Overlays\Chat\ChatTabControl.cs" />
|
||||
<Compile Include="Overlays\Music\FilterControl.cs" />
|
||||
<Compile Include="Overlays\Music\PlaylistItem.cs" />
|
||||
<Compile Include="Overlays\Music\PlaylistList.cs" />
|
||||
@ -228,6 +229,7 @@
|
||||
<Compile Include="Screens\Charts\ChartInfo.cs" />
|
||||
<Compile Include="Screens\Edit\Editor.cs" />
|
||||
<Compile Include="Screens\Play\HotkeyRetryOverlay.cs" />
|
||||
<Compile Include="Screens\Play\SongProgressInfo.cs" />
|
||||
<Compile Include="Screens\Play\HUD\ModDisplay.cs" />
|
||||
<Compile Include="Screens\Play\SquareGraph.cs" />
|
||||
<Compile Include="Screens\Play\StandardHUDOverlay.cs" />
|
||||
@ -285,7 +287,6 @@
|
||||
<Compile Include="Screens\Play\HUD\ComboResultCounter.cs" />
|
||||
<Compile Include="Graphics\UserInterface\RollingCounter.cs" />
|
||||
<Compile Include="Graphics\UserInterface\Volume\VolumeControlReceptor.cs" />
|
||||
<Compile Include="Input\GlobalHotkeys.cs" />
|
||||
<Compile Include="Graphics\Backgrounds\Background.cs" />
|
||||
<Compile Include="Graphics\Containers\ParallaxContainer.cs" />
|
||||
<Compile Include="Graphics\Cursor\MenuCursor.cs" />
|
||||
@ -306,8 +307,8 @@
|
||||
<Compile Include="Online\API\Requests\GetMessagesRequest.cs" />
|
||||
<Compile Include="Online\API\Requests\ListChannelsRequest.cs" />
|
||||
<Compile Include="Online\Chat\Channel.cs" />
|
||||
<Compile Include="Online\Chat\Drawables\DrawableChannel.cs" />
|
||||
<Compile Include="Online\Chat\Drawables\ChatLine.cs" />
|
||||
<Compile Include="Overlays\Chat\DrawableChannel.cs" />
|
||||
<Compile Include="Overlays\Chat\ChatLine.cs" />
|
||||
<Compile Include="Online\Chat\Message.cs" />
|
||||
<Compile Include="OsuGame.cs" />
|
||||
<Compile Include="OsuGameBase.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user