diff --git a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs new file mode 100644 index 0000000000..d65355b5f4 --- /dev/null +++ b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Audio.Track; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; +using osu.Game.Graphics; + +namespace osu.Game.Screens.Edit.Components +{ + public class BottomBarContainer : Container + { + private const float corner_radius = 5; + private const float contents_padding = 15; + + public Bindable Beatmap = new Bindable(); + protected Track Track => Beatmap.Value.Track; + + private readonly Drawable background; + private readonly Container content; + + protected override Container Content => content; + + public BottomBarContainer() + { + Masking = true; + CornerRadius = corner_radius; + + InternalChildren = new[] + { + background = new Box { RelativeSizeAxes = Axes.Both }, + content = new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = contents_padding }, + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray1; + } + } +} diff --git a/osu.Game/Screens/Edit/Components/PlaybackContainer.cs b/osu.Game/Screens/Edit/Components/PlaybackContainer.cs new file mode 100644 index 0000000000..a7d1db4802 --- /dev/null +++ b/osu.Game/Screens/Edit/Components/PlaybackContainer.cs @@ -0,0 +1,160 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit.Components +{ + public class PlaybackContainer : BottomBarContainer + { + private readonly IconButton playButton; + + public PlaybackContainer() + { + PlaybackTabControl tabs; + + Children = new Drawable[] + { + playButton = new IconButton + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.Centre, + Scale = new Vector2(1.4f), + IconScale = new Vector2(1.4f), + Icon = FontAwesome.fa_play_circle_o, + Action = playPause, + Padding = new MarginPadding { Left = 20 } + }, + new OsuSpriteText + { + Origin = Anchor.BottomLeft, + Text = "Playback Speed", + RelativePositionAxes = Axes.Y, + Y = 0.5f, + Padding = new MarginPadding { Left = 45 } + }, + new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Both, + Height = 0.5f, + Padding = new MarginPadding { Left = 45 }, + Child = tabs = new PlaybackTabControl(), + } + }; + + tabs.AddItem(0.25); + tabs.AddItem(0.75); + tabs.AddItem(1); + + tabs.Current.ValueChanged += newValue => Track.Tempo.Value = newValue; + } + + private void playPause() + { + if (Track.IsRunning) + Track.Stop(); + else + Track.Start(); + } + + protected override void Update() + { + base.Update(); + + playButton.Icon = Track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o; + } + + private class PlaybackTabControl : OsuTabControl + { + protected override TabItem CreateTabItem(double value) => new PlaybackTabItem(value); + + protected override Dropdown CreateDropdown() => null; + + public PlaybackTabControl() + { + RelativeSizeAxes = Axes.Both; + TabContainer.Spacing = new Vector2(20, 0); + } + + public class PlaybackTabItem : TabItem + { + private const float fade_duration = 100; + + private readonly OsuSpriteText text; + private readonly OsuSpriteText textBold; + + public PlaybackTabItem(double value) : base(value) + { + AutoSizeAxes = Axes.X; + RelativeSizeAxes = Axes.Y; + + Children = new Drawable[] + { + text = new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = $"{value:P0}", + TextSize = 14, + }, + textBold = new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = $"{value:P0}", + TextSize = 14, + Font = @"Exo2.0-Bold", + Alpha = 0, + AlwaysPresent = true, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + text.Colour = colours.Gray5; + } + + protected override bool OnHover(InputState state) + { + if (!Active) + toBold(); + return true; + } + + protected override void OnHoverLost(InputState state) + { + if (!Active) + toNormal(); + } + + private void toBold() + { + text.FadeOut(fade_duration); + textBold.FadeIn(fade_duration); + } + + private void toNormal() + { + text.FadeIn(fade_duration); + textBold.FadeOut(fade_duration); + } + + protected override void OnActivated() => toBold(); + + protected override void OnDeactivated() => toNormal(); + } + } + } +} diff --git a/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs b/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs new file mode 100644 index 0000000000..b9b6867ea6 --- /dev/null +++ b/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs @@ -0,0 +1,38 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Game.Graphics.Sprites; +using System; + +namespace osu.Game.Screens.Edit.Components +{ + public class TimeInfoContainer : BottomBarContainer + { + private const int count_duration = 150; + + private readonly OsuSpriteText trackTimer; + + public TimeInfoContainer() + { + Children = new Drawable[] + { + trackTimer = new OsuSpriteText + { + Origin = Anchor.BottomLeft, + RelativePositionAxes = Axes.Y, + TextSize = 22, + FixedWidth = true, + Y = 0.5f, + } + }; + } + + protected override void Update() + { + base.Update(); + + trackTimer.Text = TimeSpan.FromMilliseconds(Track.CurrentTime).ToString(@"mm\:ss\:fff"); + } + } +} diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs index 4d925f7584..a63d02a0a5 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs @@ -3,11 +3,9 @@ using OpenTK; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; @@ -16,83 +14,64 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary /// /// The timeline that sits at the bottom of the editor. /// - public class SummaryTimeline : CompositeDrawable + public class SummaryTimeline : BottomBarContainer { - private const float corner_radius = 5; - private const float contents_padding = 15; - - public Bindable Beatmap = new Bindable(); - - private readonly Drawable background; - private readonly Drawable timelineBar; public SummaryTimeline() { - Masking = true; - CornerRadius = corner_radius; - TimelinePart markerPart, controlPointPart, bookmarkPart, breakPart; - InternalChildren = new[] + Children = new[] { - background = new Box { RelativeSizeAxes = Axes.Both }, - new Container + markerPart = new MarkerPart { RelativeSizeAxes = Axes.Both }, + controlPointPart = new ControlPointPart + { + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.Both, + Height = 0.35f + }, + bookmarkPart = new BookmarkPart + { + Anchor = Anchor.Centre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.Both, + Height = 0.35f + }, + timelineBar = new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = contents_padding, Right = contents_padding }, - Children = new[] + Children = new Drawable[] { - markerPart = new MarkerPart { RelativeSizeAxes = Axes.Both }, - controlPointPart = new ControlPointPart + new Circle { - Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.Both, - Height = 0.35f + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreRight, + Size = new Vector2(5) }, - bookmarkPart = new BookmarkPart + new Box { - Anchor = Anchor.Centre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.Both, - Height = 0.35f + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + Height = 1, + EdgeSmoothness = new Vector2(0, 1), }, - timelineBar = new Container + new Circle { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Circle - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreRight, - Size = new Vector2(5) - }, - new Box - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.X, - Height = 1, - EdgeSmoothness = new Vector2(0, 1), - }, - new Circle - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreLeft, - Size = new Vector2(5) - }, - } + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreLeft, + Size = new Vector2(5) }, - breakPart = new BreakPart - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Height = 0.25f - } } + }, + breakPart = new BreakPart + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Height = 0.25f } }; @@ -105,7 +84,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary [BackgroundDependencyLoader] private void load(OsuColour colours) { - background.Colour = colours.Gray1; timelineBar.Colour = colours.Gray5; } } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 74e55e58ad..e2971deb75 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -10,13 +10,13 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Screens.Edit.Menus; using osu.Game.Screens.Edit.Components.Timelines.Summary; -using OpenTK; using osu.Framework.Allocation; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Screens; using osu.Game.Screens.Edit.Screens.Compose; using osu.Game.Screens.Edit.Screens.Design; +using osu.Game.Screens.Edit.Components; namespace osu.Game.Screens.Edit { @@ -34,7 +34,9 @@ namespace osu.Game.Screens.Edit public Editor() { EditorMenuBar menuBar; + TimeInfoContainer timeInfo; SummaryTimeline timeline; + PlaybackContainer playback; Children = new[] { @@ -84,30 +86,47 @@ namespace osu.Game.Screens.Edit new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 5, Bottom = 5, Left = 10, Right = 10 }, - Child = new FillFlowContainer + Padding = new MarginPadding { Vertical = 5, Horizontal = 10 }, + Child = new GridContainer { - Name = "Bottom bar", RelativeSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new[] + ColumnDimensions = new[] { - timeline = new SummaryTimeline + new Dimension(GridSizeMode.Absolute, 220), + new Dimension(), + new Dimension(GridSizeMode.Absolute, 220) + }, + Content = new[] + { + new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Width = 0.65f - } + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Right = 10 }, + Child = timeInfo = new TimeInfoContainer { RelativeSizeAxes = Axes.Both }, + }, + timeline = new SummaryTimeline + { + RelativeSizeAxes = Axes.Both, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = 10 }, + Child = playback = new PlaybackContainer { RelativeSizeAxes = Axes.Both }, + } + }, } - } + }, } } }, }; + timeInfo.Beatmap.BindTo(Beatmap); timeline.Beatmap.BindTo(Beatmap); + playback.Beatmap.BindTo(Beatmap); menuBar.Mode.ValueChanged += onModeChanged; } @@ -154,7 +173,11 @@ namespace osu.Game.Screens.Edit protected override bool OnExiting(Screen next) { Background.FadeColour(Color4.White, 500); - Beatmap.Value.Track?.Start(); + if (Beatmap.Value.Track != null) + { + Beatmap.Value.Track.Tempo.Value = 1; + Beatmap.Value.Track.Start(); + } return base.OnExiting(next); } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index c3af014fe1..048735358e 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -298,6 +298,9 @@ + + +