mirror of
https://github.com/osukey/osukey.git
synced 2025-07-02 00:40:09 +09:00
Merge branch 'master' into leaderboard-scores
This commit is contained in:
Submodule osu-framework updated: 2a56eb0619...825505e788
@ -2,60 +2,38 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Configuration;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Graphics.UserInterface;
|
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Judgements;
|
using osu.Game.Rulesets.Osu.Judgements;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
namespace osu.Desktop.Tests.Visual
|
namespace osu.Desktop.Tests.Visual
|
||||||
{
|
{
|
||||||
internal class TestCaseHitObjects : OsuTestCase
|
internal class TestCaseHitObjects : OsuTestCase
|
||||||
{
|
{
|
||||||
private readonly FramedClock framedClock;
|
private FramedClock framedClock;
|
||||||
|
|
||||||
private bool auto;
|
private bool auto;
|
||||||
|
|
||||||
public TestCaseHitObjects()
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(RulesetStore rulesets)
|
||||||
{
|
{
|
||||||
var rateAdjustClock = new StopwatchClock(true);
|
var rateAdjustClock = new StopwatchClock(true);
|
||||||
framedClock = new FramedClock(rateAdjustClock);
|
framedClock = new FramedClock(rateAdjustClock);
|
||||||
playbackSpeed.ValueChanged += delegate { rateAdjustClock.Rate = playbackSpeed.Value; };
|
|
||||||
|
|
||||||
playbackSpeed.TriggerChange();
|
|
||||||
|
|
||||||
AddStep(@"circles", () => loadHitobjects(HitObjectType.Circle));
|
AddStep(@"circles", () => loadHitobjects(HitObjectType.Circle));
|
||||||
AddStep(@"slider", () => loadHitobjects(HitObjectType.Slider));
|
AddStep(@"slider", () => loadHitobjects(HitObjectType.Slider));
|
||||||
AddStep(@"spinner", () => loadHitobjects(HitObjectType.Spinner));
|
AddStep(@"spinner", () => loadHitobjects(HitObjectType.Spinner));
|
||||||
|
|
||||||
AddToggleStep(@"auto", state => { auto = state; loadHitobjects(mode); });
|
AddToggleStep("Auto", state => { auto = state; loadHitobjects(mode); });
|
||||||
|
AddSliderStep("Playback speed", 0.0, 2.0, 0.5, v => rateAdjustClock.Rate = v);
|
||||||
BasicSliderBar<double> sliderBar;
|
|
||||||
Add(new Container
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopRight,
|
|
||||||
Origin = Anchor.TopRight,
|
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new SpriteText { Text = "Playback Speed" },
|
|
||||||
sliderBar = new BasicSliderBar<double>
|
|
||||||
{
|
|
||||||
Width = 150,
|
|
||||||
Height = 10,
|
|
||||||
SelectionColor = Color4.Orange,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
sliderBar.Current.BindTo(playbackSpeed);
|
|
||||||
|
|
||||||
framedClock.ProcessFrame();
|
framedClock.ProcessFrame();
|
||||||
|
|
||||||
@ -65,7 +43,7 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
Clock = framedClock,
|
Clock = framedClock,
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
playfieldContainer = new Container { RelativeSizeAxes = Axes.Both },
|
playfieldContainer = new OsuInputManager(rulesets.GetRuleset(0)) { RelativeSizeAxes = Axes.Both },
|
||||||
approachContainer = new Container { RelativeSizeAxes = Axes.Both }
|
approachContainer = new Container { RelativeSizeAxes = Axes.Both }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -75,9 +53,8 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
|
|
||||||
private HitObjectType mode = HitObjectType.Slider;
|
private HitObjectType mode = HitObjectType.Slider;
|
||||||
|
|
||||||
private readonly BindableNumber<double> playbackSpeed = new BindableDouble(0.5) { MinValue = 0, MaxValue = 1 };
|
private Container playfieldContainer;
|
||||||
private readonly Container playfieldContainer;
|
private Container approachContainer;
|
||||||
private readonly Container approachContainer;
|
|
||||||
|
|
||||||
private void loadHitobjects(HitObjectType mode)
|
private void loadHitobjects(HitObjectType mode)
|
||||||
{
|
{
|
||||||
|
25
osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs
Normal file
25
osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// 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.Game.Overlays;
|
||||||
|
|
||||||
|
namespace osu.Desktop.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseKeyConfiguration : OsuTestCase
|
||||||
|
{
|
||||||
|
private readonly KeyBindingOverlay overlay;
|
||||||
|
|
||||||
|
public override string Description => @"Key configuration";
|
||||||
|
|
||||||
|
public TestCaseKeyConfiguration()
|
||||||
|
{
|
||||||
|
Child = overlay = new KeyBindingOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
overlay.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,8 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Framework.Configuration;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
@ -34,34 +31,13 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
new KeyCounterMouse(MouseButton.Right),
|
new KeyCounterMouse(MouseButton.Right),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
BindableInt bindable = new BindableInt { MinValue = 0, MaxValue = 200, Default = 50 };
|
|
||||||
bindable.ValueChanged += delegate { kc.FadeTime = bindable.Value; };
|
AddStep("Add random", () =>
|
||||||
AddStep("Add Random", () =>
|
|
||||||
{
|
{
|
||||||
Key key = (Key)((int)Key.A + RNG.Next(26));
|
Key key = (Key)((int)Key.A + RNG.Next(26));
|
||||||
kc.Add(new KeyCounterKeyboard(key));
|
kc.Add(new KeyCounterKeyboard(key));
|
||||||
});
|
});
|
||||||
|
AddSliderStep("Fade time", 0, 200, 50, v => kc.FadeTime = v);
|
||||||
TestSliderBar<int> sliderBar;
|
|
||||||
|
|
||||||
Add(new Container
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopRight,
|
|
||||||
Origin = Anchor.TopRight,
|
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new SpriteText { Text = "FadeTime" },
|
|
||||||
sliderBar = new TestSliderBar<int>
|
|
||||||
{
|
|
||||||
Width = 150,
|
|
||||||
Height = 10,
|
|
||||||
SelectionColor = Color4.Orange,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
sliderBar.Current.BindTo(bindable);
|
|
||||||
|
|
||||||
Add(kc);
|
Add(kc);
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
|
|
||||||
while (progressingNotifications.Count(n => n.State == ProgressNotificationState.Active) < 3)
|
while (progressingNotifications.Count(n => n.State == ProgressNotificationState.Active) < 3)
|
||||||
{
|
{
|
||||||
var p = progressingNotifications.FirstOrDefault(n => n.IsLoaded && n.State == ProgressNotificationState.Queued);
|
var p = progressingNotifications.FirstOrDefault(n => n.IsAlive && n.State == ProgressNotificationState.Queued);
|
||||||
if (p == null)
|
if (p == null)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
|
|
||||||
public TestCaseSettings()
|
public TestCaseSettings()
|
||||||
{
|
{
|
||||||
Children = new[] { settings = new SettingsOverlay() };
|
Children = new[] { settings = new MainSettings() };
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
|
@ -14,6 +14,9 @@ using osu.Game.Rulesets.Taiko.UI;
|
|||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Desktop.Tests.Beatmaps;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
namespace osu.Desktop.Tests.Visual
|
namespace osu.Desktop.Tests.Visual
|
||||||
{
|
{
|
||||||
@ -27,7 +30,7 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
protected override double TimePerAction => default_duration * 2;
|
protected override double TimePerAction => default_duration * 2;
|
||||||
|
|
||||||
private readonly Random rng = new Random(1337);
|
private readonly Random rng = new Random(1337);
|
||||||
private readonly TaikoPlayfield playfield;
|
private readonly TaikoRulesetContainer rulesetContainer;
|
||||||
private readonly Container playfieldContainer;
|
private readonly Container playfieldContainer;
|
||||||
|
|
||||||
public TestCaseTaikoPlayfield()
|
public TestCaseTaikoPlayfield()
|
||||||
@ -51,6 +54,25 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
AddStep("Height test 5", () => changePlayfieldSize(5));
|
AddStep("Height test 5", () => changePlayfieldSize(5));
|
||||||
AddStep("Reset height", () => changePlayfieldSize(6));
|
AddStep("Reset height", () => changePlayfieldSize(6));
|
||||||
|
|
||||||
|
var controlPointInfo = new ControlPointInfo();
|
||||||
|
controlPointInfo.TimingPoints.Add(new TimingControlPoint());
|
||||||
|
|
||||||
|
WorkingBeatmap beatmap = new TestWorkingBeatmap(new Beatmap
|
||||||
|
{
|
||||||
|
HitObjects = new List<HitObject> { new CentreHit() },
|
||||||
|
BeatmapInfo = new BeatmapInfo
|
||||||
|
{
|
||||||
|
Difficulty = new BeatmapDifficulty(),
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Artist = @"Unknown",
|
||||||
|
Title = @"Sample Beatmap",
|
||||||
|
Author = @"peppy",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ControlPointInfo = controlPointInfo
|
||||||
|
});
|
||||||
|
|
||||||
var rateAdjustClock = new StopwatchClock(true) { Rate = 1 };
|
var rateAdjustClock = new StopwatchClock(true) { Rate = 1 };
|
||||||
|
|
||||||
Add(playfieldContainer = new Container
|
Add(playfieldContainer = new Container
|
||||||
@ -58,12 +80,9 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Height = TaikoPlayfield.DEFAULT_HEIGHT,
|
Height = 768,
|
||||||
Clock = new FramedClock(rateAdjustClock),
|
Clock = new FramedClock(rateAdjustClock),
|
||||||
Children = new[]
|
Children = new[] { rulesetContainer = new TaikoRulesetContainer(null, beatmap, true) }
|
||||||
{
|
|
||||||
playfield = new TaikoPlayfield()
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,18 +147,18 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
playfield.OnJudgement(h);
|
rulesetContainer.Playfield.OnJudgement(h);
|
||||||
|
|
||||||
if (RNG.Next(10) == 0)
|
if (RNG.Next(10) == 0)
|
||||||
{
|
{
|
||||||
h.Judgement.SecondHit = true;
|
h.Judgement.SecondHit = true;
|
||||||
playfield.OnJudgement(h);
|
rulesetContainer.Playfield.OnJudgement(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMissJudgement()
|
private void addMissJudgement()
|
||||||
{
|
{
|
||||||
playfield.OnJudgement(new DrawableTestHit(new Hit())
|
rulesetContainer.Playfield.OnJudgement(new DrawableTestHit(new Hit())
|
||||||
{
|
{
|
||||||
Judgement = new TaikoJudgement
|
Judgement = new TaikoJudgement
|
||||||
{
|
{
|
||||||
@ -151,22 +170,17 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
|
|
||||||
private void addBarLine(bool major, double delay = scroll_time)
|
private void addBarLine(bool major, double delay = scroll_time)
|
||||||
{
|
{
|
||||||
BarLine bl = new BarLine
|
BarLine bl = new BarLine { StartTime = rulesetContainer.Playfield.Time.Current + delay };
|
||||||
{
|
|
||||||
StartTime = playfield.Time.Current + delay,
|
|
||||||
ScrollTime = scroll_time
|
|
||||||
};
|
|
||||||
|
|
||||||
playfield.AddBarLine(major ? new DrawableBarLineMajor(bl) : new DrawableBarLine(bl));
|
rulesetContainer.Playfield.Add(major ? new DrawableBarLineMajor(bl) : new DrawableBarLine(bl));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSwell(double duration = default_duration)
|
private void addSwell(double duration = default_duration)
|
||||||
{
|
{
|
||||||
playfield.Add(new DrawableSwell(new Swell
|
rulesetContainer.Playfield.Add(new DrawableSwell(new Swell
|
||||||
{
|
{
|
||||||
StartTime = playfield.Time.Current + scroll_time,
|
StartTime = rulesetContainer.Playfield.Time.Current + scroll_time,
|
||||||
Duration = duration,
|
Duration = duration,
|
||||||
ScrollTime = scroll_time
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,43 +191,40 @@ namespace osu.Desktop.Tests.Visual
|
|||||||
|
|
||||||
var d = new DrumRoll
|
var d = new DrumRoll
|
||||||
{
|
{
|
||||||
StartTime = playfield.Time.Current + scroll_time,
|
StartTime = rulesetContainer.Playfield.Time.Current + scroll_time,
|
||||||
IsStrong = strong,
|
IsStrong = strong,
|
||||||
Duration = duration,
|
Duration = duration,
|
||||||
ScrollTime = scroll_time,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
playfield.Add(new DrawableDrumRoll(d));
|
rulesetContainer.Playfield.Add(new DrawableDrumRoll(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCentreHit(bool strong)
|
private void addCentreHit(bool strong)
|
||||||
{
|
{
|
||||||
Hit h = new Hit
|
Hit h = new Hit
|
||||||
{
|
{
|
||||||
StartTime = playfield.Time.Current + scroll_time,
|
StartTime = rulesetContainer.Playfield.Time.Current + scroll_time,
|
||||||
ScrollTime = scroll_time,
|
|
||||||
IsStrong = strong
|
IsStrong = strong
|
||||||
};
|
};
|
||||||
|
|
||||||
if (strong)
|
if (strong)
|
||||||
playfield.Add(new DrawableCentreHitStrong(h));
|
rulesetContainer.Playfield.Add(new DrawableCentreHitStrong(h));
|
||||||
else
|
else
|
||||||
playfield.Add(new DrawableCentreHit(h));
|
rulesetContainer.Playfield.Add(new DrawableCentreHit(h));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addRimHit(bool strong)
|
private void addRimHit(bool strong)
|
||||||
{
|
{
|
||||||
Hit h = new Hit
|
Hit h = new Hit
|
||||||
{
|
{
|
||||||
StartTime = playfield.Time.Current + scroll_time,
|
StartTime = rulesetContainer.Playfield.Time.Current + scroll_time,
|
||||||
ScrollTime = scroll_time,
|
|
||||||
IsStrong = strong
|
IsStrong = strong
|
||||||
};
|
};
|
||||||
|
|
||||||
if (strong)
|
if (strong)
|
||||||
playfield.Add(new DrawableRimHitStrong(h));
|
rulesetContainer.Playfield.Add(new DrawableRimHitStrong(h));
|
||||||
else
|
else
|
||||||
playfield.Add(new DrawableRimHit(h));
|
rulesetContainer.Playfield.Add(new DrawableRimHit(h));
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DrawableTestHit : DrawableHitObject<TaikoHitObject, TaikoJudgement>
|
private class DrawableTestHit : DrawableHitObject<TaikoHitObject, TaikoJudgement>
|
||||||
|
@ -81,6 +81,7 @@
|
|||||||
<Compile Include="Visual\TestCaseGamefield.cs" />
|
<Compile Include="Visual\TestCaseGamefield.cs" />
|
||||||
<Compile Include="Visual\TestCaseGraph.cs" />
|
<Compile Include="Visual\TestCaseGraph.cs" />
|
||||||
<Compile Include="Visual\TestCaseHitObjects.cs" />
|
<Compile Include="Visual\TestCaseHitObjects.cs" />
|
||||||
|
<Compile Include="Visual\TestCaseKeyConfiguration.cs" />
|
||||||
<Compile Include="Visual\TestCaseKeyCounter.cs" />
|
<Compile Include="Visual\TestCaseKeyCounter.cs" />
|
||||||
<Compile Include="Visual\TestCaseLeaderboard.cs" />
|
<Compile Include="Visual\TestCaseLeaderboard.cs" />
|
||||||
<Compile Include="Visual\TestCaseManiaHitObjects.cs" />
|
<Compile Include="Visual\TestCaseManiaHitObjects.cs" />
|
||||||
|
@ -27,8 +27,6 @@ namespace osu.Desktop.Overlays
|
|||||||
private UpdateManager updateManager;
|
private UpdateManager updateManager;
|
||||||
private NotificationOverlay notificationOverlay;
|
private NotificationOverlay notificationOverlay;
|
||||||
|
|
||||||
protected override bool HideOnEscape => false;
|
|
||||||
|
|
||||||
public override bool HandleInput => false;
|
public override bool HandleInput => false;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -1,30 +1,18 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Game.Input.Bindings;
|
using osu.Game.Input.Bindings;
|
||||||
using OpenTK.Input;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch
|
namespace osu.Game.Rulesets.Catch
|
||||||
{
|
{
|
||||||
public class CatchInputManager : DatabasedKeyBindingInputManager<CatchAction>
|
public class CatchInputManager : DatabasedKeyBindingInputManager<CatchAction>
|
||||||
{
|
{
|
||||||
public CatchInputManager(RulesetInfo ruleset)
|
public CatchInputManager(RulesetInfo ruleset)
|
||||||
: base(ruleset, simultaneousMode: SimultaneousBindingMode.Unique)
|
: base(ruleset, 0, SimultaneousBindingMode.Unique)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IEnumerable<KeyBinding> CreateDefaultMappings() => new[]
|
|
||||||
{
|
|
||||||
new KeyBinding(Key.Z, CatchAction.MoveLeft),
|
|
||||||
new KeyBinding(Key.Left, CatchAction.MoveLeft),
|
|
||||||
new KeyBinding(Key.X, CatchAction.MoveRight),
|
|
||||||
new KeyBinding(Key.Right, CatchAction.MoveRight),
|
|
||||||
new KeyBinding(Key.LShift, CatchAction.Dash),
|
|
||||||
new KeyBinding(Key.RShift, CatchAction.Dash),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CatchAction
|
public enum CatchAction
|
||||||
|
@ -13,6 +13,7 @@ using System.Collections.Generic;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Catch.Scoring;
|
using osu.Game.Rulesets.Catch.Scoring;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch
|
namespace osu.Game.Rulesets.Catch
|
||||||
{
|
{
|
||||||
@ -20,6 +21,16 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
{
|
{
|
||||||
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new CatchRulesetContainer(this, beatmap, isForCurrentRuleset);
|
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new CatchRulesetContainer(this, beatmap, isForCurrentRuleset);
|
||||||
|
|
||||||
|
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
||||||
|
{
|
||||||
|
new KeyBinding(InputKey.Z, CatchAction.MoveLeft),
|
||||||
|
new KeyBinding(InputKey.Left, CatchAction.MoveLeft),
|
||||||
|
new KeyBinding(InputKey.X, CatchAction.MoveRight),
|
||||||
|
new KeyBinding(InputKey.Right, CatchAction.MoveRight),
|
||||||
|
new KeyBinding(InputKey.Shift, CatchAction.Dash),
|
||||||
|
new KeyBinding(InputKey.Shift, CatchAction.Dash),
|
||||||
|
};
|
||||||
|
|
||||||
public override IEnumerable<Mod> GetModsFor(ModType type)
|
public override IEnumerable<Mod> GetModsFor(ModType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
protected override Playfield<CatchBaseHit, CatchJudgement> CreatePlayfield() => new CatchPlayfield();
|
protected override Playfield<CatchBaseHit, CatchJudgement> CreatePlayfield() => new CatchPlayfield();
|
||||||
|
|
||||||
protected override PassThroughInputManager CreateActionMappingInputManager() => new CatchInputManager(Ruleset?.RulesetInfo);
|
public override PassThroughInputManager CreateKeyBindingInputManager() => new CatchInputManager(Ruleset?.RulesetInfo);
|
||||||
|
|
||||||
protected override DrawableHitObject<CatchBaseHit, CatchJudgement> GetVisualRepresentation(CatchBaseHit h)
|
protected override DrawableHitObject<CatchBaseHit, CatchJudgement> GetVisualRepresentation(CatchBaseHit h)
|
||||||
{
|
{
|
||||||
|
@ -51,6 +51,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
protected virtual void UpdateCurrentState(ArmedState state)
|
protected virtual void UpdateCurrentState(ArmedState state)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private OsuInputManager osuActionInputManager;
|
||||||
|
internal OsuInputManager OsuActionInputManager => osuActionInputManager ?? (osuActionInputManager = GetContainingInputManager() as OsuInputManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ComboResult
|
public enum ComboResult
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
@ -165,6 +166,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
glow.Colour = colours.BlueDark;
|
glow.Colour = colours.BlueDark;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton);
|
||||||
|
|
||||||
|
base.Update();
|
||||||
|
}
|
||||||
|
|
||||||
protected override void UpdateAfterChildren()
|
protected override void UpdateAfterChildren()
|
||||||
{
|
{
|
||||||
base.UpdateAfterChildren();
|
base.UpdateAfterChildren();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
@ -118,7 +119,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
if (Time.Current < slider.EndTime)
|
if (Time.Current < slider.EndTime)
|
||||||
Tracking = canCurrentlyTrack && lastState != null && ReceiveMouseInputAt(lastState.Mouse.NativeState.Position) && lastState.Mouse.HasMainButtonPressed;
|
Tracking = canCurrentlyTrack && lastState != null && ReceiveMouseInputAt(lastState.Mouse.NativeState.Position) && ((Parent as DrawableSlider)?.OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateProgress(double progress, int repeat)
|
public void UpdateProgress(double progress, int repeat)
|
||||||
|
@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
return;
|
return;
|
||||||
accentColour = value;
|
accentColour = value;
|
||||||
|
|
||||||
if (LoadState == LoadState.Loaded)
|
if (LoadState == LoadState.Ready)
|
||||||
Schedule(reloadTexture);
|
Schedule(reloadTexture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,21 +66,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
|
||||||
{
|
|
||||||
Tracking |= state.Mouse.HasMainButtonPressed;
|
|
||||||
return base.OnMouseDown(state, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
|
||||||
{
|
|
||||||
Tracking &= state.Mouse.HasMainButtonPressed;
|
|
||||||
return base.OnMouseUp(state, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool OnMouseMove(InputState state)
|
protected override bool OnMouseMove(InputState state)
|
||||||
{
|
{
|
||||||
Tracking |= state.Mouse.HasMainButtonPressed;
|
|
||||||
mousePosition = Parent.ToLocalSpace(state.Mouse.NativeState.Position);
|
mousePosition = Parent.ToLocalSpace(state.Mouse.NativeState.Position);
|
||||||
return base.OnMouseMove(state);
|
return base.OnMouseMove(state);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
{
|
{
|
||||||
public class OsuInputManager : DatabasedKeyBindingInputManager<OsuAction>
|
public class OsuInputManager : DatabasedKeyBindingInputManager<OsuAction>
|
||||||
{
|
{
|
||||||
public OsuInputManager(RulesetInfo ruleset) : base(ruleset, simultaneousMode: SimultaneousBindingMode.Unique)
|
public OsuInputManager(RulesetInfo ruleset) : base(ruleset, 0, SimultaneousBindingMode.Unique)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -33,19 +33,13 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
keyboard.Keys = keyboard.Keys.Concat(new[] { Key.LastKey + 2 });
|
keyboard.Keys = keyboard.Keys.Concat(new[] { Key.LastKey + 2 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IEnumerable<KeyBinding> CreateDefaultMappings() => new[]
|
|
||||||
{
|
|
||||||
new KeyBinding(Key.Z, OsuAction.LeftButton),
|
|
||||||
new KeyBinding(Key.X, OsuAction.RightButton),
|
|
||||||
new KeyBinding(Key.LastKey + 1, OsuAction.LeftButton),
|
|
||||||
new KeyBinding(Key.LastKey + 2, OsuAction.RightButton),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum OsuAction
|
public enum OsuAction
|
||||||
{
|
{
|
||||||
|
[Description("Left Button")]
|
||||||
LeftButton,
|
LeftButton,
|
||||||
|
[Description("Right Button")]
|
||||||
RightButton
|
RightButton
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Game.Rulesets.Osu.Scoring;
|
using osu.Game.Rulesets.Osu.Scoring;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu
|
namespace osu.Game.Rulesets.Osu
|
||||||
{
|
{
|
||||||
@ -24,8 +25,16 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
{
|
{
|
||||||
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new OsuRulesetContainer(this, beatmap, isForCurrentRuleset);
|
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new OsuRulesetContainer(this, beatmap, isForCurrentRuleset);
|
||||||
|
|
||||||
public override IEnumerable<BeatmapStatistic> GetBeatmapStatistics(WorkingBeatmap beatmap) => new[]
|
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
||||||
{
|
{
|
||||||
|
new KeyBinding(InputKey.Z, OsuAction.LeftButton),
|
||||||
|
new KeyBinding(InputKey.X, OsuAction.RightButton),
|
||||||
|
new KeyBinding(InputKey.LastKey + 1, OsuAction.LeftButton),
|
||||||
|
new KeyBinding(InputKey.LastKey + 2, OsuAction.RightButton),
|
||||||
|
};
|
||||||
|
|
||||||
|
public override IEnumerable<BeatmapStatistic> GetBeatmapStatistics(WorkingBeatmap beatmap) => new[]
|
||||||
|
{
|
||||||
new BeatmapStatistic
|
new BeatmapStatistic
|
||||||
{
|
{
|
||||||
Name = @"Circle count",
|
Name = @"Circle count",
|
||||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
|
|
||||||
protected override Playfield<OsuHitObject, OsuJudgement> CreatePlayfield() => new OsuPlayfield();
|
protected override Playfield<OsuHitObject, OsuJudgement> CreatePlayfield() => new OsuPlayfield();
|
||||||
|
|
||||||
protected override PassThroughInputManager CreateActionMappingInputManager() => new OsuInputManager(Ruleset?.RulesetInfo);
|
public override PassThroughInputManager CreateKeyBindingInputManager() => new OsuInputManager(Ruleset?.RulesetInfo);
|
||||||
|
|
||||||
protected override DrawableHitObject<OsuHitObject, OsuJudgement> GetVisualRepresentation(OsuHitObject h)
|
protected override DrawableHitObject<OsuHitObject, OsuJudgement> GetVisualRepresentation(OsuHitObject h)
|
||||||
{
|
{
|
||||||
|
@ -2,16 +2,17 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Taiko.Judgements;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A line that scrolls alongside hit objects in the playfield and visualises control points.
|
/// A line that scrolls alongside hit objects in the playfield and visualises control points.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DrawableBarLine : Container
|
public class DrawableBarLine : DrawableScrollingHitObject<TaikoHitObject, TaikoJudgement>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The width of the line tracker.
|
/// The width of the line tracker.
|
||||||
@ -34,15 +35,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
protected readonly BarLine BarLine;
|
protected readonly BarLine BarLine;
|
||||||
|
|
||||||
public DrawableBarLine(BarLine barLine)
|
public DrawableBarLine(BarLine barLine)
|
||||||
|
: base(barLine)
|
||||||
{
|
{
|
||||||
BarLine = barLine;
|
BarLine = barLine;
|
||||||
|
|
||||||
Anchor = Anchor.CentreLeft;
|
Anchor = Anchor.CentreLeft;
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
RelativePositionAxes = Axes.X;
|
|
||||||
RelativeSizeAxes = Axes.Y;
|
RelativeSizeAxes = Axes.Y;
|
||||||
|
|
||||||
Width = tracker_width;
|
Width = tracker_width;
|
||||||
|
|
||||||
Children = new[]
|
Children = new[]
|
||||||
@ -56,24 +56,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
Alpha = 0.75f
|
Alpha = 0.75f
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
LifetimeStart = BarLine.StartTime - BarLine.ScrollTime * 2;
|
|
||||||
LifetimeEnd = BarLine.StartTime + BarLine.ScrollTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override TaikoJudgement CreateJudgement() => new TaikoJudgement();
|
||||||
|
|
||||||
|
protected override void UpdateState(ArmedState state)
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
|
||||||
this.Delay(BarLine.StartTime - Time.Current).FadeOut(base_fadeout_time * BarLine.ScrollTime / 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateScrollPosition(double time) => this.MoveToX((float)((BarLine.StartTime - time) / BarLine.ScrollTime));
|
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
base.Update();
|
|
||||||
|
|
||||||
updateScrollPosition(Time.Current);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,6 +11,7 @@ using OpenTK;
|
|||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||||
{
|
{
|
||||||
@ -31,30 +32,29 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
public DrawableDrumRoll(DrumRoll drumRoll)
|
public DrawableDrumRoll(DrumRoll drumRoll)
|
||||||
: base(drumRoll)
|
: base(drumRoll)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Y;
|
Width = (float)HitObject.Duration;
|
||||||
AutoSizeAxes = Axes.X;
|
|
||||||
|
Container<DrawableDrumRollTick> tickContainer;
|
||||||
|
MainPiece.Add(tickContainer = new Container<DrawableDrumRollTick>
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
RelativeChildOffset = new Vector2((float)HitObject.StartTime, 0),
|
||||||
|
RelativeChildSize = new Vector2((float)HitObject.Duration, 1)
|
||||||
|
});
|
||||||
|
|
||||||
foreach (var tick in drumRoll.Ticks)
|
foreach (var tick in drumRoll.Ticks)
|
||||||
{
|
{
|
||||||
var newTick = new DrawableDrumRollTick(tick)
|
var newTick = new DrawableDrumRollTick(tick);
|
||||||
{
|
|
||||||
X = (float)((tick.StartTime - HitObject.StartTime) / HitObject.Duration)
|
|
||||||
};
|
|
||||||
|
|
||||||
newTick.OnJudgement += onTickJudgement;
|
newTick.OnJudgement += onTickJudgement;
|
||||||
|
|
||||||
AddNested(newTick);
|
AddNested(newTick);
|
||||||
MainPiece.Add(newTick);
|
tickContainer.Add(newTick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override TaikoJudgement CreateJudgement() => new TaikoJudgement { SecondHit = HitObject.IsStrong };
|
protected override TaikoJudgement CreateJudgement() => new TaikoJudgement { SecondHit = HitObject.IsStrong };
|
||||||
|
|
||||||
protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece
|
protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece();
|
||||||
{
|
|
||||||
Length = (float)(HitObject.Duration / HitObject.ScrollTime),
|
|
||||||
PlayfieldLengthReference = () => Parent.DrawSize.X
|
|
||||||
};
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
@ -63,17 +63,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
accentDarkColour = colours.YellowDarker;
|
accentDarkColour = colours.YellowDarker;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
// This is naive, however it's based on the reasoning that the hit target
|
|
||||||
// is further than mid point of the play field, so the time taken to scroll in should always
|
|
||||||
// be greater than the time taken to scroll out to the left of the screen.
|
|
||||||
// Thus, using PreEmpt here is enough for the drum roll to completely scroll out.
|
|
||||||
LifetimeEnd = HitObject.EndTime + HitObject.ScrollTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onTickJudgement(DrawableHitObject<TaikoHitObject, TaikoJudgement> obj)
|
private void onTickJudgement(DrawableHitObject<TaikoHitObject, TaikoJudgement> obj)
|
||||||
{
|
{
|
||||||
if (obj.Judgement.Result == HitResult.Hit)
|
if (obj.Judgement.Result == HitResult.Hit)
|
||||||
|
@ -15,9 +15,21 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
public DrawableDrumRollTick(DrumRollTick tick)
|
public DrawableDrumRollTick(DrumRollTick tick)
|
||||||
: base(tick)
|
: base(tick)
|
||||||
{
|
{
|
||||||
|
// Because ticks aren't added by the ScrollingPlayfield, we need to set the following properties ourselves
|
||||||
|
RelativePositionAxes = Axes.X;
|
||||||
|
X = (float)tick.StartTime;
|
||||||
|
|
||||||
FillMode = FillMode.Fit;
|
FillMode = FillMode.Fit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
// We need to set this here because RelativeSizeAxes won't/can't set our size by default with a different RelativeChildSize
|
||||||
|
Width *= Parent.RelativeChildSize.X;
|
||||||
|
}
|
||||||
|
|
||||||
protected override TaikoPiece CreateMainPiece() => new TickPiece
|
protected override TaikoPiece CreateMainPiece() => new TickPiece
|
||||||
{
|
{
|
||||||
Filled = HitObject.FirstTick
|
Filled = HitObject.FirstTick
|
||||||
@ -47,11 +59,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateScrollPosition(double time)
|
|
||||||
{
|
|
||||||
// Ticks don't move
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool HandleKeyPress(Key key)
|
protected override bool HandleKeyPress(Key key)
|
||||||
{
|
{
|
||||||
return Judgement.Result == HitResult.None && UpdateJudgement(true);
|
return Judgement.Result == HitResult.None && UpdateJudgement(true);
|
||||||
|
@ -29,6 +29,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
FillMode = FillMode.Fit;
|
FillMode = FillMode.Fit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
// We need to set this here because RelativeSizeAxes won't/can't set our size by default with a different RelativeChildSize
|
||||||
|
Width *= Parent.RelativeChildSize.X;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void CheckJudgement(bool userTriggered)
|
protected override void CheckJudgement(bool userTriggered)
|
||||||
{
|
{
|
||||||
if (!userTriggered)
|
if (!userTriggered)
|
||||||
|
@ -118,7 +118,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
});
|
});
|
||||||
|
|
||||||
MainPiece.Add(symbol = new SwellSymbolPiece());
|
MainPiece.Add(symbol = new SwellSymbolPiece());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -129,6 +128,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
targetRing.BorderColour = colours.YellowDark.Opacity(0.25f);
|
targetRing.BorderColour = colours.YellowDark.Opacity(0.25f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
// We need to set this here because RelativeSizeAxes won't/can't set our size by default with a different RelativeChildSize
|
||||||
|
Width *= Parent.RelativeChildSize.X;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void CheckJudgement(bool userTriggered)
|
protected override void CheckJudgement(bool userTriggered)
|
||||||
{
|
{
|
||||||
if (userTriggered)
|
if (userTriggered)
|
||||||
@ -189,20 +196,22 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
Expire();
|
Expire();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateScrollPosition(double time)
|
protected override void Update()
|
||||||
{
|
{
|
||||||
// Make the swell stop at the hit target
|
base.Update();
|
||||||
double t = Math.Min(HitObject.StartTime, time);
|
|
||||||
|
|
||||||
|
// Make the swell stop at the hit target
|
||||||
|
X = (float)Math.Max(Time.Current, HitObject.StartTime);
|
||||||
|
|
||||||
|
double t = Math.Min(HitObject.StartTime, Time.Current);
|
||||||
if (t == HitObject.StartTime && !hasStarted)
|
if (t == HitObject.StartTime && !hasStarted)
|
||||||
{
|
{
|
||||||
OnStart?.Invoke();
|
OnStart?.Invoke();
|
||||||
hasStarted = true;
|
hasStarted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
base.UpdateScrollPosition(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected override bool HandleKeyPress(Key key)
|
protected override bool HandleKeyPress(Key key)
|
||||||
{
|
{
|
||||||
if (Judgement.Result != HitResult.None)
|
if (Judgement.Result != HitResult.None)
|
||||||
|
@ -12,7 +12,7 @@ using OpenTK.Input;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||||
{
|
{
|
||||||
public abstract class DrawableTaikoHitObject<TaikoHitType> : DrawableHitObject<TaikoHitObject, TaikoJudgement>
|
public abstract class DrawableTaikoHitObject<TaikoHitType> : DrawableScrollingHitObject<TaikoHitObject, TaikoJudgement>
|
||||||
where TaikoHitType : TaikoHitObject
|
where TaikoHitType : TaikoHitObject
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -38,30 +38,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
Size = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
|
Size = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
|
||||||
|
|
||||||
RelativePositionAxes = Axes.X;
|
|
||||||
|
|
||||||
Add(MainPiece = CreateMainPiece());
|
Add(MainPiece = CreateMainPiece());
|
||||||
MainPiece.KiaiMode = HitObject.Kiai;
|
MainPiece.KiaiMode = HitObject.Kiai;
|
||||||
|
|
||||||
LifetimeStart = HitObject.StartTime - HitObject.ScrollTime * 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override TaikoJudgement CreateJudgement() => new TaikoJudgement();
|
protected override TaikoJudgement CreateJudgement() => new TaikoJudgement();
|
||||||
|
|
||||||
protected virtual TaikoPiece CreateMainPiece() => new CirclePiece();
|
protected virtual TaikoPiece CreateMainPiece() => new CirclePiece();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the scroll position of the DrawableHitObject relative to the offset between
|
|
||||||
/// a time value and the HitObject's StartTime.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="time"></param>
|
|
||||||
protected virtual void UpdateScrollPosition(double time) => X = (float)((HitObject.StartTime - time) / HitObject.ScrollTime);
|
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
UpdateScrollPosition(Time.Current);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual bool HandleKeyPress(Key key) => false;
|
protected virtual bool HandleKeyPress(Key key) => false;
|
||||||
|
|
||||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||||
|
@ -1,23 +1,12 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
||||||
{
|
{
|
||||||
public class ElongatedCirclePiece : CirclePiece
|
public class ElongatedCirclePiece : CirclePiece
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// As we are being used to define the absolute size of hits, we need to be given a relative reference of our containing playfield container.
|
|
||||||
/// </summary>
|
|
||||||
public Func<float> PlayfieldLengthReference;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The length of this piece as a multiple of the value returned by <see cref="PlayfieldLengthReference"/>
|
|
||||||
/// </summary>
|
|
||||||
public float Length;
|
|
||||||
|
|
||||||
public ElongatedCirclePiece()
|
public ElongatedCirclePiece()
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Y;
|
RelativeSizeAxes = Axes.Y;
|
||||||
@ -35,7 +24,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
|||||||
Right = padding,
|
Right = padding,
|
||||||
};
|
};
|
||||||
|
|
||||||
Width = (PlayfieldLengthReference?.Invoke() ?? 0) * Length + DrawHeight;
|
Width = Parent.DrawSize.X + DrawHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,6 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
ret.Add(new DrumRollTick
|
ret.Add(new DrumRollTick
|
||||||
{
|
{
|
||||||
FirstTick = first,
|
FirstTick = first,
|
||||||
ScrollTime = ScrollTime,
|
|
||||||
TickSpacing = tickSpacing,
|
TickSpacing = tickSpacing,
|
||||||
StartTime = t,
|
StartTime = t,
|
||||||
IsStrong = IsStrong,
|
IsStrong = IsStrong,
|
||||||
|
@ -24,16 +24,6 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const float DEFAULT_STRONG_SIZE = DEFAULT_SIZE * STRONG_SCALE;
|
public const float DEFAULT_STRONG_SIZE = DEFAULT_SIZE * STRONG_SCALE;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The time taken from the initial (off-screen) spawn position to the centre of the hit target for a <see cref="TimingControlPoint.BeatLength"/> of 1000ms.
|
|
||||||
/// </summary>
|
|
||||||
private const double scroll_time = 6000;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Our adjusted <see cref="scroll_time"/> taking into consideration local <see cref="TimingControlPoint.BeatLength"/> and other speed multipliers.
|
|
||||||
/// </summary>
|
|
||||||
public double ScrollTime;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this HitObject is a "strong" type.
|
/// Whether this HitObject is a "strong" type.
|
||||||
/// Strong hit objects give more points for hitting the hit object with both keys.
|
/// Strong hit objects give more points for hitting the hit object with both keys.
|
||||||
@ -49,12 +39,8 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
{
|
{
|
||||||
base.ApplyDefaults(controlPointInfo, difficulty);
|
base.ApplyDefaults(controlPointInfo, difficulty);
|
||||||
|
|
||||||
TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime);
|
|
||||||
DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(StartTime);
|
|
||||||
EffectControlPoint effectPoint = controlPointInfo.EffectPointAt(StartTime);
|
EffectControlPoint effectPoint = controlPointInfo.EffectPointAt(StartTime);
|
||||||
|
|
||||||
ScrollTime = scroll_time * (timingPoint.BeatLength * difficultyPoint.SpeedMultiplier / 1000) / difficulty.SliderMultiplier;
|
|
||||||
|
|
||||||
Kiai |= effectPoint.KiaiMode;
|
Kiai |= effectPoint.KiaiMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.UI
|
namespace osu.Game.Rulesets.Taiko.UI
|
||||||
{
|
{
|
||||||
public class TaikoPlayfield : Playfield<TaikoHitObject, TaikoJudgement>
|
public class TaikoPlayfield : ScrollingPlayfield<TaikoHitObject, TaikoJudgement>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default height of a <see cref="TaikoPlayfield"/> when inside a <see cref="TaikoRulesetContainer"/>.
|
/// Default height of a <see cref="TaikoPlayfield"/> when inside a <see cref="TaikoRulesetContainer"/>.
|
||||||
@ -35,14 +35,14 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const float left_area_size = 240;
|
private const float left_area_size = 240;
|
||||||
|
|
||||||
protected override Container<Drawable> Content => hitObjectContainer;
|
|
||||||
|
|
||||||
private readonly Container<HitExplosion> hitExplosionContainer;
|
private readonly Container<HitExplosion> hitExplosionContainer;
|
||||||
private readonly Container<KiaiHitExplosion> kiaiExplosionContainer;
|
private readonly Container<KiaiHitExplosion> kiaiExplosionContainer;
|
||||||
private readonly Container<DrawableBarLine> barLineContainer;
|
|
||||||
private readonly Container<DrawableTaikoJudgement> judgementContainer;
|
private readonly Container<DrawableTaikoJudgement> judgementContainer;
|
||||||
|
|
||||||
private readonly Container hitObjectContainer;
|
protected override Container<Drawable> Content => content;
|
||||||
|
private readonly Container content;
|
||||||
|
|
||||||
private readonly Container topLevelHitContainer;
|
private readonly Container topLevelHitContainer;
|
||||||
|
|
||||||
private readonly Container overlayBackgroundContainer;
|
private readonly Container overlayBackgroundContainer;
|
||||||
@ -52,6 +52,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
|
|
||||||
public TaikoPlayfield()
|
public TaikoPlayfield()
|
||||||
|
: base(Axes.X)
|
||||||
{
|
{
|
||||||
AddRangeInternal(new Drawable[]
|
AddRangeInternal(new Drawable[]
|
||||||
{
|
{
|
||||||
@ -96,10 +97,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
FillMode = FillMode.Fit,
|
FillMode = FillMode.Fit,
|
||||||
BlendingMode = BlendingMode.Additive,
|
BlendingMode = BlendingMode.Additive,
|
||||||
},
|
},
|
||||||
barLineContainer = new Container<DrawableBarLine>
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
},
|
|
||||||
new HitTarget
|
new HitTarget
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
@ -107,7 +104,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
FillMode = FillMode.Fit
|
FillMode = FillMode.Fit
|
||||||
},
|
},
|
||||||
hitObjectContainer = new Container
|
content = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
@ -181,6 +178,8 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
VisibleTimeRange.Value = 6000;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -205,11 +204,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
swell.OnStart += () => topLevelHitContainer.Add(swell.CreateProxy());
|
swell.OnStart += () => topLevelHitContainer.Add(swell.CreateProxy());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddBarLine(DrawableBarLine barLine)
|
|
||||||
{
|
|
||||||
barLineContainer.Add(barLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnJudgement(DrawableHitObject<TaikoHitObject, TaikoJudgement> judgedObject)
|
public override void OnJudgement(DrawableHitObject<TaikoHitObject, TaikoJudgement> judgedObject)
|
||||||
{
|
{
|
||||||
bool wasHit = judgedObject.Judgement.Result == HitResult.Hit;
|
bool wasHit = judgedObject.Judgement.Result == HitResult.Hit;
|
||||||
@ -230,7 +224,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
|
|
||||||
if (!secondHit)
|
if (!secondHit)
|
||||||
{
|
{
|
||||||
if (judgedObject.X >= -0.05f && !(judgedObject is DrawableSwell))
|
if (judgedObject.X >= -0.05f && judgedObject is DrawableHit)
|
||||||
{
|
{
|
||||||
// If we're far enough away from the left stage, we should bring outselves in front of it
|
// If we're far enough away from the left stage, we should bring outselves in front of it
|
||||||
topLevelHitContainer.Add(judgedObject.CreateProxy());
|
topLevelHitContainer.Add(judgedObject.CreateProxy());
|
||||||
|
@ -21,7 +21,7 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.UI
|
namespace osu.Game.Rulesets.Taiko.UI
|
||||||
{
|
{
|
||||||
public class TaikoRulesetContainer : RulesetContainer<TaikoHitObject, TaikoJudgement>
|
public class TaikoRulesetContainer : ScrollingRulesetContainer<TaikoPlayfield, TaikoHitObject, TaikoJudgement>
|
||||||
{
|
{
|
||||||
public TaikoRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
public TaikoRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||||
: base(ruleset, beatmap, isForCurrentRuleset)
|
: base(ruleset, beatmap, isForCurrentRuleset)
|
||||||
@ -36,11 +36,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
|
|
||||||
private void loadBarLines()
|
private void loadBarLines()
|
||||||
{
|
{
|
||||||
var taikoPlayfield = Playfield as TaikoPlayfield;
|
|
||||||
|
|
||||||
if (taikoPlayfield == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TaikoHitObject lastObject = Beatmap.HitObjects[Beatmap.HitObjects.Count - 1];
|
TaikoHitObject lastObject = Beatmap.HitObjects[Beatmap.HitObjects.Count - 1];
|
||||||
double lastHitTime = 1 + (lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime;
|
double lastHitTime = 1 + (lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime;
|
||||||
|
|
||||||
@ -72,7 +67,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
barLine.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.Difficulty);
|
barLine.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.Difficulty);
|
||||||
|
|
||||||
bool isMajor = currentBeat % (int)currentPoint.TimeSignature == 0;
|
bool isMajor = currentBeat % (int)currentPoint.TimeSignature == 0;
|
||||||
taikoPlayfield.AddBarLine(isMajor ? new DrawableBarLineMajor(barLine) : new DrawableBarLine(barLine));
|
Playfield.Add(isMajor ? new DrawableBarLineMajor(barLine) : new DrawableBarLine(barLine));
|
||||||
|
|
||||||
double bl = currentPoint.BeatLength;
|
double bl = currentPoint.BeatLength;
|
||||||
if (bl < 800)
|
if (bl < 800)
|
||||||
|
@ -307,6 +307,11 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <returns>The imported beatmap, or an existing instance if it is already present.</returns>
|
/// <returns>The imported beatmap, or an existing instance if it is already present.</returns>
|
||||||
private BeatmapSetInfo importToStorage(ArchiveReader reader)
|
private BeatmapSetInfo importToStorage(ArchiveReader reader)
|
||||||
{
|
{
|
||||||
|
// let's make sure there are actually .osu files to import.
|
||||||
|
string mapName = reader.Filenames.FirstOrDefault(f => f.EndsWith(".osu"));
|
||||||
|
if (string.IsNullOrEmpty(mapName))
|
||||||
|
throw new InvalidOperationException("No beatmap files found in the map folder.");
|
||||||
|
|
||||||
// for now, concatenate all .osu files in the set to create a unique hash.
|
// for now, concatenate all .osu files in the set to create a unique hash.
|
||||||
MemoryStream hashable = new MemoryStream();
|
MemoryStream hashable = new MemoryStream();
|
||||||
foreach (string file in reader.Filenames.Where(f => f.EndsWith(".osu")))
|
foreach (string file in reader.Filenames.Where(f => f.EndsWith(".osu")))
|
||||||
@ -339,7 +344,7 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
BeatmapMetadata metadata;
|
BeatmapMetadata metadata;
|
||||||
|
|
||||||
using (var stream = new StreamReader(reader.GetStream(reader.Filenames.First(f => f.EndsWith(".osu")))))
|
using (var stream = new StreamReader(reader.GetStream(mapName)))
|
||||||
metadata = BeatmapDecoder.GetDecoder(stream).Decode(stream).Metadata;
|
metadata = BeatmapDecoder.GetDecoder(stream).Decode(stream).Metadata;
|
||||||
|
|
||||||
beatmapSet = new BeatmapSetInfo
|
beatmapSet = new BeatmapSetInfo
|
||||||
|
@ -19,7 +19,9 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
|
|
||||||
public static BeatmapDecoder GetDecoder(StreamReader stream)
|
public static BeatmapDecoder GetDecoder(StreamReader stream)
|
||||||
{
|
{
|
||||||
string line = stream.ReadLine()?.Trim();
|
string line;
|
||||||
|
do { line = stream.ReadLine()?.Trim(); }
|
||||||
|
while (line != null && line.Length == 0);
|
||||||
|
|
||||||
if (line == null || !decoders.ContainsKey(line))
|
if (line == null || !decoders.ContainsKey(line))
|
||||||
throw new IOException(@"Unknown file format");
|
throw new IOException(@"Unknown file format");
|
||||||
|
@ -27,7 +27,9 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
AddDecoder<OsuLegacyDecoder>(@"osu file format v7");
|
AddDecoder<OsuLegacyDecoder>(@"osu file format v7");
|
||||||
AddDecoder<OsuLegacyDecoder>(@"osu file format v6");
|
AddDecoder<OsuLegacyDecoder>(@"osu file format v6");
|
||||||
AddDecoder<OsuLegacyDecoder>(@"osu file format v5");
|
AddDecoder<OsuLegacyDecoder>(@"osu file format v5");
|
||||||
// TODO: Not sure how far back to go, or differences between versions
|
AddDecoder<OsuLegacyDecoder>(@"osu file format v4");
|
||||||
|
AddDecoder<OsuLegacyDecoder>(@"osu file format v3");
|
||||||
|
// TODO: differences between versions
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConvertHitObjectParser parser;
|
private ConvertHitObjectParser parser;
|
||||||
@ -222,6 +224,7 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
{
|
{
|
||||||
while (line.IndexOf('$') >= 0)
|
while (line.IndexOf('$') >= 0)
|
||||||
{
|
{
|
||||||
|
string origLine = line;
|
||||||
string[] split = line.Split(',');
|
string[] split = line.Split(',');
|
||||||
for (int i = 0; i < split.Length; i++)
|
for (int i = 0; i < split.Length; i++)
|
||||||
{
|
{
|
||||||
@ -231,6 +234,7 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
}
|
}
|
||||||
|
|
||||||
line = string.Join(",", split);
|
line = string.Join(",", split);
|
||||||
|
if (line == origLine) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,6 +331,7 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
|
|
||||||
if (speedMultiplier != difficultyPoint.SpeedMultiplier)
|
if (speedMultiplier != difficultyPoint.SpeedMultiplier)
|
||||||
{
|
{
|
||||||
|
beatmap.ControlPointInfo.DifficultyPoints.RemoveAll(x => x.Time == time);
|
||||||
beatmap.ControlPointInfo.DifficultyPoints.Add(new DifficultyControlPoint
|
beatmap.ControlPointInfo.DifficultyPoints.Add(new DifficultyControlPoint
|
||||||
{
|
{
|
||||||
Time = time,
|
Time = time,
|
||||||
|
@ -34,9 +34,8 @@ namespace osu.Game.Graphics.Containers
|
|||||||
protected override Container<Drawable> Content => content;
|
protected override Container<Drawable> Content => content;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(UserInputManager input, OsuConfigManager config)
|
private void load(OsuConfigManager config)
|
||||||
{
|
{
|
||||||
this.input = input;
|
|
||||||
parallaxEnabled = config.GetBindable<bool>(OsuSetting.MenuParallax);
|
parallaxEnabled = config.GetBindable<bool>(OsuSetting.MenuParallax);
|
||||||
parallaxEnabled.ValueChanged += delegate
|
parallaxEnabled.ValueChanged += delegate
|
||||||
{
|
{
|
||||||
@ -48,6 +47,12 @@ namespace osu.Game.Graphics.Containers
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
input = GetContainingInputManager();
|
||||||
|
}
|
||||||
|
|
||||||
private bool firstUpdate = true;
|
private bool firstUpdate = true;
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
|
@ -3,10 +3,8 @@
|
|||||||
|
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Graphics.UserInterface
|
||||||
{
|
{
|
||||||
@ -28,34 +26,28 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
{
|
{
|
||||||
focus = value;
|
focus = value;
|
||||||
if (!focus && HasFocus)
|
if (!focus && HasFocus)
|
||||||
inputManager.ChangeFocus(null);
|
GetContainingInputManager().ChangeFocus(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputManager inputManager;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(UserInputManager inputManager)
|
|
||||||
{
|
|
||||||
this.inputManager = inputManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnFocus(InputState state)
|
protected override void OnFocus(InputState state)
|
||||||
{
|
{
|
||||||
base.OnFocus(state);
|
base.OnFocus(state);
|
||||||
BorderThickness = 0;
|
BorderThickness = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnFocusLost(InputState state)
|
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||||
{
|
{
|
||||||
if (state.Keyboard.Keys.Any(key => key == Key.Escape))
|
if (args.Key == Key.Escape)
|
||||||
{
|
{
|
||||||
if (Text.Length > 0)
|
if (Text.Length > 0)
|
||||||
Text = string.Empty;
|
Text = string.Empty;
|
||||||
else
|
else
|
||||||
Exit?.Invoke();
|
Exit?.Invoke();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
base.OnFocusLost(state);
|
|
||||||
|
return base.OnKeyDown(state, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool RequestsFocus => HoldFocus;
|
public override bool RequestsFocus => HoldFocus;
|
||||||
|
@ -7,6 +7,7 @@ using osu.Framework.Audio;
|
|||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
@ -16,7 +17,7 @@ using osu.Game.Graphics.Sprites;
|
|||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Graphics.UserInterface
|
||||||
{
|
{
|
||||||
public class OsuButton : Button
|
public class OsuButton : Button, IFilterable
|
||||||
{
|
{
|
||||||
private Box hover;
|
private Box hover;
|
||||||
|
|
||||||
@ -108,5 +109,15 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
Content.ScaleTo(1, 1000, Easing.OutElastic);
|
Content.ScaleTo(1, 1000, Easing.OutElastic);
|
||||||
return base.OnMouseUp(state, args);
|
return base.OnMouseUp(state, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string[] FilterTerms => new[] { Text };
|
||||||
|
|
||||||
|
public bool MatchingFilter
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.FadeTo(value ? 1 : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,8 +15,6 @@ namespace osu.Game.Graphics.UserInterface.Volume
|
|||||||
{
|
{
|
||||||
private readonly VolumeMeter volumeMeterMaster;
|
private readonly VolumeMeter volumeMeterMaster;
|
||||||
|
|
||||||
protected override bool HideOnEscape => false;
|
|
||||||
|
|
||||||
private void volumeChanged(double newVolume)
|
private void volumeChanged(double newVolume)
|
||||||
{
|
{
|
||||||
Show();
|
Show();
|
||||||
|
@ -1,48 +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.Platform;
|
|
||||||
using osu.Game.Database;
|
|
||||||
using osu.Game.Input.Bindings;
|
|
||||||
using SQLite.Net;
|
|
||||||
|
|
||||||
namespace osu.Game.Input
|
|
||||||
{
|
|
||||||
public class BindingStore : DatabaseBackedStore
|
|
||||||
{
|
|
||||||
public BindingStore(SQLiteConnection connection, Storage storage = null)
|
|
||||||
: base(connection, storage)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override int StoreVersion => 2;
|
|
||||||
|
|
||||||
protected override void PerformMigration(int currentVersion, int targetVersion)
|
|
||||||
{
|
|
||||||
base.PerformMigration(currentVersion, targetVersion);
|
|
||||||
|
|
||||||
while (currentVersion++ < targetVersion)
|
|
||||||
{
|
|
||||||
switch (currentVersion)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
// cannot migrate; breaking underlying changes.
|
|
||||||
Reset();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Prepare(bool reset = false)
|
|
||||||
{
|
|
||||||
Connection.CreateTable<DatabasedKeyBinding>();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Type[] ValidTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(DatabasedKeyBinding)
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,6 +11,9 @@ namespace osu.Game.Input.Bindings
|
|||||||
[Table("KeyBinding")]
|
[Table("KeyBinding")]
|
||||||
public class DatabasedKeyBinding : KeyBinding
|
public class DatabasedKeyBinding : KeyBinding
|
||||||
{
|
{
|
||||||
|
[PrimaryKey, AutoIncrement]
|
||||||
|
public int ID { get; set; }
|
||||||
|
|
||||||
[ForeignKey(typeof(RulesetInfo))]
|
[ForeignKey(typeof(RulesetInfo))]
|
||||||
public int? RulesetID { get; set; }
|
public int? RulesetID { get; set; }
|
||||||
|
|
||||||
@ -24,11 +27,12 @@ namespace osu.Game.Input.Bindings
|
|||||||
private set { KeyCombination = value; }
|
private set { KeyCombination = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Indexed]
|
||||||
[Column("Action")]
|
[Column("Action")]
|
||||||
public new int Action
|
public int IntAction
|
||||||
{
|
{
|
||||||
get { return base.Action; }
|
get { return (int)Action; }
|
||||||
private set { base.Action = value; }
|
set { Action = value; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
@ -18,7 +20,9 @@ namespace osu.Game.Input.Bindings
|
|||||||
|
|
||||||
private readonly int? variant;
|
private readonly int? variant;
|
||||||
|
|
||||||
private BindingStore store;
|
private KeyBindingStore store;
|
||||||
|
|
||||||
|
public override IEnumerable<KeyBinding> DefaultKeyBindings => ruleset.CreateInstance().GetDefaultKeyBindings();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new instance.
|
/// Create a new instance.
|
||||||
@ -31,27 +35,20 @@ namespace osu.Game.Input.Bindings
|
|||||||
{
|
{
|
||||||
this.ruleset = ruleset;
|
this.ruleset = ruleset;
|
||||||
this.variant = variant;
|
this.variant = variant;
|
||||||
|
|
||||||
|
if (ruleset != null && variant == null)
|
||||||
|
throw new InvalidOperationException($"{nameof(variant)} can not be null when a non-null {nameof(ruleset)} is provided.");
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(BindingStore bindings)
|
private void load(KeyBindingStore keyBindings)
|
||||||
{
|
{
|
||||||
store = bindings;
|
store = keyBindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ReloadMappings()
|
protected override void ReloadMappings()
|
||||||
{
|
{
|
||||||
// load defaults
|
KeyBindings = store.Query(ruleset?.ID, variant);
|
||||||
base.ReloadMappings();
|
|
||||||
|
|
||||||
var rulesetId = ruleset?.ID;
|
|
||||||
|
|
||||||
// load from database if present.
|
|
||||||
if (store != null)
|
|
||||||
{
|
|
||||||
foreach (var b in store.Query<DatabasedKeyBinding>(b => b.RulesetID == rulesetId && b.Variant == variant))
|
|
||||||
KeyBindings.Add(b);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,68 +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 OpenTK.Input;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Input;
|
|
||||||
using osu.Framework.Input.Bindings;
|
|
||||||
|
|
||||||
namespace osu.Game.Input.Bindings
|
|
||||||
{
|
|
||||||
public class GlobalBindingInputManager : DatabasedKeyBindingInputManager<GlobalAction>
|
|
||||||
{
|
|
||||||
private readonly Drawable handler;
|
|
||||||
|
|
||||||
public GlobalBindingInputManager(OsuGameBase game)
|
|
||||||
{
|
|
||||||
if (game is IKeyBindingHandler<GlobalAction>)
|
|
||||||
handler = game;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override IEnumerable<KeyBinding> CreateDefaultMappings() => new[]
|
|
||||||
{
|
|
||||||
new KeyBinding(Key.F8, GlobalAction.ToggleChat),
|
|
||||||
new KeyBinding(Key.F9, GlobalAction.ToggleSocial),
|
|
||||||
new KeyBinding(new[] { Key.LControl, Key.LAlt, Key.R }, GlobalAction.ResetInputSettings),
|
|
||||||
new KeyBinding(new[] { Key.LControl, Key.T }, GlobalAction.ToggleToolbar),
|
|
||||||
new KeyBinding(new[] { Key.LControl, Key.O }, GlobalAction.ToggleSettings),
|
|
||||||
new KeyBinding(new[] { Key.LControl, Key.D }, GlobalAction.ToggleDirect),
|
|
||||||
};
|
|
||||||
|
|
||||||
protected override bool PropagateKeyDown(IEnumerable<Drawable> drawables, InputState state, KeyDownEventArgs args)
|
|
||||||
{
|
|
||||||
if (handler != null)
|
|
||||||
drawables = new[] { handler }.Concat(drawables);
|
|
||||||
|
|
||||||
// always handle ourselves before all children.
|
|
||||||
return base.PropagateKeyDown(drawables, state, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool PropagateKeyUp(IEnumerable<Drawable> drawables, InputState state, KeyUpEventArgs args)
|
|
||||||
{
|
|
||||||
if (handler != null)
|
|
||||||
drawables = new[] { handler }.Concat(drawables);
|
|
||||||
|
|
||||||
// always handle ourselves before all children.
|
|
||||||
return base.PropagateKeyUp(drawables, state, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum GlobalAction
|
|
||||||
{
|
|
||||||
[Description("Toggle chat overlay")]
|
|
||||||
ToggleChat,
|
|
||||||
[Description("Toggle social overlay")]
|
|
||||||
ToggleSocial,
|
|
||||||
[Description("Reset input settings")]
|
|
||||||
ResetInputSettings,
|
|
||||||
[Description("Toggle toolbar")]
|
|
||||||
ToggleToolbar,
|
|
||||||
[Description("Toggle settings")]
|
|
||||||
ToggleSettings,
|
|
||||||
[Description("Toggle osu!direct")]
|
|
||||||
ToggleDirect,
|
|
||||||
}
|
|
||||||
}
|
|
51
osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs
Normal file
51
osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
|
|
||||||
|
namespace osu.Game.Input.Bindings
|
||||||
|
{
|
||||||
|
public class GlobalKeyBindingInputManager : DatabasedKeyBindingInputManager<GlobalAction>
|
||||||
|
{
|
||||||
|
private readonly Drawable handler;
|
||||||
|
|
||||||
|
public GlobalKeyBindingInputManager(OsuGameBase game)
|
||||||
|
{
|
||||||
|
if (game is IKeyBindingHandler<GlobalAction>)
|
||||||
|
handler = game;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<KeyBinding> DefaultKeyBindings => new[]
|
||||||
|
{
|
||||||
|
new KeyBinding(InputKey.F8, GlobalAction.ToggleChat),
|
||||||
|
new KeyBinding(InputKey.F9, GlobalAction.ToggleSocial),
|
||||||
|
new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.R }, GlobalAction.ResetInputSettings),
|
||||||
|
new KeyBinding(new[] { InputKey.Control, InputKey.T }, GlobalAction.ToggleToolbar),
|
||||||
|
new KeyBinding(new[] { InputKey.Control, InputKey.O }, GlobalAction.ToggleSettings),
|
||||||
|
new KeyBinding(new[] { InputKey.Control, InputKey.D }, GlobalAction.ToggleDirect),
|
||||||
|
};
|
||||||
|
|
||||||
|
protected override IEnumerable<Drawable> KeyBindingInputQueue =>
|
||||||
|
handler == null ? base.KeyBindingInputQueue : new[] { handler }.Concat(base.KeyBindingInputQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum GlobalAction
|
||||||
|
{
|
||||||
|
[Description("Toggle chat overlay")]
|
||||||
|
ToggleChat,
|
||||||
|
[Description("Toggle social overlay")]
|
||||||
|
ToggleSocial,
|
||||||
|
[Description("Reset input settings")]
|
||||||
|
ResetInputSettings,
|
||||||
|
[Description("Toggle toolbar")]
|
||||||
|
ToggleToolbar,
|
||||||
|
[Description("Toggle settings")]
|
||||||
|
ToggleSettings,
|
||||||
|
[Description("Toggle osu!direct")]
|
||||||
|
ToggleDirect,
|
||||||
|
}
|
||||||
|
}
|
93
osu.Game/Input/KeyBindingStore.cs
Normal file
93
osu.Game/Input/KeyBindingStore.cs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
|
using osu.Framework.Platform;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Input.Bindings;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using SQLite.Net;
|
||||||
|
|
||||||
|
namespace osu.Game.Input
|
||||||
|
{
|
||||||
|
public class KeyBindingStore : DatabaseBackedStore
|
||||||
|
{
|
||||||
|
public KeyBindingStore(SQLiteConnection connection, RulesetStore rulesets, Storage storage = null)
|
||||||
|
: base(connection, storage)
|
||||||
|
{
|
||||||
|
foreach (var info in rulesets.Query<RulesetInfo>())
|
||||||
|
{
|
||||||
|
var ruleset = info.CreateInstance();
|
||||||
|
foreach (var variant in ruleset.AvailableVariants)
|
||||||
|
insertDefaults(ruleset.GetDefaultKeyBindings(), info.ID, variant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Register(KeyBindingInputManager manager) => insertDefaults(manager.DefaultKeyBindings);
|
||||||
|
|
||||||
|
protected override int StoreVersion => 3;
|
||||||
|
|
||||||
|
protected override void PerformMigration(int currentVersion, int targetVersion)
|
||||||
|
{
|
||||||
|
base.PerformMigration(currentVersion, targetVersion);
|
||||||
|
|
||||||
|
while (currentVersion++ < targetVersion)
|
||||||
|
{
|
||||||
|
switch (currentVersion)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
// cannot migrate; breaking underlying changes.
|
||||||
|
Reset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Prepare(bool reset = false)
|
||||||
|
{
|
||||||
|
if (reset)
|
||||||
|
Connection.DropTable<DatabasedKeyBinding>();
|
||||||
|
|
||||||
|
Connection.CreateTable<DatabasedKeyBinding>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertDefaults(IEnumerable<KeyBinding> defaults, int? rulesetId = null, int? variant = null)
|
||||||
|
{
|
||||||
|
var query = Query(rulesetId, variant);
|
||||||
|
|
||||||
|
// compare counts in database vs defaults
|
||||||
|
foreach (var group in defaults.GroupBy(k => k.Action))
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
while (group.Count() > (count = query.Count(k => (int)k.Action == (int)group.Key)))
|
||||||
|
{
|
||||||
|
var insertable = group.Skip(count).First();
|
||||||
|
|
||||||
|
// insert any defaults which are missing.
|
||||||
|
Connection.Insert(new DatabasedKeyBinding
|
||||||
|
{
|
||||||
|
KeyCombination = insertable.KeyCombination,
|
||||||
|
Action = insertable.Action,
|
||||||
|
RulesetID = rulesetId,
|
||||||
|
Variant = variant
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Type[] ValidTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(DatabasedKeyBinding)
|
||||||
|
};
|
||||||
|
|
||||||
|
public IEnumerable<KeyBinding> Query(int? rulesetId = null, int? variant = null) =>
|
||||||
|
Query<DatabasedKeyBinding>(b => b.RulesetID == rulesetId && b.Variant == variant);
|
||||||
|
|
||||||
|
public void Update(KeyBinding keyBinding) => Connection.Update(keyBinding);
|
||||||
|
}
|
||||||
|
}
|
@ -182,7 +182,11 @@ namespace osu.Game
|
|||||||
LoadComponentAsync(direct = new DirectOverlay { Depth = -1 }, mainContent.Add);
|
LoadComponentAsync(direct = new DirectOverlay { Depth = -1 }, mainContent.Add);
|
||||||
LoadComponentAsync(social = new SocialOverlay { Depth = -1 }, mainContent.Add);
|
LoadComponentAsync(social = new SocialOverlay { Depth = -1 }, mainContent.Add);
|
||||||
LoadComponentAsync(chat = new ChatOverlay { Depth = -1 }, mainContent.Add);
|
LoadComponentAsync(chat = new ChatOverlay { Depth = -1 }, mainContent.Add);
|
||||||
LoadComponentAsync(settings = new SettingsOverlay { Depth = -1 }, overlayContent.Add);
|
LoadComponentAsync(settings = new MainSettings
|
||||||
|
{
|
||||||
|
GetToolbarHeight = () => ToolbarOffset,
|
||||||
|
Depth = -1
|
||||||
|
}, overlayContent.Add);
|
||||||
LoadComponentAsync(userProfile = new UserProfileOverlay { Depth = -2 }, mainContent.Add);
|
LoadComponentAsync(userProfile = new UserProfileOverlay { Depth = -2 }, mainContent.Add);
|
||||||
LoadComponentAsync(musicController = new MusicController
|
LoadComponentAsync(musicController = new MusicController
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ namespace osu.Game
|
|||||||
|
|
||||||
protected ScoreStore ScoreStore;
|
protected ScoreStore ScoreStore;
|
||||||
|
|
||||||
protected BindingStore BindingStore;
|
protected KeyBindingStore KeyBindingStore;
|
||||||
|
|
||||||
protected override string MainResourceFile => @"osu.Game.Resources.dll";
|
protected override string MainResourceFile => @"osu.Game.Resources.dll";
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ namespace osu.Game
|
|||||||
dependencies.Cache(FileStore = new FileStore(connection, Host.Storage));
|
dependencies.Cache(FileStore = new FileStore(connection, Host.Storage));
|
||||||
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, Host));
|
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, Host));
|
||||||
dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, connection, Host, BeatmapManager));
|
dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, connection, Host, BeatmapManager));
|
||||||
dependencies.Cache(BindingStore = new BindingStore(connection));
|
dependencies.Cache(KeyBindingStore = new KeyBindingStore(connection, RulesetStore));
|
||||||
dependencies.Cache(new OsuColour());
|
dependencies.Cache(new OsuColour());
|
||||||
|
|
||||||
//this completely overrides the framework default. will need to change once we make a proper FontStore.
|
//this completely overrides the framework default. will need to change once we make a proper FontStore.
|
||||||
@ -183,12 +183,14 @@ namespace osu.Game
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
|
GlobalKeyBindingInputManager globalBinding;
|
||||||
|
|
||||||
base.Content.Add(new RatioAdjust
|
base.Content.Add(new RatioAdjust
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
Cursor = new MenuCursor(),
|
Cursor = new MenuCursor(),
|
||||||
new GlobalBindingInputManager(this)
|
globalBinding = new GlobalKeyBindingInputManager(this)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Child = new OsuTooltipContainer(Cursor)
|
Child = new OsuTooltipContainer(Cursor)
|
||||||
@ -200,6 +202,9 @@ namespace osu.Game
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
KeyBindingStore.Register(globalBinding);
|
||||||
|
dependencies.Cache(globalBinding);
|
||||||
|
|
||||||
// TODO: This is temporary until we reimplement the local FPS display.
|
// TODO: This is temporary until we reimplement the local FPS display.
|
||||||
// It's just to allow end-users to access the framework FPS display without knowing the shortcut key.
|
// It's just to allow end-users to access the framework FPS display without knowing the shortcut key.
|
||||||
fpsDisplayVisible = LocalConfig.GetBindable<bool>(OsuSetting.ShowFpsDisplay);
|
fpsDisplayVisible = LocalConfig.GetBindable<bool>(OsuSetting.ShowFpsDisplay);
|
||||||
|
@ -152,7 +152,7 @@ namespace osu.Game.Overlays.Chat
|
|||||||
|
|
||||||
protected override void OnFocus(InputState state)
|
protected override void OnFocus(InputState state)
|
||||||
{
|
{
|
||||||
InputManager.ChangeFocus(search);
|
GetContainingInputManager().ChangeFocus(search);
|
||||||
base.OnFocus(state);
|
base.OnFocus(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ namespace osu.Game.Overlays
|
|||||||
protected override void OnFocus(InputState state)
|
protected override void OnFocus(InputState state)
|
||||||
{
|
{
|
||||||
//this is necessary as inputTextBox is masked away and therefore can't get focus :(
|
//this is necessary as inputTextBox is masked away and therefore can't get focus :(
|
||||||
InputManager.ChangeFocus(inputTextBox);
|
GetContainingInputManager().ChangeFocus(inputTextBox);
|
||||||
base.OnFocus(state);
|
base.OnFocus(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs
Normal file
23
osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// 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.Input.Bindings;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.KeyBinding
|
||||||
|
{
|
||||||
|
public class GlobalKeyBindingsSection : KeyBindingsSection
|
||||||
|
{
|
||||||
|
private readonly string name;
|
||||||
|
|
||||||
|
public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail;
|
||||||
|
public override string Header => name;
|
||||||
|
|
||||||
|
public GlobalKeyBindingsSection(KeyBindingInputManager manager, string name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
|
||||||
|
Defaults = manager.DefaultKeyBindings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
356
osu.Game/Overlays/KeyBinding/KeyBindingRow.cs
Normal file
356
osu.Game/Overlays/KeyBinding/KeyBindingRow.cs
Normal file
@ -0,0 +1,356 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Input;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Input;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
using OpenTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.KeyBinding
|
||||||
|
{
|
||||||
|
internal class KeyBindingRow : Container, IFilterable
|
||||||
|
{
|
||||||
|
private readonly Enum action;
|
||||||
|
private readonly IEnumerable<Framework.Input.Bindings.KeyBinding> bindings;
|
||||||
|
|
||||||
|
private const float transition_time = 150;
|
||||||
|
|
||||||
|
private const float height = 20;
|
||||||
|
|
||||||
|
private const float padding = 5;
|
||||||
|
|
||||||
|
private bool matchingFilter;
|
||||||
|
|
||||||
|
public bool MatchingFilter
|
||||||
|
{
|
||||||
|
get { return matchingFilter; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
matchingFilter = value;
|
||||||
|
this.FadeTo(!matchingFilter ? 0 : 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private OsuSpriteText text;
|
||||||
|
private OsuSpriteText pressAKey;
|
||||||
|
|
||||||
|
private FillFlowContainer<KeyButton> buttons;
|
||||||
|
|
||||||
|
public string[] FilterTerms => new[] { text.Text }.Concat(bindings.Select(b => b.KeyCombination.ReadableString())).ToArray();
|
||||||
|
|
||||||
|
public KeyBindingRow(Enum action, IEnumerable<Framework.Input.Bindings.KeyBinding> bindings)
|
||||||
|
{
|
||||||
|
this.action = action;
|
||||||
|
this.bindings = bindings;
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
|
||||||
|
Masking = true;
|
||||||
|
CornerRadius = padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyBindingStore store;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours, KeyBindingStore store)
|
||||||
|
{
|
||||||
|
this.store = store;
|
||||||
|
|
||||||
|
EdgeEffect = new EdgeEffectParameters
|
||||||
|
{
|
||||||
|
Radius = 2,
|
||||||
|
Colour = colours.YellowDark.Opacity(0),
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Hollow = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Black,
|
||||||
|
Alpha = 0.6f,
|
||||||
|
},
|
||||||
|
text = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = action.GetDescription(),
|
||||||
|
Margin = new MarginPadding(padding),
|
||||||
|
},
|
||||||
|
buttons = new FillFlowContainer<KeyButton>
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight
|
||||||
|
},
|
||||||
|
pressAKey = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = "Press a key to change binding, DEL to delete, ESC to cancel.",
|
||||||
|
Y = height,
|
||||||
|
Margin = new MarginPadding(padding),
|
||||||
|
Alpha = 0,
|
||||||
|
Colour = colours.YellowDark
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var b in bindings)
|
||||||
|
buttons.Add(new KeyButton(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnHover(InputState state)
|
||||||
|
{
|
||||||
|
this.FadeEdgeEffectTo<Container>(1, transition_time, Easing.OutQuint);
|
||||||
|
|
||||||
|
return base.OnHover(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(InputState state)
|
||||||
|
{
|
||||||
|
this.FadeEdgeEffectTo<Container>(0, transition_time, Easing.OutQuint);
|
||||||
|
|
||||||
|
base.OnHoverLost(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool AcceptsFocus => bindTarget == null;
|
||||||
|
|
||||||
|
private KeyButton bindTarget;
|
||||||
|
|
||||||
|
public bool AllowMainMouseButtons;
|
||||||
|
|
||||||
|
private bool isModifier(Key k) => k < Key.F1;
|
||||||
|
|
||||||
|
protected override bool OnClick(InputState state) => true;
|
||||||
|
|
||||||
|
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||||
|
{
|
||||||
|
if (HasFocus)
|
||||||
|
{
|
||||||
|
if (bindTarget.IsHovered)
|
||||||
|
{
|
||||||
|
if (!AllowMainMouseButtons)
|
||||||
|
{
|
||||||
|
switch (args.Button)
|
||||||
|
{
|
||||||
|
case MouseButton.Left:
|
||||||
|
case MouseButton.Right:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(state));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.OnMouseDown(state, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
||||||
|
{
|
||||||
|
if (HasFocus && !state.Mouse.Buttons.Any())
|
||||||
|
{
|
||||||
|
if (bindTarget.IsHovered)
|
||||||
|
finalise();
|
||||||
|
else
|
||||||
|
updateBindTarget();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.OnMouseUp(state, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||||
|
{
|
||||||
|
if (!HasFocus)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (args.Key)
|
||||||
|
{
|
||||||
|
case Key.Escape:
|
||||||
|
finalise();
|
||||||
|
return true;
|
||||||
|
case Key.Delete:
|
||||||
|
bindTarget.UpdateKeyCombination(InputKey.None);
|
||||||
|
finalise();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(state));
|
||||||
|
if (!isModifier(args.Key)) finalise();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnKeyUp(InputState state, KeyUpEventArgs args)
|
||||||
|
{
|
||||||
|
if (HasFocus)
|
||||||
|
{
|
||||||
|
finalise();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.OnKeyUp(state, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void finalise()
|
||||||
|
{
|
||||||
|
if (bindTarget != null)
|
||||||
|
{
|
||||||
|
store.Update(bindTarget.KeyBinding);
|
||||||
|
|
||||||
|
bindTarget.IsBinding = false;
|
||||||
|
Schedule(() =>
|
||||||
|
{
|
||||||
|
// schedule to ensure we don't instantly get focus back on next OnMouseClick (see AcceptFocus impl.)
|
||||||
|
bindTarget = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasFocus)
|
||||||
|
GetContainingInputManager().ChangeFocus(null);
|
||||||
|
|
||||||
|
pressAKey.FadeOut(300, Easing.OutQuint);
|
||||||
|
pressAKey.Padding = new MarginPadding { Bottom = -pressAKey.DrawHeight };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFocus(InputState state)
|
||||||
|
{
|
||||||
|
AutoSizeDuration = 500;
|
||||||
|
AutoSizeEasing = Easing.OutQuint;
|
||||||
|
|
||||||
|
pressAKey.FadeIn(300, Easing.OutQuint);
|
||||||
|
pressAKey.Padding = new MarginPadding();
|
||||||
|
|
||||||
|
updateBindTarget();
|
||||||
|
base.OnFocus(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFocusLost(InputState state)
|
||||||
|
{
|
||||||
|
finalise();
|
||||||
|
base.OnFocusLost(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBindTarget()
|
||||||
|
{
|
||||||
|
if (bindTarget != null) bindTarget.IsBinding = false;
|
||||||
|
bindTarget = buttons.FirstOrDefault(b => b.IsHovered) ?? buttons.FirstOrDefault();
|
||||||
|
if (bindTarget != null) bindTarget.IsBinding = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class KeyButton : Container
|
||||||
|
{
|
||||||
|
public readonly Framework.Input.Bindings.KeyBinding KeyBinding;
|
||||||
|
|
||||||
|
private readonly Box box;
|
||||||
|
public readonly OsuSpriteText Text;
|
||||||
|
|
||||||
|
private Color4 hoverColour;
|
||||||
|
|
||||||
|
private bool isBinding;
|
||||||
|
|
||||||
|
public bool IsBinding
|
||||||
|
{
|
||||||
|
get { return isBinding; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == isBinding) return;
|
||||||
|
isBinding = value;
|
||||||
|
|
||||||
|
updateHoverState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyButton(Framework.Input.Bindings.KeyBinding keyBinding)
|
||||||
|
{
|
||||||
|
KeyBinding = keyBinding;
|
||||||
|
|
||||||
|
Margin = new MarginPadding(padding);
|
||||||
|
|
||||||
|
// todo: use this in a meaningful way
|
||||||
|
// var isDefault = keyBinding.Action is Enum;
|
||||||
|
|
||||||
|
Masking = true;
|
||||||
|
CornerRadius = padding;
|
||||||
|
|
||||||
|
Height = height;
|
||||||
|
AutoSizeAxes = Axes.X;
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
AlwaysPresent = true,
|
||||||
|
Width = 80,
|
||||||
|
Height = height,
|
||||||
|
},
|
||||||
|
box = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Black
|
||||||
|
},
|
||||||
|
Text = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Font = "Venera",
|
||||||
|
TextSize = 10,
|
||||||
|
Margin = new MarginPadding(5),
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Text = keyBinding.KeyCombination.ReadableString(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
hoverColour = colours.YellowDark;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnHover(InputState state)
|
||||||
|
{
|
||||||
|
updateHoverState();
|
||||||
|
return base.OnHover(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(InputState state)
|
||||||
|
{
|
||||||
|
updateHoverState();
|
||||||
|
base.OnHoverLost(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateHoverState()
|
||||||
|
{
|
||||||
|
if (isBinding)
|
||||||
|
{
|
||||||
|
box.FadeColour(Color4.White, transition_time, Easing.OutQuint);
|
||||||
|
Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
box.FadeColour(IsHovered ? hoverColour : Color4.Black, transition_time, Easing.OutQuint);
|
||||||
|
Text.FadeColour(IsHovered ? Color4.Black : Color4.White, transition_time, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateKeyCombination(KeyCombination newCombination)
|
||||||
|
{
|
||||||
|
KeyBinding.KeyCombination = newCombination;
|
||||||
|
Text.Text = KeyBinding.KeyCombination.ReadableString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
49
osu.Game/Overlays/KeyBinding/KeyBindingsSection.cs
Normal file
49
osu.Game/Overlays/KeyBinding/KeyBindingsSection.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Input;
|
||||||
|
using osu.Game.Overlays.Settings;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using OpenTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.KeyBinding
|
||||||
|
{
|
||||||
|
public abstract class KeyBindingsSection : SettingsSection
|
||||||
|
{
|
||||||
|
protected IEnumerable<Framework.Input.Bindings.KeyBinding> Defaults;
|
||||||
|
|
||||||
|
protected RulesetInfo Ruleset;
|
||||||
|
|
||||||
|
protected KeyBindingsSection()
|
||||||
|
{
|
||||||
|
FlowContent.Spacing = new Vector2(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(KeyBindingStore store)
|
||||||
|
{
|
||||||
|
var enumType = Defaults?.FirstOrDefault()?.Action?.GetType();
|
||||||
|
|
||||||
|
if (enumType == null) return;
|
||||||
|
|
||||||
|
// for now let's just assume a variant of zero.
|
||||||
|
// this will need to be implemented in a better way in the future.
|
||||||
|
int? variant = null;
|
||||||
|
if (Ruleset != null)
|
||||||
|
variant = 0;
|
||||||
|
|
||||||
|
var bindings = store.Query(Ruleset?.ID, variant);
|
||||||
|
|
||||||
|
foreach (Enum v in Enum.GetValues(enumType))
|
||||||
|
// one row per valid action.
|
||||||
|
Add(new KeyBindingRow(v, bindings.Where(b => b.Action.Equals((int)(object)v)))
|
||||||
|
{
|
||||||
|
AllowMainMouseButtons = Ruleset != null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
osu.Game/Overlays/KeyBinding/RulesetBindingsSection.cs
Normal file
21
osu.Game/Overlays/KeyBinding/RulesetBindingsSection.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// 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.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.KeyBinding
|
||||||
|
{
|
||||||
|
public class RulesetBindingsSection : KeyBindingsSection
|
||||||
|
{
|
||||||
|
public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail;
|
||||||
|
public override string Header => Ruleset.Name;
|
||||||
|
|
||||||
|
public RulesetBindingsSection(RulesetInfo ruleset)
|
||||||
|
{
|
||||||
|
Ruleset = ruleset;
|
||||||
|
|
||||||
|
Defaults = ruleset.CreateInstance().GetDefaultKeyBindings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
osu.Game/Overlays/KeyBindingOverlay.cs
Normal file
31
osu.Game/Overlays/KeyBindingOverlay.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// 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.Input.Bindings;
|
||||||
|
using osu.Game.Overlays.KeyBinding;
|
||||||
|
using osu.Game.Overlays.Settings;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays
|
||||||
|
{
|
||||||
|
public class KeyBindingOverlay : SettingsOverlay
|
||||||
|
{
|
||||||
|
protected override Drawable CreateHeader() => new SettingsHeader("key configuration", "Customise your keys!");
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader(permitNulls: true)]
|
||||||
|
private void load(RulesetStore rulesets, GlobalKeyBindingInputManager global)
|
||||||
|
{
|
||||||
|
AddSection(new GlobalKeyBindingsSection(global, "Global"));
|
||||||
|
|
||||||
|
foreach (var ruleset in rulesets.Query<RulesetInfo>())
|
||||||
|
AddSection(new RulesetBindingsSection(ruleset));
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyBindingOverlay()
|
||||||
|
: base(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -69,7 +69,7 @@ namespace osu.Game.Overlays
|
|||||||
settingsSection.Bounding = true;
|
settingsSection.Bounding = true;
|
||||||
this.FadeIn(transition_time, Easing.OutQuint);
|
this.FadeIn(transition_time, Easing.OutQuint);
|
||||||
|
|
||||||
InputManager.ChangeFocus(settingsSection);
|
GetContainingInputManager().ChangeFocus(settingsSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopOut()
|
protected override void PopOut()
|
||||||
|
151
osu.Game/Overlays/MainSettings.cs
Normal file
151
osu.Game/Overlays/MainSettings.cs
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Overlays.Settings;
|
||||||
|
using osu.Game.Overlays.Settings.Sections;
|
||||||
|
using osu.Game.Screens.Ranking;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays
|
||||||
|
{
|
||||||
|
public class MainSettings : SettingsOverlay
|
||||||
|
{
|
||||||
|
private readonly KeyBindingOverlay keyBindingOverlay;
|
||||||
|
private BackButton backButton;
|
||||||
|
|
||||||
|
protected override IEnumerable<SettingsSection> CreateSections() => new SettingsSection[]
|
||||||
|
{
|
||||||
|
new GeneralSection(),
|
||||||
|
new GraphicsSection(),
|
||||||
|
new GameplaySection(),
|
||||||
|
new AudioSection(),
|
||||||
|
new SkinSection(),
|
||||||
|
new InputSection(keyBindingOverlay),
|
||||||
|
new OnlineSection(),
|
||||||
|
new MaintenanceSection(),
|
||||||
|
new DebugSection(),
|
||||||
|
};
|
||||||
|
|
||||||
|
protected override Drawable CreateHeader() => new SettingsHeader("settings", "Change the way osu! behaves");
|
||||||
|
protected override Drawable CreateFooter() => new SettingsFooter();
|
||||||
|
|
||||||
|
public MainSettings()
|
||||||
|
: base(true)
|
||||||
|
{
|
||||||
|
keyBindingOverlay = new KeyBindingOverlay
|
||||||
|
{
|
||||||
|
Depth = 1,
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
};
|
||||||
|
keyBindingOverlay.StateChanged += keyBindingOverlay_StateChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool AcceptsFocus => keyBindingOverlay.State != Visibility.Visible;
|
||||||
|
|
||||||
|
private const float hidden_width = 120;
|
||||||
|
|
||||||
|
private void keyBindingOverlay_StateChanged(VisibilityContainer container, Visibility visibility)
|
||||||
|
{
|
||||||
|
switch (visibility)
|
||||||
|
{
|
||||||
|
case Visibility.Visible:
|
||||||
|
Background.FadeTo(0.9f, 300, Easing.OutQuint);
|
||||||
|
Sidebar?.FadeColour(Color4.DarkGray, 300, Easing.OutQuint);
|
||||||
|
|
||||||
|
SectionsContainer.FadeOut(300, Easing.OutQuint);
|
||||||
|
ContentContainer.MoveToX(hidden_width - WIDTH, 500, Easing.OutQuint);
|
||||||
|
|
||||||
|
backButton.Delay(100).FadeIn(100);
|
||||||
|
break;
|
||||||
|
case Visibility.Hidden:
|
||||||
|
Background.FadeTo(0.6f, 500, Easing.OutQuint);
|
||||||
|
Sidebar?.FadeColour(Color4.White, 300, Easing.OutQuint);
|
||||||
|
|
||||||
|
SectionsContainer.FadeIn(500, Easing.OutQuint);
|
||||||
|
ContentContainer.MoveToX(0, 500, Easing.OutQuint);
|
||||||
|
|
||||||
|
backButton.FadeOut(100);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override float ExpandedPosition => keyBindingOverlay.State == Visibility.Visible ? hidden_width - WIDTH : base.ExpandedPosition;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
ContentContainer.Add(keyBindingOverlay);
|
||||||
|
|
||||||
|
ContentContainer.Add(backButton = new BackButton
|
||||||
|
{
|
||||||
|
Alpha = 0,
|
||||||
|
Width = hidden_width,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Anchor = Anchor.CentreRight,
|
||||||
|
Origin = Anchor.CentreRight,
|
||||||
|
Action = () => keyBindingOverlay.Hide()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BackButton : OsuClickableContainer
|
||||||
|
{
|
||||||
|
private AspectContainer aspect;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
aspect = new AspectContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new SpriteIcon
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Y = -15,
|
||||||
|
Size = new Vector2(15),
|
||||||
|
Shadow = true,
|
||||||
|
Icon = FontAwesome.fa_chevron_left
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Y = 15,
|
||||||
|
TextSize = 12,
|
||||||
|
Font = @"Exo2.0-Bold",
|
||||||
|
Text = @"back",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||||
|
{
|
||||||
|
aspect.ScaleTo(0.75f, 2000, Easing.OutQuint);
|
||||||
|
return base.OnMouseDown(state, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
||||||
|
{
|
||||||
|
aspect.ScaleTo(1, 1000, Easing.OutElastic);
|
||||||
|
return base.OnMouseUp(state, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,6 @@ using System.Linq;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Input;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
@ -31,12 +30,10 @@ namespace osu.Game.Overlays.Music
|
|||||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
||||||
|
|
||||||
public IEnumerable<BeatmapSetInfo> BeatmapSets;
|
public IEnumerable<BeatmapSetInfo> BeatmapSets;
|
||||||
private InputManager inputManager;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours, UserInputManager inputManager)
|
private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours)
|
||||||
{
|
{
|
||||||
this.inputManager = inputManager;
|
|
||||||
this.beatmaps = beatmaps;
|
this.beatmaps = beatmaps;
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
@ -102,7 +99,7 @@ namespace osu.Game.Overlays.Music
|
|||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
{
|
{
|
||||||
filter.Search.HoldFocus = true;
|
filter.Search.HoldFocus = true;
|
||||||
Schedule(() => inputManager.ChangeFocus(filter.Search));
|
Schedule(() => GetContainingInputManager().ChangeFocus(filter.Search));
|
||||||
|
|
||||||
this.ResizeTo(new Vector2(1, playlist_height), transition_duration, Easing.OutQuint);
|
this.ResizeTo(new Vector2(1, playlist_height), transition_duration, Easing.OutQuint);
|
||||||
this.FadeIn(transition_duration, Easing.OutQuint);
|
this.FadeIn(transition_duration, Easing.OutQuint);
|
||||||
|
@ -258,7 +258,10 @@ namespace osu.Game.Overlays
|
|||||||
Type = EdgeEffectType.Glow,
|
Type = EdgeEffectType.Glow,
|
||||||
Radius = 8,
|
Radius = 8,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
updateGlow();
|
updateGlow();
|
||||||
FinishTransforms(true);
|
FinishTransforms(true);
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ namespace osu.Game.Overlays.SearchableList
|
|||||||
|
|
||||||
protected override void OnFocus(InputState state)
|
protected override void OnFocus(InputState state)
|
||||||
{
|
{
|
||||||
InputManager.ChangeFocus(Filter.Search);
|
GetContainingInputManager().ChangeFocus(Filter.Search);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
|
@ -26,8 +26,11 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
|
|||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
audio.OnNewDevice -= onDeviceChanged;
|
if (audio != null)
|
||||||
audio.OnLostDevice -= onDeviceChanged;
|
{
|
||||||
|
audio.OnNewDevice -= onDeviceChanged;
|
||||||
|
audio.OnLostDevice -= onDeviceChanged;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateItems()
|
private void updateItems()
|
||||||
|
@ -57,12 +57,9 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
Spacing = new Vector2(0f, 5f);
|
Spacing = new Vector2(0f, 5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputManager inputManager;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader(permitNulls: true)]
|
[BackgroundDependencyLoader(permitNulls: true)]
|
||||||
private void load(OsuColour colours, APIAccess api, UserInputManager inputManager)
|
private void load(OsuColour colours, APIAccess api)
|
||||||
{
|
{
|
||||||
this.inputManager = inputManager;
|
|
||||||
this.colours = colours;
|
this.colours = colours;
|
||||||
|
|
||||||
api?.Register(this);
|
api?.Register(this);
|
||||||
@ -174,7 +171,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (form != null) inputManager.ChangeFocus(form);
|
if (form != null) GetContainingInputManager()?.ChangeFocus(form);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool AcceptsFocus => true;
|
public override bool AcceptsFocus => true;
|
||||||
@ -183,7 +180,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
|
|
||||||
protected override void OnFocus(InputState state)
|
protected override void OnFocus(InputState state)
|
||||||
{
|
{
|
||||||
if (form != null) inputManager.ChangeFocus(form);
|
if (form != null) GetContainingInputManager().ChangeFocus(form);
|
||||||
base.OnFocus(state);
|
base.OnFocus(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +189,6 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
private TextBox username;
|
private TextBox username;
|
||||||
private TextBox password;
|
private TextBox password;
|
||||||
private APIAccess api;
|
private APIAccess api;
|
||||||
private InputManager inputManager;
|
|
||||||
|
|
||||||
private void performLogin()
|
private void performLogin()
|
||||||
{
|
{
|
||||||
@ -201,9 +197,8 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(permitNulls: true)]
|
[BackgroundDependencyLoader(permitNulls: true)]
|
||||||
private void load(APIAccess api, OsuConfigManager config, UserInputManager inputManager)
|
private void load(APIAccess api, OsuConfigManager config)
|
||||||
{
|
{
|
||||||
this.inputManager = inputManager;
|
|
||||||
this.api = api;
|
this.api = api;
|
||||||
Direction = FillDirection.Vertical;
|
Direction = FillDirection.Vertical;
|
||||||
Spacing = new Vector2(0, 5);
|
Spacing = new Vector2(0, 5);
|
||||||
@ -256,7 +251,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
|
|
||||||
protected override void OnFocus(InputState state)
|
protected override void OnFocus(InputState state)
|
||||||
{
|
{
|
||||||
Schedule(() => { inputManager.ChangeFocus(string.IsNullOrEmpty(username.Text) ? username : password); });
|
Schedule(() => { GetContainingInputManager().ChangeFocus(string.IsNullOrEmpty(username.Text) ? username : password); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,14 +10,15 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
{
|
{
|
||||||
protected override string Header => "Keyboard";
|
protected override string Header => "Keyboard";
|
||||||
|
|
||||||
public KeyboardSettings()
|
public KeyboardSettings(KeyBindingOverlay keyConfig)
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new OsuButton
|
new OsuButton
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Text = "Key Configuration"
|
Text = "Key Configuration",
|
||||||
|
Action = () => keyConfig.ToggleVisibility()
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,12 @@ namespace osu.Game.Overlays.Settings.Sections
|
|||||||
public override string Header => "Input";
|
public override string Header => "Input";
|
||||||
public override FontAwesome Icon => FontAwesome.fa_keyboard_o;
|
public override FontAwesome Icon => FontAwesome.fa_keyboard_o;
|
||||||
|
|
||||||
public InputSection()
|
public InputSection(KeyBindingOverlay keyConfig)
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new MouseSettings(),
|
new MouseSettings(),
|
||||||
new KeyboardSettings(),
|
new KeyboardSettings(keyConfig),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,15 @@ namespace osu.Game.Overlays.Settings
|
|||||||
{
|
{
|
||||||
public class SettingsHeader : Container
|
public class SettingsHeader : Container
|
||||||
{
|
{
|
||||||
|
private readonly string heading;
|
||||||
|
private readonly string subheading;
|
||||||
|
|
||||||
|
public SettingsHeader(string heading, string subheading)
|
||||||
|
{
|
||||||
|
this.heading = heading;
|
||||||
|
this.subheading = subheading;
|
||||||
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
@ -28,7 +37,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
{
|
{
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = "settings",
|
Text = heading,
|
||||||
TextSize = 40,
|
TextSize = 40,
|
||||||
Margin = new MarginPadding
|
Margin = new MarginPadding
|
||||||
{
|
{
|
||||||
@ -39,7 +48,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Colour = colours.Pink,
|
Colour = colours.Pink,
|
||||||
Text = "Change the way osu! behaves",
|
Text = subheading,
|
||||||
TextSize = 18,
|
TextSize = 18,
|
||||||
Margin = new MarginPadding
|
Margin = new MarginPadding
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,6 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -25,25 +24,38 @@ namespace osu.Game.Overlays.Settings
|
|||||||
|
|
||||||
public IEnumerable<IFilterable> FilterableChildren => Children.OfType<IFilterable>();
|
public IEnumerable<IFilterable> FilterableChildren => Children.OfType<IFilterable>();
|
||||||
public string[] FilterTerms => new[] { Header };
|
public string[] FilterTerms => new[] { Header };
|
||||||
|
|
||||||
|
private const int header_size = 26;
|
||||||
|
private const int header_margin = 25;
|
||||||
|
private const int border_size = 2;
|
||||||
|
|
||||||
public bool MatchingFilter
|
public bool MatchingFilter
|
||||||
{
|
{
|
||||||
set
|
set { this.FadeTo(value ? 1 : 0); }
|
||||||
{
|
|
||||||
this.FadeTo(value ? 1 : 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly SpriteText headerLabel;
|
|
||||||
|
|
||||||
protected SettingsSection()
|
protected SettingsSection()
|
||||||
{
|
{
|
||||||
Margin = new MarginPadding { Top = 20 };
|
Margin = new MarginPadding { Top = 20 };
|
||||||
AutoSizeAxes = Axes.Y;
|
AutoSizeAxes = Axes.Y;
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
|
|
||||||
const int header_size = 26;
|
FlowContent = new FillFlowContainer
|
||||||
const int header_margin = 25;
|
{
|
||||||
const int border_size = 2;
|
Margin = new MarginPadding
|
||||||
|
{
|
||||||
|
Top = header_size + header_margin
|
||||||
|
},
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(0, 30),
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
AddRangeInternal(new Drawable[]
|
AddRangeInternal(new Drawable[]
|
||||||
{
|
{
|
||||||
new Box
|
new Box
|
||||||
@ -65,28 +77,16 @@ namespace osu.Game.Overlays.Settings
|
|||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
headerLabel = new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
TextSize = header_size,
|
TextSize = header_size,
|
||||||
Text = Header,
|
Text = Header,
|
||||||
|
Colour = colours.Yellow
|
||||||
},
|
},
|
||||||
FlowContent = new FillFlowContainer
|
FlowContent
|
||||||
{
|
|
||||||
Margin = new MarginPadding { Top = header_size + header_margin },
|
|
||||||
Direction = FillDirection.Vertical,
|
|
||||||
Spacing = new Vector2(0, 30),
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(OsuColour colours)
|
|
||||||
{
|
|
||||||
headerLabel.Colour = colours.Yellow;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,12 @@ using osu.Game.Overlays.Toolbar;
|
|||||||
|
|
||||||
namespace osu.Game.Overlays.Settings
|
namespace osu.Game.Overlays.Settings
|
||||||
{
|
{
|
||||||
public class Sidebar : Container, IStateful<ExpandedState>
|
public class Sidebar : Container<SidebarButton>, IStateful<ExpandedState>
|
||||||
{
|
{
|
||||||
private readonly FillFlowContainer content;
|
private readonly FillFlowContainer<SidebarButton> content;
|
||||||
internal const float DEFAULT_WIDTH = ToolbarButton.WIDTH;
|
internal const float DEFAULT_WIDTH = ToolbarButton.WIDTH;
|
||||||
internal const int EXPANDED_WIDTH = 200;
|
internal const int EXPANDED_WIDTH = 200;
|
||||||
protected override Container<Drawable> Content => content;
|
protected override Container<SidebarButton> Content => content;
|
||||||
|
|
||||||
public Sidebar()
|
public Sidebar()
|
||||||
{
|
{
|
||||||
@ -35,7 +35,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
{
|
{
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
content = new FillFlowContainer
|
content = new FillFlowContainer<SidebarButton>
|
||||||
{
|
{
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
@ -87,6 +87,8 @@ namespace osu.Game.Overlays.Settings
|
|||||||
get { return state; }
|
get { return state; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
expandEvent?.Cancel();
|
||||||
|
|
||||||
if (state == value) return;
|
if (state == value) return;
|
||||||
|
|
||||||
state = value;
|
state = value;
|
||||||
|
@ -2,9 +2,12 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
@ -12,11 +15,10 @@ using osu.Framework.Input;
|
|||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
using osu.Game.Overlays.Settings.Sections;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays
|
namespace osu.Game.Overlays
|
||||||
{
|
{
|
||||||
public class SettingsOverlay : OsuFocusedOverlayContainer
|
public abstract class SettingsOverlay : OsuFocusedOverlayContainer
|
||||||
{
|
{
|
||||||
internal const float CONTENT_MARGINS = 10;
|
internal const float CONTENT_MARGINS = 10;
|
||||||
|
|
||||||
@ -24,125 +26,152 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
public const float SIDEBAR_WIDTH = Sidebar.DEFAULT_WIDTH;
|
public const float SIDEBAR_WIDTH = Sidebar.DEFAULT_WIDTH;
|
||||||
|
|
||||||
private const float width = 400;
|
protected const float WIDTH = 400;
|
||||||
|
|
||||||
private const float sidebar_padding = 10;
|
private const float sidebar_padding = 10;
|
||||||
|
|
||||||
private Sidebar sidebar;
|
protected Container<Drawable> ContentContainer;
|
||||||
private SidebarButton[] sidebarButtons;
|
|
||||||
|
protected override Container<Drawable> Content => ContentContainer;
|
||||||
|
|
||||||
|
protected Sidebar Sidebar;
|
||||||
private SidebarButton selectedSidebarButton;
|
private SidebarButton selectedSidebarButton;
|
||||||
|
|
||||||
private SettingsSectionsContainer sectionsContainer;
|
protected SettingsSectionsContainer SectionsContainer;
|
||||||
|
|
||||||
private SearchTextBox searchTextBox;
|
private SearchTextBox searchTextBox;
|
||||||
|
|
||||||
private Func<float> getToolbarHeight;
|
/// <summary>
|
||||||
|
/// Provide a source for the toolbar height.
|
||||||
|
/// </summary>
|
||||||
|
public Func<float> GetToolbarHeight;
|
||||||
|
|
||||||
public SettingsOverlay()
|
private readonly bool showSidebar;
|
||||||
|
|
||||||
|
protected Box Background;
|
||||||
|
|
||||||
|
protected SettingsOverlay(bool showSidebar)
|
||||||
{
|
{
|
||||||
|
this.showSidebar = showSidebar;
|
||||||
RelativeSizeAxes = Axes.Y;
|
RelativeSizeAxes = Axes.Y;
|
||||||
AutoSizeAxes = Axes.X;
|
AutoSizeAxes = Axes.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(permitNulls: true)]
|
protected virtual IEnumerable<SettingsSection> CreateSections() => null;
|
||||||
private void load(OsuGame game)
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
{
|
{
|
||||||
var sections = new SettingsSection[]
|
InternalChild = ContentContainer = new Container
|
||||||
{
|
{
|
||||||
new GeneralSection(),
|
Width = WIDTH,
|
||||||
new GraphicsSection(),
|
RelativeSizeAxes = Axes.Y,
|
||||||
new GameplaySection(),
|
Children = new Drawable[]
|
||||||
new AudioSection(),
|
|
||||||
new SkinSection(),
|
|
||||||
new InputSection(),
|
|
||||||
new OnlineSection(),
|
|
||||||
new MaintenanceSection(),
|
|
||||||
new DebugSection(),
|
|
||||||
};
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
Background = new Box
|
||||||
Colour = Color4.Black,
|
|
||||||
Alpha = 0.6f,
|
|
||||||
},
|
|
||||||
sectionsContainer = new SettingsSectionsContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
|
||||||
Width = width,
|
|
||||||
Margin = new MarginPadding { Left = SIDEBAR_WIDTH },
|
|
||||||
ExpandableHeader = new SettingsHeader(),
|
|
||||||
FixedHeader = searchTextBox = new SearchTextBox
|
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
Anchor = Anchor.TopRight,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopRight,
|
||||||
Anchor = Anchor.TopCentre,
|
Scale = new Vector2(2, 1), // over-extend to the left for transitions
|
||||||
Width = 0.95f,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Margin = new MarginPadding
|
Colour = Color4.Black,
|
||||||
{
|
Alpha = 0.6f,
|
||||||
Top = 20,
|
|
||||||
Bottom = 20
|
|
||||||
},
|
|
||||||
Exit = Hide,
|
|
||||||
},
|
},
|
||||||
Children = sections,
|
SectionsContainer = new SettingsSectionsContainer
|
||||||
Footer = new SettingsFooter()
|
{
|
||||||
},
|
RelativeSizeAxes = Axes.Both,
|
||||||
sidebar = new Sidebar
|
ExpandableHeader = CreateHeader(),
|
||||||
{
|
FixedHeader = searchTextBox = new SearchTextBox
|
||||||
Width = SIDEBAR_WIDTH,
|
|
||||||
Children = sidebarButtons = sections.Select(section =>
|
|
||||||
new SidebarButton
|
|
||||||
{
|
{
|
||||||
Section = section,
|
RelativeSizeAxes = Axes.X,
|
||||||
Action = s =>
|
Origin = Anchor.TopCentre,
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Width = 0.95f,
|
||||||
|
Margin = new MarginPadding
|
||||||
{
|
{
|
||||||
sectionsContainer.ScrollTo(s);
|
Top = 20,
|
||||||
sidebar.State = ExpandedState.Contracted;
|
Bottom = 20
|
||||||
},
|
},
|
||||||
}
|
Exit = Hide,
|
||||||
).ToArray()
|
},
|
||||||
|
Footer = CreateFooter()
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
selectedSidebarButton = sidebarButtons[0];
|
if (showSidebar)
|
||||||
selectedSidebarButton.Selected = true;
|
|
||||||
|
|
||||||
sectionsContainer.SelectedSection.ValueChanged += section =>
|
|
||||||
{
|
{
|
||||||
selectedSidebarButton.Selected = false;
|
AddInternal(Sidebar = new Sidebar { Width = SIDEBAR_WIDTH });
|
||||||
selectedSidebarButton = sidebarButtons.Single(b => b.Section == section);
|
|
||||||
selectedSidebarButton.Selected = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
searchTextBox.Current.ValueChanged += newValue => sectionsContainer.SearchContainer.SearchTerm = newValue;
|
SectionsContainer.SelectedSection.ValueChanged += section =>
|
||||||
|
{
|
||||||
|
selectedSidebarButton.Selected = false;
|
||||||
|
selectedSidebarButton = Sidebar.Children.Single(b => b.Section == section);
|
||||||
|
selectedSidebarButton.Selected = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
getToolbarHeight = () => game?.ToolbarOffset ?? 0;
|
searchTextBox.Current.ValueChanged += newValue => SectionsContainer.SearchContainer.SearchTerm = newValue;
|
||||||
|
|
||||||
|
CreateSections()?.ForEach(AddSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void AddSection(SettingsSection section)
|
||||||
|
{
|
||||||
|
SectionsContainer.Add(section);
|
||||||
|
|
||||||
|
if (Sidebar != null)
|
||||||
|
{
|
||||||
|
var button = new SidebarButton
|
||||||
|
{
|
||||||
|
Section = section,
|
||||||
|
Action = s =>
|
||||||
|
{
|
||||||
|
SectionsContainer.ScrollTo(s);
|
||||||
|
Sidebar.State = ExpandedState.Contracted;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Sidebar.Add(button);
|
||||||
|
|
||||||
|
if (selectedSidebarButton == null)
|
||||||
|
{
|
||||||
|
selectedSidebarButton = Sidebar.Children.First();
|
||||||
|
selectedSidebarButton.Selected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual Drawable CreateHeader() => new Container();
|
||||||
|
|
||||||
|
protected virtual Drawable CreateFooter() => new Container();
|
||||||
|
|
||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
{
|
{
|
||||||
base.PopIn();
|
base.PopIn();
|
||||||
|
|
||||||
sectionsContainer.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint);
|
ContentContainer.MoveToX(ExpandedPosition, TRANSITION_LENGTH, Easing.OutQuint);
|
||||||
sidebar.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint);
|
|
||||||
this.FadeTo(1, TRANSITION_LENGTH / 2);
|
Sidebar?.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint);
|
||||||
|
this.FadeTo(1, TRANSITION_LENGTH, Easing.OutQuint);
|
||||||
|
|
||||||
searchTextBox.HoldFocus = true;
|
searchTextBox.HoldFocus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual float ExpandedPosition => 0;
|
||||||
|
|
||||||
protected override void PopOut()
|
protected override void PopOut()
|
||||||
{
|
{
|
||||||
base.PopOut();
|
base.PopOut();
|
||||||
|
|
||||||
sectionsContainer.MoveToX(-width, TRANSITION_LENGTH, Easing.OutQuint);
|
ContentContainer.MoveToX(-WIDTH, TRANSITION_LENGTH, Easing.OutQuint);
|
||||||
sidebar.MoveToX(-SIDEBAR_WIDTH, TRANSITION_LENGTH, Easing.OutQuint);
|
|
||||||
this.FadeTo(0, TRANSITION_LENGTH / 2);
|
Sidebar?.MoveToX(-SIDEBAR_WIDTH, TRANSITION_LENGTH, Easing.OutQuint);
|
||||||
|
this.FadeTo(0, TRANSITION_LENGTH, Easing.OutQuint);
|
||||||
|
|
||||||
searchTextBox.HoldFocus = false;
|
searchTextBox.HoldFocus = false;
|
||||||
if (searchTextBox.HasFocus)
|
if (searchTextBox.HasFocus)
|
||||||
InputManager.ChangeFocus(null);
|
GetContainingInputManager().ChangeFocus(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool AcceptsFocus => true;
|
public override bool AcceptsFocus => true;
|
||||||
@ -151,7 +180,7 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
protected override void OnFocus(InputState state)
|
protected override void OnFocus(InputState state)
|
||||||
{
|
{
|
||||||
InputManager.ChangeFocus(searchTextBox);
|
GetContainingInputManager().ChangeFocus(searchTextBox);
|
||||||
base.OnFocus(state);
|
base.OnFocus(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,11 +188,11 @@ namespace osu.Game.Overlays
|
|||||||
{
|
{
|
||||||
base.UpdateAfterChildren();
|
base.UpdateAfterChildren();
|
||||||
|
|
||||||
sectionsContainer.Margin = new MarginPadding { Left = sidebar.DrawWidth };
|
ContentContainer.Margin = new MarginPadding { Left = Sidebar?.DrawWidth ?? 0 };
|
||||||
sectionsContainer.Padding = new MarginPadding { Top = getToolbarHeight() };
|
ContentContainer.Padding = new MarginPadding { Top = GetToolbarHeight?.Invoke() ?? 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SettingsSectionsContainer : SectionsContainer<SettingsSection>
|
protected class SettingsSectionsContainer : SectionsContainer<SettingsSection>
|
||||||
{
|
{
|
||||||
public SearchContainer<SettingsSection> SearchContainer;
|
public SearchContainer<SettingsSection> SearchContainer;
|
||||||
|
|
||||||
|
@ -22,8 +22,6 @@ namespace osu.Game.Overlays.Toolbar
|
|||||||
|
|
||||||
private readonly ToolbarUserArea userArea;
|
private readonly ToolbarUserArea userArea;
|
||||||
|
|
||||||
protected override bool HideOnEscape => false;
|
|
||||||
|
|
||||||
protected override bool BlockPassThroughMouse => false;
|
protected override bool BlockPassThroughMouse => false;
|
||||||
|
|
||||||
private const double transition_time = 500;
|
private const double transition_time = 500;
|
||||||
@ -60,8 +58,8 @@ namespace osu.Game.Overlays.Toolbar
|
|||||||
AutoSizeAxes = Axes.X,
|
AutoSizeAxes = Axes.X,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new ToolbarSocialButton(),
|
|
||||||
new ToolbarChatButton(),
|
new ToolbarChatButton(),
|
||||||
|
new ToolbarSocialButton(),
|
||||||
new ToolbarMusicButton(),
|
new ToolbarMusicButton(),
|
||||||
new ToolbarButton
|
new ToolbarButton
|
||||||
{
|
{
|
||||||
|
@ -32,6 +32,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool RemoveWhenNotAlive => false;
|
||||||
|
|
||||||
protected DrawableScrollingHitObject(TObject hitObject)
|
protected DrawableScrollingHitObject(TObject hitObject)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
|
@ -19,147 +19,155 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
|||||||
{
|
{
|
||||||
public override HitObject Parse(string text)
|
public override HitObject Parse(string text)
|
||||||
{
|
{
|
||||||
string[] split = text.Split(',');
|
try
|
||||||
ConvertHitObjectType type = (ConvertHitObjectType)int.Parse(split[3]) & ~ConvertHitObjectType.ColourHax;
|
|
||||||
bool combo = type.HasFlag(ConvertHitObjectType.NewCombo);
|
|
||||||
type &= ~ConvertHitObjectType.NewCombo;
|
|
||||||
|
|
||||||
var soundType = (LegacySoundType)int.Parse(split[4]);
|
|
||||||
var bankInfo = new SampleBankInfo();
|
|
||||||
|
|
||||||
HitObject result = null;
|
|
||||||
|
|
||||||
if ((type & ConvertHitObjectType.Circle) > 0)
|
|
||||||
{
|
{
|
||||||
result = CreateHit(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo);
|
string[] split = text.Split(',');
|
||||||
|
|
||||||
if (split.Length > 5)
|
ConvertHitObjectType type = (ConvertHitObjectType)int.Parse(split[3]) & ~ConvertHitObjectType.ColourHax;
|
||||||
readCustomSampleBanks(split[5], bankInfo);
|
bool combo = type.HasFlag(ConvertHitObjectType.NewCombo);
|
||||||
}
|
type &= ~ConvertHitObjectType.NewCombo;
|
||||||
else if ((type & ConvertHitObjectType.Slider) > 0)
|
|
||||||
{
|
|
||||||
CurveType curveType = CurveType.Catmull;
|
|
||||||
double length = 0;
|
|
||||||
var points = new List<Vector2> { new Vector2(int.Parse(split[0]), int.Parse(split[1])) };
|
|
||||||
|
|
||||||
string[] pointsplit = split[5].Split('|');
|
var soundType = (LegacySoundType)int.Parse(split[4]);
|
||||||
foreach (string t in pointsplit)
|
var bankInfo = new SampleBankInfo();
|
||||||
|
|
||||||
|
HitObject result = null;
|
||||||
|
|
||||||
|
if ((type & ConvertHitObjectType.Circle) > 0)
|
||||||
{
|
{
|
||||||
if (t.Length == 1)
|
result = CreateHit(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo);
|
||||||
|
|
||||||
|
if (split.Length > 5)
|
||||||
|
readCustomSampleBanks(split[5], bankInfo);
|
||||||
|
}
|
||||||
|
else if ((type & ConvertHitObjectType.Slider) > 0)
|
||||||
|
{
|
||||||
|
CurveType curveType = CurveType.Catmull;
|
||||||
|
double length = 0;
|
||||||
|
var points = new List<Vector2> { new Vector2(int.Parse(split[0]), int.Parse(split[1])) };
|
||||||
|
|
||||||
|
string[] pointsplit = split[5].Split('|');
|
||||||
|
foreach (string t in pointsplit)
|
||||||
{
|
{
|
||||||
switch (t)
|
if (t.Length == 1)
|
||||||
{
|
{
|
||||||
case @"C":
|
switch (t)
|
||||||
curveType = CurveType.Catmull;
|
{
|
||||||
break;
|
case @"C":
|
||||||
case @"B":
|
curveType = CurveType.Catmull;
|
||||||
curveType = CurveType.Bezier;
|
break;
|
||||||
break;
|
case @"B":
|
||||||
case @"L":
|
curveType = CurveType.Bezier;
|
||||||
curveType = CurveType.Linear;
|
break;
|
||||||
break;
|
case @"L":
|
||||||
case @"P":
|
curveType = CurveType.Linear;
|
||||||
curveType = CurveType.PerfectCurve;
|
break;
|
||||||
break;
|
case @"P":
|
||||||
|
curveType = CurveType.PerfectCurve;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
|
string[] temp = t.Split(':');
|
||||||
|
points.Add(new Vector2((int)Convert.ToDouble(temp[0], CultureInfo.InvariantCulture), (int)Convert.ToDouble(temp[1], CultureInfo.InvariantCulture)));
|
||||||
}
|
}
|
||||||
|
|
||||||
string[] temp = t.Split(':');
|
int repeatCount = Convert.ToInt32(split[6], CultureInfo.InvariantCulture);
|
||||||
points.Add(new Vector2((int)Convert.ToDouble(temp[0], CultureInfo.InvariantCulture), (int)Convert.ToDouble(temp[1], CultureInfo.InvariantCulture)));
|
|
||||||
}
|
|
||||||
|
|
||||||
int repeatCount = Convert.ToInt32(split[6], CultureInfo.InvariantCulture);
|
if (repeatCount > 9000)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(repeatCount), @"Repeat count is way too high");
|
||||||
|
|
||||||
if (repeatCount > 9000)
|
if (split.Length > 7)
|
||||||
throw new ArgumentOutOfRangeException(nameof(repeatCount), @"Repeat count is way too high");
|
length = Convert.ToDouble(split[7], CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
if (split.Length > 7)
|
if (split.Length > 10)
|
||||||
length = Convert.ToDouble(split[7], CultureInfo.InvariantCulture);
|
readCustomSampleBanks(split[10], bankInfo);
|
||||||
|
|
||||||
if (split.Length > 10)
|
// One node for each repeat + the start and end nodes
|
||||||
readCustomSampleBanks(split[10], bankInfo);
|
// Note that the first length of the slider is considered a repeat, but there are no actual repeats happening
|
||||||
|
int nodes = Math.Max(0, repeatCount - 1) + 2;
|
||||||
|
|
||||||
// One node for each repeat + the start and end nodes
|
// Populate node sample bank infos with the default hit object sample bank
|
||||||
// Note that the first length of the slider is considered a repeat, but there are no actual repeats happening
|
var nodeBankInfos = new List<SampleBankInfo>();
|
||||||
int nodes = Math.Max(0, repeatCount - 1) + 2;
|
|
||||||
|
|
||||||
// Populate node sample bank infos with the default hit object sample bank
|
|
||||||
var nodeBankInfos = new List<SampleBankInfo>();
|
|
||||||
for (int i = 0; i < nodes; i++)
|
|
||||||
nodeBankInfos.Add(bankInfo.Clone());
|
|
||||||
|
|
||||||
// Read any per-node sample banks
|
|
||||||
if (split.Length > 9 && split[9].Length > 0)
|
|
||||||
{
|
|
||||||
string[] sets = split[9].Split('|');
|
|
||||||
for (int i = 0; i < nodes; i++)
|
for (int i = 0; i < nodes; i++)
|
||||||
|
nodeBankInfos.Add(bankInfo.Clone());
|
||||||
|
|
||||||
|
// Read any per-node sample banks
|
||||||
|
if (split.Length > 9 && split[9].Length > 0)
|
||||||
{
|
{
|
||||||
if (i >= sets.Length)
|
string[] sets = split[9].Split('|');
|
||||||
break;
|
for (int i = 0; i < nodes; i++)
|
||||||
|
{
|
||||||
|
if (i >= sets.Length)
|
||||||
|
break;
|
||||||
|
|
||||||
SampleBankInfo info = nodeBankInfos[i];
|
SampleBankInfo info = nodeBankInfos[i];
|
||||||
readCustomSampleBanks(sets[i], info);
|
readCustomSampleBanks(sets[i], info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Populate node sound types with the default hit object sound type
|
// Populate node sound types with the default hit object sound type
|
||||||
var nodeSoundTypes = new List<LegacySoundType>();
|
var nodeSoundTypes = new List<LegacySoundType>();
|
||||||
for (int i = 0; i < nodes; i++)
|
|
||||||
nodeSoundTypes.Add(soundType);
|
|
||||||
|
|
||||||
// Read any per-node sound types
|
|
||||||
if (split.Length > 8 && split[8].Length > 0)
|
|
||||||
{
|
|
||||||
string[] adds = split[8].Split('|');
|
|
||||||
for (int i = 0; i < nodes; i++)
|
for (int i = 0; i < nodes; i++)
|
||||||
|
nodeSoundTypes.Add(soundType);
|
||||||
|
|
||||||
|
// Read any per-node sound types
|
||||||
|
if (split.Length > 8 && split[8].Length > 0)
|
||||||
{
|
{
|
||||||
if (i >= adds.Length)
|
string[] adds = split[8].Split('|');
|
||||||
break;
|
for (int i = 0; i < nodes; i++)
|
||||||
|
{
|
||||||
|
if (i >= adds.Length)
|
||||||
|
break;
|
||||||
|
|
||||||
int sound;
|
int sound;
|
||||||
int.TryParse(adds[i], out sound);
|
int.TryParse(adds[i], out sound);
|
||||||
nodeSoundTypes[i] = (LegacySoundType)sound;
|
nodeSoundTypes[i] = (LegacySoundType)sound;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate the final per-node samples
|
||||||
|
var nodeSamples = new List<SampleInfoList>(nodes);
|
||||||
|
for (int i = 0; i <= repeatCount; i++)
|
||||||
|
nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i]));
|
||||||
|
|
||||||
|
result = CreateSlider(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo, points, length, curveType, repeatCount, nodeSamples);
|
||||||
}
|
}
|
||||||
|
else if ((type & ConvertHitObjectType.Spinner) > 0)
|
||||||
// Generate the final per-node samples
|
|
||||||
var nodeSamples = new List<SampleInfoList>(nodes);
|
|
||||||
for (int i = 0; i <= repeatCount; i++)
|
|
||||||
nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i]));
|
|
||||||
|
|
||||||
result = CreateSlider(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo, points, length, curveType, repeatCount, nodeSamples);
|
|
||||||
}
|
|
||||||
else if ((type & ConvertHitObjectType.Spinner) > 0)
|
|
||||||
{
|
|
||||||
result = CreateSpinner(new Vector2(512, 384) / 2, Convert.ToDouble(split[5], CultureInfo.InvariantCulture));
|
|
||||||
|
|
||||||
if (split.Length > 6)
|
|
||||||
readCustomSampleBanks(split[6], bankInfo);
|
|
||||||
}
|
|
||||||
else if ((type & ConvertHitObjectType.Hold) > 0)
|
|
||||||
{
|
|
||||||
// Note: Hold is generated by BMS converts
|
|
||||||
|
|
||||||
double endTime = Convert.ToDouble(split[2], CultureInfo.InvariantCulture);
|
|
||||||
|
|
||||||
if (split.Length > 5 && !string.IsNullOrEmpty(split[5]))
|
|
||||||
{
|
{
|
||||||
string[] ss = split[5].Split(':');
|
result = CreateSpinner(new Vector2(512, 384) / 2, Convert.ToDouble(split[5], CultureInfo.InvariantCulture));
|
||||||
endTime = Convert.ToDouble(ss[0], CultureInfo.InvariantCulture);
|
|
||||||
readCustomSampleBanks(string.Join(":", ss.Skip(1)), bankInfo);
|
if (split.Length > 6)
|
||||||
|
readCustomSampleBanks(split[6], bankInfo);
|
||||||
|
}
|
||||||
|
else if ((type & ConvertHitObjectType.Hold) > 0)
|
||||||
|
{
|
||||||
|
// Note: Hold is generated by BMS converts
|
||||||
|
|
||||||
|
double endTime = Convert.ToDouble(split[2], CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
|
if (split.Length > 5 && !string.IsNullOrEmpty(split[5]))
|
||||||
|
{
|
||||||
|
string[] ss = split[5].Split(':');
|
||||||
|
endTime = Convert.ToDouble(ss[0], CultureInfo.InvariantCulture);
|
||||||
|
readCustomSampleBanks(string.Join(":", ss.Skip(1)), bankInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = CreateHold(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo, endTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = CreateHold(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo, endTime);
|
if (result == null)
|
||||||
|
throw new InvalidOperationException($@"Unknown hit object type {type}.");
|
||||||
|
|
||||||
|
result.StartTime = Convert.ToDouble(split[2], CultureInfo.InvariantCulture);
|
||||||
|
result.Samples = convertSoundType(soundType, bankInfo);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
throw new FormatException("One or more hit objects were malformed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == null)
|
|
||||||
throw new InvalidOperationException($@"Unknown hit object type {type}.");
|
|
||||||
|
|
||||||
result.StartTime = Convert.ToDouble(split[2], CultureInfo.InvariantCulture);
|
|
||||||
result.Samples = convertSoundType(soundType, bankInfo);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readCustomSampleBanks(string str, SampleBankInfo bankInfo)
|
private void readCustomSampleBanks(string str, SampleBankInfo bankInfo)
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
@ -64,5 +65,17 @@ namespace osu.Game.Rulesets
|
|||||||
/// Do not override this unless you are a legacy mode.
|
/// Do not override this unless you are a legacy mode.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual int LegacyID => -1;
|
public virtual int LegacyID => -1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of available variant ids.
|
||||||
|
/// </summary>
|
||||||
|
public virtual IEnumerable<int> AvailableVariants => new[] { 0 };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a list of default keys for the specified variant.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variant">A variant.</param>
|
||||||
|
/// <returns>A list of valid <see cref="KeyBinding"/>s.</returns>
|
||||||
|
public virtual IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new KeyBinding[] { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ using SQLite.Net.Attributes;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets
|
namespace osu.Game.Rulesets
|
||||||
{
|
{
|
||||||
public class RulesetInfo
|
public class RulesetInfo : IEquatable<RulesetInfo>
|
||||||
{
|
{
|
||||||
[PrimaryKey, AutoIncrement]
|
[PrimaryKey, AutoIncrement]
|
||||||
public int? ID { get; set; }
|
public int? ID { get; set; }
|
||||||
@ -21,5 +21,7 @@ namespace osu.Game.Rulesets
|
|||||||
public bool Available { get; set; }
|
public bool Available { get; set; }
|
||||||
|
|
||||||
public virtual Ruleset CreateInstance() => (Ruleset)Activator.CreateInstance(Type.GetType(InstantiationInfo), this);
|
public virtual Ruleset CreateInstance() => (Ruleset)Activator.CreateInstance(Type.GetType(InstantiationInfo), this);
|
||||||
|
|
||||||
|
public bool Equals(RulesetInfo other) => other != null && ID == other.ID && Available == other.Available && Name == other.Name && InstantiationInfo == other.InstantiationInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,8 @@ namespace osu.Game.Rulesets.Timing
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal Axes ScrollingAxes;
|
internal Axes ScrollingAxes;
|
||||||
|
|
||||||
|
public override bool RemoveWhenNotAlive => false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The control point that defines the speed adjustments for this container. This is set by the <see cref="SpeedAdjustmentContainer"/>.
|
/// The control point that defines the speed adjustments for this container. This is set by the <see cref="SpeedAdjustmentContainer"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -34,6 +34,8 @@ namespace osu.Game.Rulesets.Timing
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Axes ScrollingAxes { get; internal set; }
|
public Axes ScrollingAxes { get; internal set; }
|
||||||
|
|
||||||
|
public override bool RemoveWhenNotAlive => false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="MultiplierControlPoint"/> that defines the speed adjustments.
|
/// The <see cref="MultiplierControlPoint"/> that defines the speed adjustments.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
internal RulesetContainer(Ruleset ruleset)
|
internal RulesetContainer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
Ruleset = ruleset;
|
Ruleset = ruleset;
|
||||||
KeyConversionInputManager = CreateActionMappingInputManager();
|
KeyConversionInputManager = CreateKeyBindingInputManager();
|
||||||
KeyConversionInputManager.RelativeSizeAxes = Axes.Both;
|
KeyConversionInputManager.RelativeSizeAxes = Axes.Both;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// Creates a key conversion input manager.
|
/// Creates a key conversion input manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The input manager.</returns>
|
/// <returns>The input manager.</returns>
|
||||||
protected virtual PassThroughInputManager CreateActionMappingInputManager() => new PassThroughInputManager();
|
public virtual PassThroughInputManager CreateKeyBindingInputManager() => new PassThroughInputManager();
|
||||||
|
|
||||||
protected virtual FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new FramedReplayInputHandler(replay);
|
protected virtual FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new FramedReplayInputHandler(replay);
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
|||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Transforms;
|
using osu.Framework.Graphics.Transforms;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
@ -154,7 +155,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// Hit objects that are to be re-processed on the next update.
|
/// Hit objects that are to be re-processed on the next update.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly List<DrawableHitObject> queuedHitObjects = new List<DrawableHitObject>();
|
private readonly List<DrawableHitObject> queuedHitObjects = new List<DrawableHitObject>();
|
||||||
private readonly List<SpeedAdjustmentContainer> speedAdjustments = new List<SpeedAdjustmentContainer>();
|
private readonly Container<SpeedAdjustmentContainer> speedAdjustments;
|
||||||
|
|
||||||
private readonly Axes scrollingAxes;
|
private readonly Axes scrollingAxes;
|
||||||
|
|
||||||
@ -165,6 +166,8 @@ namespace osu.Game.Rulesets.UI
|
|||||||
public ScrollingHitObjectContainer(Axes scrollingAxes)
|
public ScrollingHitObjectContainer(Axes scrollingAxes)
|
||||||
{
|
{
|
||||||
this.scrollingAxes = scrollingAxes;
|
this.scrollingAxes = scrollingAxes;
|
||||||
|
|
||||||
|
AddInternal(speedAdjustments = new Container<SpeedAdjustmentContainer> { RelativeSizeAxes = Axes.Both });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -176,9 +179,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
speedAdjustment.ScrollingAxes = scrollingAxes;
|
speedAdjustment.ScrollingAxes = scrollingAxes;
|
||||||
speedAdjustment.VisibleTimeRange.BindTo(VisibleTimeRange);
|
speedAdjustment.VisibleTimeRange.BindTo(VisibleTimeRange);
|
||||||
speedAdjustment.Reversed.BindTo(Reversed);
|
speedAdjustment.Reversed.BindTo(Reversed);
|
||||||
|
|
||||||
speedAdjustments.Add(speedAdjustment);
|
speedAdjustments.Add(speedAdjustment);
|
||||||
AddInternal(speedAdjustment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<DrawableHitObject> Objects => speedAdjustments.SelectMany(s => s.Children);
|
public override IEnumerable<DrawableHitObject> Objects => speedAdjustments.SelectMany(s => s.Children);
|
||||||
@ -210,11 +211,11 @@ namespace osu.Game.Rulesets.UI
|
|||||||
var hitObject = queuedHitObjects[i];
|
var hitObject = queuedHitObjects[i];
|
||||||
|
|
||||||
var target = adjustmentContainerFor(hitObject);
|
var target = adjustmentContainerFor(hitObject);
|
||||||
if (target != null)
|
if (target == null)
|
||||||
{
|
continue;
|
||||||
target.Add(hitObject);
|
|
||||||
queuedHitObjects.RemoveAt(i);
|
target.Add(hitObject);
|
||||||
}
|
queuedHitObjects.RemoveAt(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Screens
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the in-progress loading is complete before pushing the screen.
|
// Make sure the in-progress loading is complete before pushing the screen.
|
||||||
while (screen.LoadState < LoadState.Loaded)
|
while (screen.LoadState < LoadState.Ready)
|
||||||
Thread.Sleep(1);
|
Thread.Sleep(1);
|
||||||
|
|
||||||
base.Push(screen);
|
base.Push(screen);
|
||||||
|
@ -108,7 +108,7 @@ namespace osu.Game.Screens.Play
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool HandleInput => receptor?.IsAlive != true;
|
public override bool HandleInput => receptor == null;
|
||||||
|
|
||||||
private Receptor receptor;
|
private Receptor receptor;
|
||||||
|
|
||||||
|
@ -22,8 +22,6 @@ namespace osu.Game.Screens.Play
|
|||||||
private const int button_height = 70;
|
private const int button_height = 70;
|
||||||
private const float background_alpha = 0.75f;
|
private const float background_alpha = 0.75f;
|
||||||
|
|
||||||
protected override bool HideOnEscape => false;
|
|
||||||
|
|
||||||
protected override bool BlockPassThroughKeyboard => true;
|
protected override bool BlockPassThroughKeyboard => true;
|
||||||
|
|
||||||
public Action OnRetry;
|
public Action OnRetry;
|
||||||
@ -95,7 +93,8 @@ namespace osu.Game.Screens.Play
|
|||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Height = button_height,
|
Height = button_height,
|
||||||
Action = delegate {
|
Action = delegate
|
||||||
|
{
|
||||||
action?.Invoke();
|
action?.Invoke();
|
||||||
Hide();
|
Hide();
|
||||||
}
|
}
|
||||||
|
@ -227,9 +227,9 @@ namespace osu.Game.Screens.Play
|
|||||||
Direction = FillDirection.Horizontal,
|
Direction = FillDirection.Horizontal,
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
new SpriteIcon { Icon = FontAwesome.fa_chevron_right },
|
new SpriteIcon { Size = new Vector2(15), Shadow = true, Icon = FontAwesome.fa_chevron_right },
|
||||||
new SpriteIcon { Icon = FontAwesome.fa_chevron_right },
|
new SpriteIcon { Size = new Vector2(15), Shadow = true, Icon = FontAwesome.fa_chevron_right },
|
||||||
new SpriteIcon { Icon = FontAwesome.fa_chevron_right },
|
new SpriteIcon { Size = new Vector2(15), Shadow = true, Icon = FontAwesome.fa_chevron_right },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
|
@ -18,8 +18,6 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
private const int bottom_bar_height = 5;
|
private const int bottom_bar_height = 5;
|
||||||
|
|
||||||
protected override bool HideOnEscape => false;
|
|
||||||
|
|
||||||
private static readonly Vector2 handle_size = new Vector2(14, 25);
|
private static readonly Vector2 handle_size = new Vector2(14, 25);
|
||||||
|
|
||||||
private const float transition_duration = 200;
|
private const float transition_duration = 200;
|
||||||
|
@ -50,8 +50,6 @@ namespace osu.Game.Screens.Select
|
|||||||
AlwaysPresent = true;
|
AlwaysPresent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool HideOnEscape => false;
|
|
||||||
|
|
||||||
protected override bool BlockPassThroughMouse => false;
|
protected override bool BlockPassThroughMouse => false;
|
||||||
|
|
||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
|
@ -153,7 +153,7 @@ namespace osu.Game.Screens.Select
|
|||||||
{
|
{
|
||||||
searchTextBox.HoldFocus = false;
|
searchTextBox.HoldFocus = false;
|
||||||
if (searchTextBox.HasFocus)
|
if (searchTextBox.HasFocus)
|
||||||
inputManager.ChangeFocus(searchTextBox);
|
GetContainingInputManager().ChangeFocus(searchTextBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Activate()
|
public void Activate()
|
||||||
@ -163,13 +163,9 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||||
|
|
||||||
private InputManager inputManager;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader(permitNulls: true)]
|
[BackgroundDependencyLoader(permitNulls: true)]
|
||||||
private void load(OsuColour colours, OsuGame osu, UserInputManager inputManager)
|
private void load(OsuColour colours, OsuGame osu)
|
||||||
{
|
{
|
||||||
this.inputManager = inputManager;
|
|
||||||
|
|
||||||
sortTabs.AccentColour = colours.GreenLight;
|
sortTabs.AccentColour = colours.GreenLight;
|
||||||
|
|
||||||
if (osu != null)
|
if (osu != null)
|
||||||
|
@ -345,6 +345,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
Icon = FontAwesome.fa_square,
|
Icon = FontAwesome.fa_square,
|
||||||
Colour = OsuColour.FromHex(@"3087ac"),
|
Colour = OsuColour.FromHex(@"3087ac"),
|
||||||
Rotation = 45,
|
Rotation = 45,
|
||||||
|
Size = new Vector2(20),
|
||||||
Shadow = true,
|
Shadow = true,
|
||||||
},
|
},
|
||||||
new SpriteIcon
|
new SpriteIcon
|
||||||
@ -352,7 +353,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Icon = icon,
|
Icon = icon,
|
||||||
Colour = OsuColour.FromHex(@"a4edff"),
|
Colour = OsuColour.FromHex(@"a4edff"),
|
||||||
Scale = new Vector2(0.8f),
|
Size = new Vector2(14),
|
||||||
},
|
},
|
||||||
new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
|
new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
|
||||||
{
|
{
|
||||||
|
@ -156,11 +156,11 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(permitNulls: true)]
|
[BackgroundDependencyLoader(permitNulls: true)]
|
||||||
private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours, UserInputManager input)
|
private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours)
|
||||||
{
|
{
|
||||||
if (Footer != null)
|
if (Footer != null)
|
||||||
{
|
{
|
||||||
Footer.AddButton(@"random", colours.Green, () => triggerRandom(input), Key.F2);
|
Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2);
|
||||||
Footer.AddButton(@"options", colours.Blue, BeatmapOptions.ToggleVisibility, Key.F3);
|
Footer.AddButton(@"options", colours.Blue, BeatmapOptions.ToggleVisibility, Key.F3);
|
||||||
|
|
||||||
BeatmapOptions.AddButton(@"Delete", @"Beatmap", FontAwesome.fa_trash, colours.Pink, promptDelete, Key.Number4, float.MaxValue);
|
BeatmapOptions.AddButton(@"Delete", @"Beatmap", FontAwesome.fa_trash, colours.Pink, promptDelete, Key.Number4, float.MaxValue);
|
||||||
@ -253,8 +253,6 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Ruleset.Value = beatmap.Ruleset;
|
|
||||||
|
|
||||||
if (beatmap.BeatmapSetInfoID == beatmapNoDebounce?.BeatmapSetInfoID)
|
if (beatmap.BeatmapSetInfoID == beatmapNoDebounce?.BeatmapSetInfoID)
|
||||||
sampleChangeDifficulty.Play();
|
sampleChangeDifficulty.Play();
|
||||||
else
|
else
|
||||||
@ -267,9 +265,9 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void triggerRandom(UserInputManager input)
|
private void triggerRandom()
|
||||||
{
|
{
|
||||||
if (input.CurrentState.Keyboard.ShiftPressed)
|
if (GetContainingInputManager().CurrentState.Keyboard.ShiftPressed)
|
||||||
carousel.SelectPreviousRandom();
|
carousel.SelectPreviousRandom();
|
||||||
else
|
else
|
||||||
carousel.SelectNextRandom();
|
carousel.SelectNextRandom();
|
||||||
@ -372,6 +370,9 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
if (!track.IsRunning)
|
if (!track.IsRunning)
|
||||||
{
|
{
|
||||||
|
// Ensure the track is added to the TrackManager, since it is removed after the player finishes the map.
|
||||||
|
// Using AddItemToList rather than AddItem so that it doesn't attempt to register adjustment dependencies more than once.
|
||||||
|
Game.Audio.Track.AddItemToList(track);
|
||||||
if (preview) track.Seek(Beatmap.Value.Metadata.PreviewTime);
|
if (preview) track.Seek(Beatmap.Value.Metadata.PreviewTime);
|
||||||
track.Start();
|
track.Start();
|
||||||
}
|
}
|
||||||
|
@ -94,14 +94,20 @@
|
|||||||
<Compile Include="Graphics\UserInterface\OsuContextMenuItem.cs" />
|
<Compile Include="Graphics\UserInterface\OsuContextMenuItem.cs" />
|
||||||
<Compile Include="Input\Bindings\DatabasedKeyBinding.cs" />
|
<Compile Include="Input\Bindings\DatabasedKeyBinding.cs" />
|
||||||
<Compile Include="Input\Bindings\DatabasedKeyBindingInputManager.cs" />
|
<Compile Include="Input\Bindings\DatabasedKeyBindingInputManager.cs" />
|
||||||
<Compile Include="Input\BindingStore.cs" />
|
<Compile Include="Input\KeyBindingStore.cs" />
|
||||||
<Compile Include="Input\Bindings\GlobalBindingInputManager.cs" />
|
<Compile Include="Input\Bindings\GlobalKeyBindingInputManager.cs" />
|
||||||
<Compile Include="IO\FileStore.cs" />
|
<Compile Include="IO\FileStore.cs" />
|
||||||
<Compile Include="IO\FileInfo.cs" />
|
<Compile Include="IO\FileInfo.cs" />
|
||||||
<Compile Include="Online\API\Requests\GetUsersRequest.cs" />
|
<Compile Include="Online\API\Requests\GetUsersRequest.cs" />
|
||||||
<Compile Include="Online\API\Requests\PostMessageRequest.cs" />
|
<Compile Include="Online\API\Requests\PostMessageRequest.cs" />
|
||||||
<Compile Include="Online\Chat\ErrorMessage.cs" />
|
<Compile Include="Online\Chat\ErrorMessage.cs" />
|
||||||
<Compile Include="Overlays\Chat\ChatTabControl.cs" />
|
<Compile Include="Overlays\Chat\ChatTabControl.cs" />
|
||||||
|
<Compile Include="Overlays\KeyBinding\GlobalKeyBindingsSection.cs" />
|
||||||
|
<Compile Include="Overlays\KeyBinding\KeyBindingRow.cs" />
|
||||||
|
<Compile Include="Overlays\KeyBinding\KeyBindingsSection.cs" />
|
||||||
|
<Compile Include="Overlays\KeyBindingOverlay.cs" />
|
||||||
|
<Compile Include="Overlays\KeyBinding\RulesetBindingsSection.cs" />
|
||||||
|
<Compile Include="Overlays\MainSettings.cs" />
|
||||||
<Compile Include="Overlays\Music\CollectionsDropdown.cs" />
|
<Compile Include="Overlays\Music\CollectionsDropdown.cs" />
|
||||||
<Compile Include="Overlays\Music\FilterControl.cs" />
|
<Compile Include="Overlays\Music\FilterControl.cs" />
|
||||||
<Compile Include="Overlays\Music\PlaylistItem.cs" />
|
<Compile Include="Overlays\Music\PlaylistItem.cs" />
|
||||||
|
Reference in New Issue
Block a user