mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 03:22:55 +08:00
Merge pull request #1112 from peppy/key-config-settings
Key configuration
This commit is contained in:
commit
99c54e348c
@ -1 +1 @@
|
||||
Subproject commit 2a56eb0619adf654ed4927af1a4b227596c87494
|
||||
Subproject commit acb9bfb084b5607ff31c6269cb7942fa02624b75
|
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();
|
||||
}
|
||||
}
|
||||
}
|
@ -68,7 +68,7 @@ namespace osu.Desktop.Tests.Visual
|
||||
|
||||
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)
|
||||
break;
|
||||
|
||||
|
@ -13,7 +13,7 @@ namespace osu.Desktop.Tests.Visual
|
||||
|
||||
public TestCaseSettings()
|
||||
{
|
||||
Children = new[] { settings = new SettingsOverlay() };
|
||||
Children = new[] { settings = new MainSettings() };
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
@ -81,6 +81,7 @@
|
||||
<Compile Include="Visual\TestCaseGamefield.cs" />
|
||||
<Compile Include="Visual\TestCaseGraph.cs" />
|
||||
<Compile Include="Visual\TestCaseHitObjects.cs" />
|
||||
<Compile Include="Visual\TestCaseKeyConfiguration.cs" />
|
||||
<Compile Include="Visual\TestCaseKeyCounter.cs" />
|
||||
<Compile Include="Visual\TestCaseLeaderboard.cs" />
|
||||
<Compile Include="Visual\TestCaseManiaHitObjects.cs" />
|
||||
|
@ -1,11 +1,9 @@
|
||||
// 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 osu.Framework.Input.Bindings;
|
||||
using osu.Game.Input.Bindings;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch
|
||||
{
|
||||
@ -15,16 +13,6 @@ namespace osu.Game.Rulesets.Catch
|
||||
: base(ruleset, simultaneousMode: 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
|
||||
|
@ -13,6 +13,7 @@ using System.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Catch.Scoring;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Framework.Input.Bindings;
|
||||
|
||||
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 IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => 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 override IEnumerable<Mod> GetModsFor(ModType type)
|
||||
{
|
||||
switch (type)
|
||||
|
@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
return;
|
||||
accentColour = value;
|
||||
|
||||
if (LoadState == LoadState.Loaded)
|
||||
if (LoadState == LoadState.Ready)
|
||||
Schedule(reloadTexture);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// 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.Input;
|
||||
using osu.Framework.Input.Bindings;
|
||||
@ -33,19 +33,13 @@ namespace osu.Game.Rulesets.Osu
|
||||
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
|
||||
{
|
||||
[Description("Left Button")]
|
||||
LeftButton,
|
||||
[Description("Right Button")]
|
||||
RightButton
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Osu.Scoring;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osu.Framework.Input.Bindings;
|
||||
|
||||
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 IEnumerable<BeatmapStatistic> GetBeatmapStatistics(WorkingBeatmap beatmap) => new[]
|
||||
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => 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 override IEnumerable<BeatmapStatistic> GetBeatmapStatistics(WorkingBeatmap beatmap) => new[]
|
||||
{
|
||||
new BeatmapStatistic
|
||||
{
|
||||
Name = @"Circle count",
|
||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -34,9 +34,8 @@ namespace osu.Game.Graphics.Containers
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(UserInputManager input, OsuConfigManager config)
|
||||
private void load(OsuConfigManager config)
|
||||
{
|
||||
this.input = input;
|
||||
parallaxEnabled = config.GetBindable<bool>(OsuSetting.MenuParallax);
|
||||
parallaxEnabled.ValueChanged += delegate
|
||||
{
|
||||
@ -48,6 +47,12 @@ namespace osu.Game.Graphics.Containers
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
input = GetContainingInputManager();
|
||||
}
|
||||
|
||||
private bool firstUpdate = true;
|
||||
|
||||
protected override void Update()
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Input;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Input;
|
||||
using System;
|
||||
using System.Linq;
|
||||
@ -28,18 +27,10 @@ namespace osu.Game.Graphics.UserInterface
|
||||
{
|
||||
focus = value;
|
||||
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)
|
||||
{
|
||||
base.OnFocus(state);
|
||||
|
@ -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")]
|
||||
public class DatabasedKeyBinding : KeyBinding
|
||||
{
|
||||
[PrimaryKey, AutoIncrement]
|
||||
public int ID { get; set; }
|
||||
|
||||
[ForeignKey(typeof(RulesetInfo))]
|
||||
public int? RulesetID { get; set; }
|
||||
|
||||
@ -24,11 +27,12 @@ namespace osu.Game.Input.Bindings
|
||||
private set { KeyCombination = value; }
|
||||
}
|
||||
|
||||
[Indexed]
|
||||
[Column("Action")]
|
||||
public new int Action
|
||||
public int IntAction
|
||||
{
|
||||
get { return base.Action; }
|
||||
private set { base.Action = value; }
|
||||
get { return (int)Action; }
|
||||
set { Action = value; }
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
// 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.Input.Bindings;
|
||||
using osu.Game.Rulesets;
|
||||
@ -18,7 +19,9 @@ namespace osu.Game.Input.Bindings
|
||||
|
||||
private readonly int? variant;
|
||||
|
||||
private BindingStore store;
|
||||
private KeyBindingStore store;
|
||||
|
||||
public override IEnumerable<KeyBinding> DefaultKeyBindings => ruleset.CreateInstance().GetDefaultKeyBindings();
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance.
|
||||
@ -34,24 +37,14 @@ namespace osu.Game.Input.Bindings
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(BindingStore bindings)
|
||||
private void load(KeyBindingStore keyBindings)
|
||||
{
|
||||
store = bindings;
|
||||
store = keyBindings;
|
||||
}
|
||||
|
||||
protected override void ReloadMappings()
|
||||
{
|
||||
// load defaults
|
||||
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);
|
||||
}
|
||||
KeyBindings = store.Query(ruleset?.ID, variant);
|
||||
}
|
||||
}
|
||||
}
|
@ -11,17 +11,17 @@ using osu.Framework.Input.Bindings;
|
||||
|
||||
namespace osu.Game.Input.Bindings
|
||||
{
|
||||
public class GlobalBindingInputManager : DatabasedKeyBindingInputManager<GlobalAction>
|
||||
public class GlobalKeyBindingInputManager : DatabasedKeyBindingInputManager<GlobalAction>
|
||||
{
|
||||
private readonly Drawable handler;
|
||||
|
||||
public GlobalBindingInputManager(OsuGameBase game)
|
||||
public GlobalKeyBindingInputManager(OsuGameBase game)
|
||||
{
|
||||
if (game is IKeyBindingHandler<GlobalAction>)
|
||||
handler = game;
|
||||
}
|
||||
|
||||
protected override IEnumerable<KeyBinding> CreateDefaultMappings() => new[]
|
||||
public override IEnumerable<KeyBinding> DefaultKeyBindings => new[]
|
||||
{
|
||||
new KeyBinding(Key.F8, GlobalAction.ToggleChat),
|
||||
new KeyBinding(Key.F9, GlobalAction.ToggleSocial),
|
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,7 @@ namespace osu.Game
|
||||
LoadComponentAsync(direct = new DirectOverlay { Depth = -1 }, mainContent.Add);
|
||||
LoadComponentAsync(social = new SocialOverlay { Depth = -1 }, mainContent.Add);
|
||||
LoadComponentAsync(chat = new ChatOverlay { Depth = -1 }, mainContent.Add);
|
||||
LoadComponentAsync(settings = new SettingsOverlay { Depth = -1 }, overlayContent.Add);
|
||||
LoadComponentAsync(settings = new MainSettings { Depth = -1 }, overlayContent.Add);
|
||||
LoadComponentAsync(userProfile = new UserProfileOverlay { Depth = -2 }, mainContent.Add);
|
||||
LoadComponentAsync(musicController = new MusicController
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ namespace osu.Game
|
||||
|
||||
protected ScoreStore ScoreStore;
|
||||
|
||||
protected BindingStore BindingStore;
|
||||
protected KeyBindingStore KeyBindingStore;
|
||||
|
||||
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(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, Host));
|
||||
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());
|
||||
|
||||
//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();
|
||||
|
||||
GlobalKeyBindingInputManager globalBinding;
|
||||
|
||||
base.Content.Add(new RatioAdjust
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Cursor = new MenuCursor(),
|
||||
new GlobalBindingInputManager(this)
|
||||
globalBinding = new GlobalKeyBindingInputManager(this)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
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.
|
||||
// It's just to allow end-users to access the framework FPS display without knowing the shortcut key.
|
||||
fpsDisplayVisible = LocalConfig.GetBindable<bool>(OsuSetting.ShowFpsDisplay);
|
||||
|
@ -152,7 +152,7 @@ namespace osu.Game.Overlays.Chat
|
||||
|
||||
protected override void OnFocus(InputState state)
|
||||
{
|
||||
InputManager.ChangeFocus(search);
|
||||
GetContainingInputManager().ChangeFocus(search);
|
||||
base.OnFocus(state);
|
||||
}
|
||||
|
||||
|
@ -243,7 +243,7 @@ namespace osu.Game.Overlays
|
||||
protected override void OnFocus(InputState state)
|
||||
{
|
||||
//this is necessary as inputTextBox is masked away and therefore can't get focus :(
|
||||
InputManager.ChangeFocus(inputTextBox);
|
||||
GetContainingInputManager().ChangeFocus(inputTextBox);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
285
osu.Game/Overlays/KeyBinding/KeyBindingRow.cs
Normal file
285
osu.Game/Overlays/KeyBinding/KeyBindingRow.cs
Normal file
@ -0,0 +1,285 @@
|
||||
// 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
|
||||
}
|
||||
};
|
||||
|
||||
reloadBindings();
|
||||
}
|
||||
|
||||
private void reloadBindings()
|
||||
{
|
||||
buttons.Clear();
|
||||
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 => true;
|
||||
|
||||
private KeyButton bindTarget;
|
||||
|
||||
protected override void OnFocus(InputState state)
|
||||
{
|
||||
AutoSizeDuration = 500;
|
||||
AutoSizeEasing = Easing.OutQuint;
|
||||
|
||||
pressAKey.FadeIn(300, Easing.OutQuint);
|
||||
pressAKey.Padding = new MarginPadding();
|
||||
|
||||
base.OnFocus(state);
|
||||
}
|
||||
|
||||
private bool isModifier(Key k) => k < Key.F1;
|
||||
|
||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||
{
|
||||
if (HasFocus && !isModifier(args.Key))
|
||||
{
|
||||
bindTarget.KeyBinding.KeyCombination = args.Key == Key.Delete ? Key.Unknown : new KeyCombination(state.Keyboard.Keys);
|
||||
|
||||
store.Update(bindTarget.KeyBinding);
|
||||
GetContainingInputManager().ChangeFocus(null);
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnKeyDown(state, args);
|
||||
}
|
||||
|
||||
protected override void OnFocusLost(InputState state)
|
||||
{
|
||||
bindTarget.IsBinding = false;
|
||||
bindTarget = null;
|
||||
reloadBindings();
|
||||
|
||||
pressAKey.FadeOut(300, Easing.OutQuint);
|
||||
pressAKey.Padding = new MarginPadding { Bottom = -pressAKey.DrawHeight };
|
||||
base.OnFocusLost(state);
|
||||
}
|
||||
|
||||
protected override bool OnClick(InputState state)
|
||||
{
|
||||
if (bindTarget != null) bindTarget.IsBinding = false;
|
||||
bindTarget = buttons.FirstOrDefault(b => b.IsHovered) ?? buttons.FirstOrDefault();
|
||||
if (bindTarget != null) bindTarget.IsBinding = true;
|
||||
|
||||
return bindTarget != null;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
isBinding = value;
|
||||
|
||||
if (value)
|
||||
{
|
||||
box.FadeColour(Color4.White, transition_time, Easing.OutQuint);
|
||||
Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
box.FadeColour(Color4.Black, transition_time, Easing.OutQuint);
|
||||
Text.FadeColour(Color4.White, transition_time, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (isBinding)
|
||||
return false;
|
||||
|
||||
box.FadeColour(hoverColour, transition_time, Easing.OutQuint);
|
||||
Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint);
|
||||
|
||||
return base.OnHover(state);
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(InputState state)
|
||||
{
|
||||
if (isBinding)
|
||||
return;
|
||||
|
||||
box.FadeColour(Color4.Black, transition_time, Easing.OutQuint);
|
||||
Text.FadeColour(Color4.White, transition_time, Easing.OutQuint);
|
||||
|
||||
base.OnHoverLost(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
46
osu.Game/Overlays/KeyBinding/KeyBindingsSection.cs
Normal file
46
osu.Game/Overlays/KeyBinding/KeyBindingsSection.cs
Normal file
@ -0,0 +1,46 @@
|
||||
// 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))));
|
||||
}
|
||||
}
|
||||
}
|
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;
|
||||
this.FadeIn(transition_time, Easing.OutQuint);
|
||||
|
||||
InputManager.ChangeFocus(settingsSection);
|
||||
GetContainingInputManager().ChangeFocus(settingsSection);
|
||||
}
|
||||
|
||||
protected override void PopOut()
|
||||
|
33
osu.Game/Overlays/MainSettings.cs
Normal file
33
osu.Game/Overlays/MainSettings.cs
Normal file
@ -0,0 +1,33 @@
|
||||
// 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.Graphics;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osu.Game.Overlays.Settings.Sections;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
public class MainSettings : SettingsOverlay
|
||||
{
|
||||
protected override IEnumerable<SettingsSection> CreateSections() => new SettingsSection[]
|
||||
{
|
||||
new GeneralSection(),
|
||||
new GraphicsSection(),
|
||||
new GameplaySection(),
|
||||
new AudioSection(),
|
||||
new SkinSection(),
|
||||
new InputSection(),
|
||||
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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
@ -31,12 +30,10 @@ namespace osu.Game.Overlays.Music
|
||||
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
|
||||
|
||||
public IEnumerable<BeatmapSetInfo> BeatmapSets;
|
||||
private InputManager inputManager;
|
||||
|
||||
[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;
|
||||
|
||||
Children = new Drawable[]
|
||||
@ -102,7 +99,7 @@ namespace osu.Game.Overlays.Music
|
||||
protected override void PopIn()
|
||||
{
|
||||
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.FadeIn(transition_duration, Easing.OutQuint);
|
||||
|
@ -103,7 +103,7 @@ namespace osu.Game.Overlays.SearchableList
|
||||
|
||||
protected override void OnFocus(InputState state)
|
||||
{
|
||||
InputManager.ChangeFocus(Filter.Search);
|
||||
GetContainingInputManager().ChangeFocus(Filter.Search);
|
||||
}
|
||||
|
||||
protected override void PopIn()
|
||||
|
@ -57,12 +57,9 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
Spacing = new Vector2(0f, 5f);
|
||||
}
|
||||
|
||||
private InputManager inputManager;
|
||||
|
||||
[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;
|
||||
|
||||
api?.Register(this);
|
||||
@ -174,7 +171,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
break;
|
||||
}
|
||||
|
||||
if (form != null) inputManager.ChangeFocus(form);
|
||||
if (form != null) GetContainingInputManager().ChangeFocus(form);
|
||||
}
|
||||
|
||||
public override bool AcceptsFocus => true;
|
||||
@ -183,7 +180,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
|
||||
protected override void OnFocus(InputState state)
|
||||
{
|
||||
if (form != null) inputManager.ChangeFocus(form);
|
||||
if (form != null) GetContainingInputManager().ChangeFocus(form);
|
||||
base.OnFocus(state);
|
||||
}
|
||||
|
||||
@ -192,7 +189,6 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
private TextBox username;
|
||||
private TextBox password;
|
||||
private APIAccess api;
|
||||
private InputManager inputManager;
|
||||
|
||||
private void performLogin()
|
||||
{
|
||||
@ -201,9 +197,8 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
}
|
||||
|
||||
[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;
|
||||
Direction = FillDirection.Vertical;
|
||||
Spacing = new Vector2(0, 5);
|
||||
@ -256,7 +251,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
|
||||
protected override void OnFocus(InputState state)
|
||||
{
|
||||
Schedule(() => { inputManager.ChangeFocus(string.IsNullOrEmpty(username.Text) ? username : password); });
|
||||
Schedule(() => { GetContainingInputManager().ChangeFocus(string.IsNullOrEmpty(username.Text) ? username : password); });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,15 @@ namespace osu.Game.Overlays.Settings
|
||||
{
|
||||
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]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
@ -28,7 +37,7 @@ namespace osu.Game.Overlays.Settings
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = "settings",
|
||||
Text = heading,
|
||||
TextSize = 40,
|
||||
Margin = new MarginPadding
|
||||
{
|
||||
@ -39,7 +48,7 @@ namespace osu.Game.Overlays.Settings
|
||||
new OsuSpriteText
|
||||
{
|
||||
Colour = colours.Pink,
|
||||
Text = "Change the way osu! behaves",
|
||||
Text = subheading,
|
||||
TextSize = 18,
|
||||
Margin = new MarginPadding
|
||||
{
|
||||
|
@ -7,7 +7,6 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using System.Collections.Generic;
|
||||
@ -25,25 +24,38 @@ namespace osu.Game.Overlays.Settings
|
||||
|
||||
public IEnumerable<IFilterable> FilterableChildren => Children.OfType<IFilterable>();
|
||||
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
|
||||
{
|
||||
set
|
||||
{
|
||||
this.FadeTo(value ? 1 : 0);
|
||||
}
|
||||
set { this.FadeTo(value ? 1 : 0); }
|
||||
}
|
||||
|
||||
private readonly SpriteText headerLabel;
|
||||
|
||||
protected SettingsSection()
|
||||
{
|
||||
Margin = new MarginPadding { Top = 20 };
|
||||
AutoSizeAxes = Axes.Y;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
|
||||
const int header_size = 26;
|
||||
const int header_margin = 25;
|
||||
const int border_size = 2;
|
||||
FlowContent = new FillFlowContainer
|
||||
{
|
||||
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[]
|
||||
{
|
||||
new Box
|
||||
@ -65,28 +77,16 @@ namespace osu.Game.Overlays.Settings
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Children = new[]
|
||||
{
|
||||
headerLabel = new OsuSpriteText
|
||||
new OsuSpriteText
|
||||
{
|
||||
TextSize = header_size,
|
||||
Text = Header,
|
||||
Colour = colours.Yellow
|
||||
},
|
||||
FlowContent = new FillFlowContainer
|
||||
{
|
||||
Margin = new MarginPadding { Top = header_size + header_margin },
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 30),
|
||||
AutoSizeAxes = Axes.Y,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
},
|
||||
FlowContent
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
headerLabel.Colour = colours.Yellow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,12 +14,12 @@ using osu.Game.Overlays.Toolbar;
|
||||
|
||||
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 int EXPANDED_WIDTH = 200;
|
||||
protected override Container<Drawable> Content => content;
|
||||
protected override Container<SidebarButton> Content => content;
|
||||
|
||||
public Sidebar()
|
||||
{
|
||||
@ -35,7 +35,7 @@ namespace osu.Game.Overlays.Settings
|
||||
{
|
||||
Children = new[]
|
||||
{
|
||||
content = new FillFlowContainer
|
||||
content = new FillFlowContainer<SidebarButton>
|
||||
{
|
||||
Origin = Anchor.CentreLeft,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
|
@ -2,9 +2,11 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
@ -12,11 +14,10 @@ using osu.Framework.Input;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osu.Game.Overlays.Settings.Sections;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
public class SettingsOverlay : OsuFocusedOverlayContainer
|
||||
public abstract class SettingsOverlay : OsuFocusedOverlayContainer
|
||||
{
|
||||
internal const float CONTENT_MARGINS = 10;
|
||||
|
||||
@ -29,36 +30,28 @@ namespace osu.Game.Overlays
|
||||
private const float sidebar_padding = 10;
|
||||
|
||||
private Sidebar sidebar;
|
||||
private SidebarButton[] sidebarButtons;
|
||||
private SidebarButton selectedSidebarButton;
|
||||
|
||||
private SettingsSectionsContainer sectionsContainer;
|
||||
protected SettingsSectionsContainer SectionsContainer;
|
||||
|
||||
private SearchTextBox searchTextBox;
|
||||
|
||||
private Func<float> getToolbarHeight;
|
||||
|
||||
public SettingsOverlay()
|
||||
private readonly bool showSidebar;
|
||||
|
||||
protected SettingsOverlay(bool showSidebar)
|
||||
{
|
||||
this.showSidebar = showSidebar;
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
AutoSizeAxes = Axes.X;
|
||||
}
|
||||
|
||||
protected virtual IEnumerable<SettingsSection> CreateSections() => null;
|
||||
|
||||
[BackgroundDependencyLoader(permitNulls: true)]
|
||||
private void load(OsuGame game)
|
||||
{
|
||||
var sections = new SettingsSection[]
|
||||
{
|
||||
new GeneralSection(),
|
||||
new GraphicsSection(),
|
||||
new GameplaySection(),
|
||||
new AudioSection(),
|
||||
new SkinSection(),
|
||||
new InputSection(),
|
||||
new OnlineSection(),
|
||||
new MaintenanceSection(),
|
||||
new DebugSection(),
|
||||
};
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
@ -67,12 +60,12 @@ namespace osu.Game.Overlays
|
||||
Colour = Color4.Black,
|
||||
Alpha = 0.6f,
|
||||
},
|
||||
sectionsContainer = new SettingsSectionsContainer
|
||||
SectionsContainer = new SettingsSectionsContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = width,
|
||||
Margin = new MarginPadding { Left = SIDEBAR_WIDTH },
|
||||
ExpandableHeader = new SettingsHeader(),
|
||||
ExpandableHeader = CreateHeader(),
|
||||
FixedHeader = searchTextBox = new SearchTextBox
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
@ -86,47 +79,65 @@ namespace osu.Game.Overlays
|
||||
},
|
||||
Exit = Hide,
|
||||
},
|
||||
Children = sections,
|
||||
Footer = new SettingsFooter()
|
||||
Footer = CreateFooter()
|
||||
},
|
||||
sidebar = new Sidebar
|
||||
{
|
||||
Width = SIDEBAR_WIDTH,
|
||||
Children = sidebarButtons = sections.Select(section =>
|
||||
new SidebarButton
|
||||
{
|
||||
Section = section,
|
||||
Action = s =>
|
||||
{
|
||||
sectionsContainer.ScrollTo(s);
|
||||
sidebar.State = ExpandedState.Contracted;
|
||||
},
|
||||
}
|
||||
).ToArray()
|
||||
}
|
||||
};
|
||||
|
||||
selectedSidebarButton = sidebarButtons[0];
|
||||
selectedSidebarButton.Selected = true;
|
||||
|
||||
sectionsContainer.SelectedSection.ValueChanged += section =>
|
||||
if (showSidebar)
|
||||
{
|
||||
selectedSidebarButton.Selected = false;
|
||||
selectedSidebarButton = sidebarButtons.Single(b => b.Section == section);
|
||||
selectedSidebarButton.Selected = true;
|
||||
};
|
||||
Add(sidebar = new Sidebar { Width = SIDEBAR_WIDTH });
|
||||
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
searchTextBox.Current.ValueChanged += newValue => SectionsContainer.SearchContainer.SearchTerm = newValue;
|
||||
|
||||
getToolbarHeight = () => game?.ToolbarOffset ?? 0;
|
||||
|
||||
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()
|
||||
{
|
||||
base.PopIn();
|
||||
|
||||
sectionsContainer.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint);
|
||||
sidebar.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint);
|
||||
SectionsContainer.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint);
|
||||
sidebar?.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint);
|
||||
this.FadeTo(1, TRANSITION_LENGTH / 2);
|
||||
|
||||
searchTextBox.HoldFocus = true;
|
||||
@ -136,13 +147,13 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
base.PopOut();
|
||||
|
||||
sectionsContainer.MoveToX(-width, TRANSITION_LENGTH, Easing.OutQuint);
|
||||
sidebar.MoveToX(-SIDEBAR_WIDTH, TRANSITION_LENGTH, Easing.OutQuint);
|
||||
SectionsContainer.MoveToX(-width, TRANSITION_LENGTH, Easing.OutQuint);
|
||||
sidebar?.MoveToX(-SIDEBAR_WIDTH, TRANSITION_LENGTH, Easing.OutQuint);
|
||||
this.FadeTo(0, TRANSITION_LENGTH / 2);
|
||||
|
||||
searchTextBox.HoldFocus = false;
|
||||
if (searchTextBox.HasFocus)
|
||||
InputManager.ChangeFocus(null);
|
||||
GetContainingInputManager().ChangeFocus(null);
|
||||
}
|
||||
|
||||
public override bool AcceptsFocus => true;
|
||||
@ -151,7 +162,7 @@ namespace osu.Game.Overlays
|
||||
|
||||
protected override void OnFocus(InputState state)
|
||||
{
|
||||
InputManager.ChangeFocus(searchTextBox);
|
||||
GetContainingInputManager().ChangeFocus(searchTextBox);
|
||||
base.OnFocus(state);
|
||||
}
|
||||
|
||||
@ -159,11 +170,11 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
base.UpdateAfterChildren();
|
||||
|
||||
sectionsContainer.Margin = new MarginPadding { Left = sidebar.DrawWidth };
|
||||
sectionsContainer.Padding = new MarginPadding { Top = getToolbarHeight() };
|
||||
SectionsContainer.Margin = new MarginPadding { Left = sidebar?.DrawWidth ?? 0 };
|
||||
SectionsContainer.Padding = new MarginPadding { Top = getToolbarHeight() };
|
||||
}
|
||||
|
||||
private class SettingsSectionsContainer : SectionsContainer<SettingsSection>
|
||||
protected class SettingsSectionsContainer : SectionsContainer<SettingsSection>
|
||||
{
|
||||
public SearchContainer<SettingsSection> SearchContainer;
|
||||
|
||||
|
@ -8,6 +8,7 @@ using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Screens.Play;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Overlays.Settings;
|
||||
|
||||
@ -53,5 +54,17 @@ namespace osu.Game.Rulesets
|
||||
/// Do not override this unless you are a legacy mode.
|
||||
/// </summary>
|
||||
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[] { };
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.UI
|
||||
internal RulesetContainer(Ruleset ruleset)
|
||||
{
|
||||
Ruleset = ruleset;
|
||||
KeyConversionInputManager = CreateActionMappingInputManager();
|
||||
KeyConversionInputManager = CreateKeyBindingInputManager();
|
||||
KeyConversionInputManager.RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.UI
|
||||
/// Creates a key conversion input manager.
|
||||
/// </summary>
|
||||
/// <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);
|
||||
|
||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Screens
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
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;
|
||||
|
||||
|
@ -153,7 +153,7 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
searchTextBox.HoldFocus = false;
|
||||
if (searchTextBox.HasFocus)
|
||||
inputManager.ChangeFocus(searchTextBox);
|
||||
GetContainingInputManager().ChangeFocus(searchTextBox);
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
@ -163,13 +163,9 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||
|
||||
private InputManager inputManager;
|
||||
|
||||
[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;
|
||||
|
||||
if (osu != null)
|
||||
|
@ -156,11 +156,11 @@ namespace osu.Game.Screens.Select
|
||||
}
|
||||
|
||||
[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)
|
||||
{
|
||||
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);
|
||||
|
||||
BeatmapOptions.AddButton(@"Delete", @"Beatmap", FontAwesome.fa_trash, colours.Pink, promptDelete, Key.Number4, float.MaxValue);
|
||||
@ -267,9 +267,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();
|
||||
else
|
||||
carousel.SelectNextRandom();
|
||||
|
@ -94,14 +94,20 @@
|
||||
<Compile Include="Graphics\UserInterface\OsuContextMenuItem.cs" />
|
||||
<Compile Include="Input\Bindings\DatabasedKeyBinding.cs" />
|
||||
<Compile Include="Input\Bindings\DatabasedKeyBindingInputManager.cs" />
|
||||
<Compile Include="Input\BindingStore.cs" />
|
||||
<Compile Include="Input\Bindings\GlobalBindingInputManager.cs" />
|
||||
<Compile Include="Input\KeyBindingStore.cs" />
|
||||
<Compile Include="Input\Bindings\GlobalKeyBindingInputManager.cs" />
|
||||
<Compile Include="IO\FileStore.cs" />
|
||||
<Compile Include="IO\FileInfo.cs" />
|
||||
<Compile Include="Online\API\Requests\GetUsersRequest.cs" />
|
||||
<Compile Include="Online\API\Requests\PostMessageRequest.cs" />
|
||||
<Compile Include="Online\Chat\ErrorMessage.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\FilterControl.cs" />
|
||||
<Compile Include="Overlays\Music\PlaylistItem.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user