Merge branch 'osu-direct' of https://github.com/DrabWeb/osu into osu-direct

This commit is contained in:
DrabWeb
2017-05-23 14:34:58 -03:00
52 changed files with 1661 additions and 352 deletions

View File

@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Chat
public class DrawableChannel : Container
{
public readonly Channel Channel;
private readonly FillFlowContainer flow;
private readonly FillFlowContainer<ChatLine> flow;
private readonly ScrollContainer scroll;
public DrawableChannel(Channel channel)
@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Chat
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
flow = new FillFlowContainer
flow = new FillFlowContainer<ChatLine>
{
Direction = FillDirection.Vertical,
RelativeSizeAxes = Axes.X,
@ -63,19 +63,18 @@ 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)));
if (scroll.IsScrolledToEnd(10) || !flow.Children.Any())
scrollToEnd();
//up to last Channel.MAX_HISTORY messages
foreach (Message m in displayMessages)
{
var d = new ChatLine(m);
flow.Add(d);
}
var staleMessages = flow.Children.Where(c => c.LifetimeEnd == double.MaxValue).ToArray();
int count = staleMessages.Length - Channel.MAX_HISTORY;
while (flow.Children.Count(c => c.LifetimeEnd == double.MaxValue) > Channel.MAX_HISTORY)
for (int i = 0; i < count; i++)
{
var d = flow.Children.First(c => c.LifetimeEnd == double.MaxValue);
var d = staleMessages[i];
if (!scroll.IsScrolledToEnd(10))
scroll.OffsetScrollPosition(-d.DrawHeight);
d.Expire();

View File

@ -229,6 +229,7 @@ namespace osu.Game.Overlays
Scheduler.Add(delegate
{
loading.FadeOut(100);
loading.Expire();
addChannel(channels.Find(c => c.Name == @"#lazer"));
addChannel(channels.Find(c => c.Name == @"#osu"));
@ -320,11 +321,8 @@ namespace osu.Game.Overlays
fetchReq = new GetMessagesRequest(careChannels, lastMessageId);
fetchReq.Success += delegate (List<Message> messages)
{
var ids = messages.Where(m => m.TargetType == TargetType.Channel).Select(m => m.TargetId).Distinct();
//batch messages per channel.
foreach (var id in ids)
careChannels.Find(c => c.Id == id)?.AddNewMessages(messages.Where(m => m.TargetId == id).ToArray());
foreach (var group in messages.Where(m => m.TargetType == TargetType.Channel).GroupBy(m => m.TargetId))
careChannels.Find(c => c.Id == group.Key)?.AddNewMessages(group.ToArray());
lastMessageId = messages.LastOrDefault()?.Id ?? lastMessageId;

View File

@ -1,34 +1,16 @@
// 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.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using OpenTK.Graphics;
namespace osu.Game.Overlays.Settings
{
public class SettingsHeader : Container
{
public SearchTextBox SearchTextBox;
private Box background;
private readonly Func<float> currentScrollOffset;
public Action Exit;
/// <param name="currentScrollOffset">A reference to the current scroll position of the ScrollContainer we are contained within.</param>
public SettingsHeader(Func<float> currentScrollOffset)
{
this.currentScrollOffset = currentScrollOffset;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
@ -37,11 +19,6 @@ namespace osu.Game.Overlays.Settings
Children = new Drawable[]
{
background = new Box
{
Colour = Color4.Black,
RelativeSizeAxes = Axes.Both,
},
new FillFlowContainer
{
AutoSizeAxes = Axes.Y,
@ -53,7 +30,8 @@ namespace osu.Game.Overlays.Settings
{
Text = "settings",
TextSize = 40,
Margin = new MarginPadding {
Margin = new MarginPadding
{
Left = SettingsOverlay.CONTENT_MARGINS,
Top = Toolbar.Toolbar.TOOLTIP_HEIGHT
},
@ -63,45 +41,15 @@ namespace osu.Game.Overlays.Settings
Colour = colours.Pink,
Text = "Change the way osu! behaves",
TextSize = 18,
Margin = new MarginPadding {
Margin = new MarginPadding
{
Left = SettingsOverlay.CONTENT_MARGINS,
Bottom = 30
},
},
SearchTextBox = new SearchTextBox
{
RelativeSizeAxes = Axes.X,
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Width = 0.95f,
Margin = new MarginPadding {
Top = 20,
Bottom = 20
},
Exit = () => Exit(),
},
}
}
};
}
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
// the point at which we will start anchoring to the top.
float anchorOffset = SearchTextBox.Y;
float scrollPosition = currentScrollOffset();
// we want to anchor the search field to the top of the screen when scrolling.
Margin = new MarginPadding { Top = Math.Max(0, scrollPosition - anchorOffset) };
// we don't want the header to scroll when scrolling beyond the upper extent.
Y = Math.Min(0, scrollPosition);
// we get darker as scroll progresses
background.Alpha = Math.Min(1, scrollPosition / anchorOffset) * 0.5f;
}
}
}

View File

@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Settings
private readonly Box backgroundBox;
private readonly Box selectionIndicator;
private readonly Container text;
public Action Action;
public Action<SettingsSection> Action;
private SettingsSection section;
public SettingsSection Section
@ -75,6 +75,7 @@ namespace osu.Game.Overlays.Settings
{
Width = Sidebar.DEFAULT_WIDTH,
RelativeSizeAxes = Axes.Y,
Colour = OsuColour.Gray(0.6f),
Children = new[]
{
headerText = new OsuSpriteText
@ -110,7 +111,7 @@ namespace osu.Game.Overlays.Settings
protected override bool OnClick(InputState state)
{
Action?.Invoke();
Action?.Invoke(section);
backgroundBox.FlashColour(Color4.White, 400);
return true;
}

View File

@ -7,10 +7,11 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Overlays.Settings;
using System;
using osu.Game.Overlays.Settings.Sections;
using osu.Framework.Input;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Settings;
using osu.Game.Overlays.Settings.Sections;
namespace osu.Game.Overlays
{
@ -26,18 +27,13 @@ namespace osu.Game.Overlays
private const float sidebar_padding = 10;
private ScrollContainer scrollContainer;
private Sidebar sidebar;
private SidebarButton[] sidebarButtons;
private SettingsSection[] sections;
private SidebarButton selectedSidebarButton;
private SettingsHeader header;
private SettingsSectionsContainer sectionsContainer;
private SettingsFooter footer;
private SearchContainer searchContainer;
private float lastKnownScroll;
private SearchTextBox searchTextBox;
public SettingsOverlay()
{
@ -48,7 +44,7 @@ namespace osu.Game.Overlays
[BackgroundDependencyLoader(permitNulls: true)]
private void load(OsuGame game)
{
sections = new SettingsSection[]
var sections = new SettingsSection[]
{
new GeneralSection(),
new GraphicsSection(),
@ -68,27 +64,27 @@ namespace osu.Game.Overlays
Colour = Color4.Black,
Alpha = 0.6f,
},
scrollContainer = new ScrollContainer
sectionsContainer = new SettingsSectionsContainer
{
ScrollDraggerVisible = false,
RelativeSizeAxes = Axes.Y,
Width = width,
Margin = new MarginPadding { Left = SIDEBAR_WIDTH },
Children = new Drawable[]
ExpandableHeader = new SettingsHeader(),
FixedHeader = searchTextBox = new SearchTextBox
{
searchContainer = new SearchContainer
RelativeSizeAxes = Axes.X,
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Width = 0.95f,
Margin = new MarginPadding
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Direction = FillDirection.Vertical,
Children = sections,
Top = 20,
Bottom = 20
},
footer = new SettingsFooter(),
header = new SettingsHeader(() => scrollContainer.Current)
{
Exit = Hide,
},
}
Exit = Hide,
},
Sections = sections,
Footer = new SettingsFooter()
},
sidebar = new Sidebar
{
@ -96,84 +92,89 @@ namespace osu.Game.Overlays
Children = sidebarButtons = sections.Select(section =>
new SidebarButton
{
Selected = sections[0] == section,
Section = section,
Action = () => scrollContainer.ScrollIntoView(section),
Action = sectionsContainer.ScrollContainer.ScrollIntoView,
}
).ToArray()
}
};
header.SearchTextBox.Current.ValueChanged += newValue => searchContainer.SearchTerm = newValue;
selectedSidebarButton = sidebarButtons[0];
selectedSidebarButton.Selected = true;
scrollContainer.Padding = new MarginPadding { Top = game?.Toolbar.DrawHeight ?? 0 };
}
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
//we need to update these manually because we can't put the SettingsHeader inside the SearchContainer (due to its anchoring).
searchContainer.Y = header.DrawHeight;
footer.Y = searchContainer.Y + searchContainer.DrawHeight;
}
protected override void Update()
{
base.Update();
float currentScroll = scrollContainer.Current;
if (currentScroll != lastKnownScroll)
sectionsContainer.SelectedSection.ValueChanged += section =>
{
lastKnownScroll = currentScroll;
selectedSidebarButton.Selected = false;
selectedSidebarButton = sidebarButtons.Single(b => b.Section == section);
selectedSidebarButton.Selected = true;
};
SettingsSection bestCandidate = null;
float bestDistance = float.MaxValue;
searchTextBox.Current.ValueChanged += newValue => sectionsContainer.SearchContainer.SearchTerm = newValue;
foreach (SettingsSection section in sections)
{
float distance = Math.Abs(scrollContainer.GetChildPosInContent(section) - currentScroll);
if (distance < bestDistance)
{
bestDistance = distance;
bestCandidate = section;
}
}
var previous = sidebarButtons.SingleOrDefault(sb => sb.Selected);
var next = sidebarButtons.SingleOrDefault(sb => sb.Section == bestCandidate);
if (previous != null) previous.Selected = false;
if (next != null) next.Selected = true;
}
sectionsContainer.Padding = new MarginPadding { Top = game?.Toolbar.DrawHeight ?? 0 };
}
protected override void PopIn()
{
base.PopIn();
scrollContainer.MoveToX(0, TRANSITION_LENGTH, EasingTypes.OutQuint);
sectionsContainer.MoveToX(0, TRANSITION_LENGTH, EasingTypes.OutQuint);
sidebar.MoveToX(0, TRANSITION_LENGTH, EasingTypes.OutQuint);
FadeTo(1, TRANSITION_LENGTH / 2);
header.SearchTextBox.HoldFocus = true;
searchTextBox.HoldFocus = true;
}
protected override void PopOut()
{
base.PopOut();
scrollContainer.MoveToX(-width, TRANSITION_LENGTH, EasingTypes.OutQuint);
sectionsContainer.MoveToX(-width, TRANSITION_LENGTH, EasingTypes.OutQuint);
sidebar.MoveToX(-SIDEBAR_WIDTH, TRANSITION_LENGTH, EasingTypes.OutQuint);
FadeTo(0, TRANSITION_LENGTH / 2);
header.SearchTextBox.HoldFocus = false;
header.SearchTextBox.TriggerFocusLost();
searchTextBox.HoldFocus = false;
searchTextBox.TriggerFocusLost();
}
protected override bool OnFocus(InputState state)
{
header.SearchTextBox.TriggerFocus(state);
searchTextBox.TriggerFocus(state);
return false;
}
private class SettingsSectionsContainer : SectionsContainer
{
public SearchContainer SearchContainer;
private readonly Box headerBackground;
protected override Container<Drawable> CreateScrollContentContainer()
=> SearchContainer = new SearchContainer
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Direction = FillDirection.Vertical,
};
public SettingsSectionsContainer()
{
ScrollContainer.ScrollDraggerVisible = false;
Add(headerBackground = new Box
{
Colour = Color4.Black,
RelativeSizeAxes = Axes.X
});
}
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
// no null check because the usage of this class is strict
headerBackground.Height = ExpandableHeader.LayoutSize.Y + FixedHeader.LayoutSize.Y;
headerBackground.Y = ExpandableHeader.Y;
headerBackground.Alpha = -ExpandableHeader.Y / ExpandableHeader.LayoutSize.Y * 0.5f;
}
}
}
}