1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-16 11:22:55 +08:00

Merge branch 'master' into fix-ruleset-changing

This commit is contained in:
Dean Herbert 2017-08-13 11:14:41 +09:00 committed by GitHub
commit 94b8d1de8b
24 changed files with 375 additions and 280 deletions

@ -1 +1 @@
Subproject commit 67d89a36016f98c0ede576b859a2ccafe114fce8 Subproject commit 2a56eb0619adf654ed4927af1a4b227596c87494

View File

@ -2,31 +2,37 @@
// 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.Game.Input; using System.ComponentModel;
using osu.Framework.Input.Bindings;
using osu.Game.Input.Bindings;
using OpenTK.Input; using OpenTK.Input;
namespace osu.Game.Rulesets.Catch namespace osu.Game.Rulesets.Catch
{ {
public class CatchInputManager : ActionMappingInputManager<CatchAction> public class CatchInputManager : DatabasedKeyBindingInputManager<CatchAction>
{ {
public CatchInputManager(RulesetInfo ruleset) : base(ruleset) public CatchInputManager(RulesetInfo ruleset) : base(ruleset, simultaneousMode: SimultaneousBindingMode.Unique)
{ {
Mappings = new Dictionary<Key, CatchAction>
{
{ Key.Z, CatchAction.MoveLeft },
{ Key.Left, CatchAction.MoveLeft },
{ Key.X, CatchAction.MoveRight },
{ Key.Right, CatchAction.MoveRight },
{ Key.LShift, CatchAction.Dash },
{ Key.RShift, CatchAction.Dash },
};
} }
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
{ {
[Description("Move left")]
MoveLeft, MoveLeft,
[Description("Move right")]
MoveRight, MoveRight,
[Description("Engage dash")]
Dash Dash
} }
} }

View File

@ -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); protected override PassThroughInputManager CreateActionMappingInputManager() => new CatchInputManager(Ruleset?.RulesetInfo);
protected override DrawableHitObject<CatchBaseHit, CatchJudgement> GetVisualRepresentation(CatchBaseHit h) protected override DrawableHitObject<CatchBaseHit, CatchJudgement> GetVisualRepresentation(CatchBaseHit h)
{ {

View File

@ -8,7 +8,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.Input; using osu.Framework.Input.Bindings;
using osu.Framework.MathUtils; using osu.Framework.MathUtils;
using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Catch.UI
catcher.Size = new Vector2(DrawSize.Y); catcher.Size = new Vector2(DrawSize.Y);
} }
private class Catcher : Container private class Catcher : Container, IKeyBindingHandler<CatchAction>
{ {
private Texture texture; private Texture texture;
@ -104,48 +104,40 @@ namespace osu.Game.Rulesets.Catch.UI
OriginPosition = new Vector2(DrawWidth / 2, 10) //temporary until the sprite is aligned correctly. OriginPosition = new Vector2(DrawWidth / 2, 10) //temporary until the sprite is aligned correctly.
}; };
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) public bool OnPressed(CatchAction action)
{ {
if (args.Repeat) return true; switch (action)
if (state.Data is CatchAction)
{ {
switch ((CatchAction)state.Data) case CatchAction.MoveLeft:
{ currentDirection--;
case CatchAction.MoveLeft: return true;
currentDirection--; case CatchAction.MoveRight:
return true; currentDirection++;
case CatchAction.MoveRight: return true;
currentDirection++; case CatchAction.Dash:
return true; Dashing = true;
case CatchAction.Dash: return true;
Dashing = true;
return true;
}
} }
return base.OnKeyDown(state, args); return false;
} }
protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) public bool OnReleased(CatchAction action)
{ {
if (state.Data is CatchAction) switch (action)
{ {
switch ((CatchAction)state.Data) case CatchAction.MoveLeft:
{ currentDirection++;
case CatchAction.MoveLeft: return true;
currentDirection++; case CatchAction.MoveRight:
return true; currentDirection--;
case CatchAction.MoveRight: return true;
currentDirection--; case CatchAction.Dash:
return true; Dashing = false;
case CatchAction.Dash: return true;
Dashing = false;
return true;
}
} }
return base.OnKeyUp(state, args); return false;
} }
protected override void Update() protected override void Update()

View File

@ -7,12 +7,12 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.Input; using osu.Framework.Input.Bindings;
using OpenTK; using OpenTK;
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{ {
public class CirclePiece : Container public class CirclePiece : Container, IKeyBindingHandler<OsuAction>
{ {
private readonly Sprite disc; private readonly Sprite disc;
@ -49,9 +49,18 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
disc.Texture = textures.Get(@"Play/osu/disc"); disc.Texture = textures.Get(@"Play/osu/disc");
} }
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) public bool OnPressed(OsuAction action)
{ {
return Hit?.Invoke() ?? false; switch (action)
{
case OsuAction.LeftButton:
case OsuAction.RightButton:
return IsHovered && (Hit?.Invoke() ?? false);
}
return false;
} }
public bool OnReleased(OsuAction action) => false;
} }
} }

View 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.Linq;
using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Game.Input.Bindings;
using OpenTK.Input;
using KeyboardState = osu.Framework.Input.KeyboardState;
using MouseState = osu.Framework.Input.MouseState;
namespace osu.Game.Rulesets.Osu
{
public class OsuInputManager : DatabasedKeyBindingInputManager<OsuAction>
{
public OsuInputManager(RulesetInfo ruleset) : base(ruleset, simultaneousMode: SimultaneousBindingMode.Unique)
{
}
protected override void TransformState(InputState state)
{
base.TransformState(state);
var mouse = state.Mouse as MouseState;
var keyboard = state.Keyboard as KeyboardState;
if (mouse != null && keyboard != null)
{
if (mouse.IsPressed(MouseButton.Left))
keyboard.Keys = keyboard.Keys.Concat(new[] { Key.LastKey + 1 });
if (mouse.IsPressed(MouseButton.Right))
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
{
LeftButton,
RightButton
}
}

View File

@ -1,39 +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.Linq;
using osu.Framework.Input;
using OpenTK.Input;
using KeyboardState = osu.Framework.Input.KeyboardState;
using MouseState = osu.Framework.Input.MouseState;
namespace osu.Game.Rulesets.Osu
{
public class OsuKeyConversionInputManager : PassThroughInputManager
{
private bool leftViaKeyboard;
private bool rightViaKeyboard;
protected override void TransformState(InputState state)
{
base.TransformState(state);
var mouse = state.Mouse as MouseState;
var keyboard = state.Keyboard as KeyboardState;
if (keyboard != null)
{
leftViaKeyboard = keyboard.Keys.Contains(Key.Z);
rightViaKeyboard = keyboard.Keys.Contains(Key.X);
}
if (mouse != null)
{
if (leftViaKeyboard)
mouse.SetPressed(MouseButton.Left, true);
if (rightViaKeyboard)
mouse.SetPressed(MouseButton.Right, true);
}
}
}
}

View File

@ -1,22 +1,22 @@
// 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.Diagnostics;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.OpenGL.Buffers;
using osu.Framework.Graphics.OpenGL.Vertices;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Shaders;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.Input; using osu.Framework.Input;
using OpenTK;
using System;
using osu.Framework.Graphics.OpenGL.Buffers;
using OpenTK.Graphics.ES30;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Colour;
using osu.Framework.Timing; using osu.Framework.Timing;
using System.Diagnostics; using OpenTK;
using osu.Framework.Graphics.OpenGL.Vertices; using OpenTK.Graphics.ES30;
namespace osu.Game.Graphics.Cursor namespace osu.Game.Rulesets.Osu.UI.Cursor
{ {
internal class CursorTrail : Drawable internal class CursorTrail : Drawable
{ {

View File

@ -1,8 +1,6 @@
// 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 OpenTK;
using OpenTK.Graphics;
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;
@ -10,13 +8,15 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Input; using osu.Framework.Input.Bindings;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Graphics.Cursor namespace osu.Game.Rulesets.Osu.UI.Cursor
{ {
public class GameplayCursor : CursorContainer public class GameplayCursor : CursorContainer, IKeyBindingHandler<OsuAction>
{ {
protected override Drawable CreateCursor() => new OsuCursor(); protected override Drawable CreateCursor() => new OsuCursor();
@ -25,19 +25,7 @@ namespace osu.Game.Graphics.Cursor
Add(new CursorTrail { Depth = 1 }); Add(new CursorTrail { Depth = 1 });
} }
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) private int downCount;
{
ActiveCursor.Scale = new Vector2(1);
ActiveCursor.ScaleTo(1.2f, 100, Easing.OutQuad);
return base.OnMouseDown(state, args);
}
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
{
if (!state.Mouse.HasMainButtonPressed)
ActiveCursor.ScaleTo(1, 200, Easing.OutQuad);
return base.OnMouseUp(state, args);
}
public class OsuCursor : Container public class OsuCursor : Container
{ {
@ -143,5 +131,33 @@ namespace osu.Game.Graphics.Cursor
cursorContainer.Scale = new Vector2(scale); cursorContainer.Scale = new Vector2(scale);
} }
} }
public bool OnPressed(OsuAction action)
{
switch (action)
{
case OsuAction.LeftButton:
case OsuAction.RightButton:
downCount++;
ActiveCursor.ScaleTo(1).ScaleTo(1.2f, 100, Easing.OutQuad);
break;
}
return false;
}
public bool OnReleased(OsuAction action)
{
switch (action)
{
case OsuAction.LeftButton:
case OsuAction.RightButton:
if (--downCount == 0)
ActiveCursor.ScaleTo(1, 200, Easing.OutQuad);
break;
}
return false;
}
} }
} }

View File

@ -10,8 +10,8 @@ using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects.Drawables.Connections; using osu.Game.Rulesets.Osu.Objects.Drawables.Connections;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
using System.Linq; using System.Linq;
using osu.Game.Graphics.Cursor;
using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Judgements;
using osu.Game.Rulesets.Osu.UI.Cursor;
namespace osu.Game.Rulesets.Osu.UI namespace osu.Game.Rulesets.Osu.UI
{ {

View File

@ -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 OsuKeyConversionInputManager(); protected override PassThroughInputManager CreateActionMappingInputManager() => new OsuInputManager(Ruleset?.RulesetInfo);
protected override DrawableHitObject<OsuHitObject, OsuJudgement> GetVisualRepresentation(OsuHitObject h) protected override DrawableHitObject<OsuHitObject, OsuJudgement> GetVisualRepresentation(OsuHitObject h)
{ {

View File

@ -77,7 +77,9 @@
<Compile Include="OsuDifficulty\Skills\Skill.cs" /> <Compile Include="OsuDifficulty\Skills\Skill.cs" />
<Compile Include="OsuDifficulty\Skills\Speed.cs" /> <Compile Include="OsuDifficulty\Skills\Speed.cs" />
<Compile Include="OsuDifficulty\Utils\History.cs" /> <Compile Include="OsuDifficulty\Utils\History.cs" />
<Compile Include="OsuKeyConversionInputManager.cs" /> <Compile Include="OsuInputManager.cs" />
<Compile Include="UI\Cursor\CursorTrail.cs" />
<Compile Include="UI\Cursor\GameplayCursor.cs" />
<Compile Include="UI\OsuSettings.cs" /> <Compile Include="UI\OsuSettings.cs" />
<Compile Include="Scoring\OsuScoreProcessor.cs" /> <Compile Include="Scoring\OsuScoreProcessor.cs" />
<Compile Include="UI\OsuRulesetContainer.cs" /> <Compile Include="UI\OsuRulesetContainer.cs" />

View File

@ -1,74 +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 System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Input;
using osu.Game.Rulesets;
using OpenTK.Input;
namespace osu.Game.Input
{
/// <summary>
/// Maps custom action data of type <see cref="T"/> and stores to <see cref="InputState.Data"/>.
/// </summary>
/// <typeparam name="T">The type of the custom action.</typeparam>
public class ActionMappingInputManager<T> : PassThroughInputManager
where T : struct
{
private readonly RulesetInfo ruleset;
private readonly int? variant;
/// <summary>
/// Create a new instance.
/// </summary>
/// <param name="ruleset">A reference to identify the current <see cref="Ruleset"/>. Used to lookup mappings. Null for global mappings.</param>
/// <param name="variant">An optional variant for the specified <see cref="Ruleset"/>. Used when a ruleset has more than one possible keyboard layouts.</param>
protected ActionMappingInputManager(RulesetInfo ruleset = null, int? variant = null)
{
this.ruleset = ruleset;
this.variant = variant;
}
protected IDictionary<Key, T> Mappings { get; set; }
[BackgroundDependencyLoader]
private void load(BindingStore bindings)
{
var rulesetId = ruleset?.ID;
foreach (var b in bindings.Query<Binding>(b => b.RulesetID == rulesetId && b.Variant == variant))
Mappings[b.Key] = (T)(object)b.Action;
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
mapKey(state, args.Key);
return base.OnKeyDown(state, args);
}
protected override bool OnKeyUp(InputState state, KeyUpEventArgs args)
{
mapKey(state, args.Key);
return base.OnKeyUp(state, args);
}
private void mapKey(InputState state, Key key)
{
T mappedData;
if (Mappings.TryGetValue(key, out mappedData))
state.Data = mappedData;
}
private T parseStringRepresentation(string str)
{
T res;
if (Enum.TryParse(str, out res))
return res;
return default(T);
}
}
}

View File

@ -1,23 +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 osu.Game.Rulesets;
using OpenTK.Input;
using SQLite.Net.Attributes;
using SQLiteNetExtensions.Attributes;
namespace osu.Game.Input
{
public class Binding
{
[ForeignKey(typeof(RulesetInfo))]
public int? RulesetID { get; set; }
[Indexed]
public int? Variant { get; set; }
public Key Key { get; set; }
public int Action { get; set; }
}
}

View File

@ -4,6 +4,7 @@
using System; using System;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Input.Bindings;
using SQLite.Net; using SQLite.Net;
namespace osu.Game.Input namespace osu.Game.Input
@ -15,14 +16,32 @@ namespace osu.Game.Input
{ {
} }
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) protected override void Prepare(bool reset = false)
{ {
Connection.CreateTable<Binding>(); Connection.CreateTable<DatabasedKeyBinding>();
} }
protected override Type[] ValidTypes => new[] protected override Type[] ValidTypes => new[]
{ {
typeof(Binding) typeof(DatabasedKeyBinding)
}; };
} }

View File

@ -0,0 +1,34 @@
// 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.Rulesets;
using SQLite.Net.Attributes;
using SQLiteNetExtensions.Attributes;
namespace osu.Game.Input.Bindings
{
[Table("KeyBinding")]
public class DatabasedKeyBinding : KeyBinding
{
[ForeignKey(typeof(RulesetInfo))]
public int? RulesetID { get; set; }
[Indexed]
public int? Variant { get; set; }
[Column("Keys")]
public string KeysString
{
get { return KeyCombination.ToString(); }
private set { KeyCombination = value; }
}
[Column("Action")]
public new int Action
{
get { return base.Action; }
private set { base.Action = value; }
}
}
}

View File

@ -0,0 +1,57 @@
// 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.Input.Bindings;
using osu.Game.Rulesets;
namespace osu.Game.Input.Bindings
{
/// <summary>
/// A KeyBindingInputManager with a database backing for custom overrides.
/// </summary>
/// <typeparam name="T">The type of the custom action.</typeparam>
public abstract class DatabasedKeyBindingInputManager<T> : KeyBindingInputManager<T>
where T : struct
{
private readonly RulesetInfo ruleset;
private readonly int? variant;
private BindingStore store;
/// <summary>
/// Create a new instance.
/// </summary>
/// <param name="ruleset">A reference to identify the current <see cref="Ruleset"/>. Used to lookup mappings. Null for global mappings.</param>
/// <param name="variant">An optional variant for the specified <see cref="Ruleset"/>. Used when a ruleset has more than one possible keyboard layouts.</param>
/// <param name="simultaneousMode">Specify how to deal with multiple matches of <see cref="KeyCombination"/>s and <see cref="T"/>s.</param>
protected DatabasedKeyBindingInputManager(RulesetInfo ruleset = null, int? variant = null, SimultaneousBindingMode simultaneousMode = SimultaneousBindingMode.None)
: base(simultaneousMode)
{
this.ruleset = ruleset;
this.variant = variant;
}
[BackgroundDependencyLoader]
private void load(BindingStore bindings)
{
store = bindings;
}
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);
}
}
}
}

View File

@ -0,0 +1,68 @@
// 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,
}
}

View File

@ -9,17 +9,16 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Framework.Input; using osu.Framework.Input;
using OpenTK.Input;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Game.Graphics.UserInterface.Volume; using osu.Game.Graphics.UserInterface.Volume;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Timing;
using osu.Game.Overlays.Toolbar; using osu.Game.Overlays.Toolbar;
using osu.Game.Screens; using osu.Game.Screens;
using osu.Game.Screens.Menu; using osu.Game.Screens.Menu;
using OpenTK; using OpenTK;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using osu.Framework.Input.Bindings;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Game.Graphics; using osu.Game.Graphics;
@ -27,10 +26,11 @@ using osu.Game.Rulesets.Scoring;
using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osu.Game.Input.Bindings;
namespace osu.Game namespace osu.Game
{ {
public class OsuGame : OsuGameBase public class OsuGame : OsuGameBase, IKeyBindingHandler<GlobalAction>
{ {
public Toolbar Toolbar; public Toolbar Toolbar;
@ -169,10 +169,6 @@ namespace osu.Game
volume = new VolumeControl(), volume = new VolumeControl(),
overlayContent = new Container { RelativeSizeAxes = Axes.Both }, overlayContent = new Container { RelativeSizeAxes = Axes.Both },
new OnScreenDisplay(), new OnScreenDisplay(),
new GlobalHotkeys //exists because UserInputManager is at a level below us.
{
Handler = globalHotkeyPressed
}
}); });
LoadComponentAsync(screenStack = new Loader(), d => LoadComponentAsync(screenStack = new Loader(), d =>
@ -252,63 +248,43 @@ namespace osu.Game
Cursor.State = Visibility.Hidden; Cursor.State = Visibility.Hidden;
} }
private bool globalHotkeyPressed(InputState state, KeyDownEventArgs args) public bool OnPressed(GlobalAction action)
{ {
if (args.Repeat || intro == null) return false; if (intro == null) return false;
switch (args.Key) switch (action)
{ {
case Key.F8: case GlobalAction.ToggleChat:
chat.ToggleVisibility(); chat.ToggleVisibility();
return true; return true;
case Key.F9: case GlobalAction.ToggleSocial:
social.ToggleVisibility(); social.ToggleVisibility();
return true; return true;
case Key.PageUp: case GlobalAction.ResetInputSettings:
case Key.PageDown: var sensitivity = frameworkConfig.GetBindable<double>(FrameworkSetting.CursorSensitivity);
var swClock = (Clock as ThrottledFrameClock)?.Source as StopwatchClock;
if (swClock == null) return false;
swClock.Rate *= args.Key == Key.PageUp ? 1.1f : 0.9f; sensitivity.Disabled = false;
Logger.Log($@"Adjusting game clock to {swClock.Rate}", LoggingTarget.Debug); sensitivity.Value = 1;
sensitivity.Disabled = true;
frameworkConfig.Set(FrameworkSetting.ActiveInputHandlers, string.Empty);
return true;
case GlobalAction.ToggleToolbar:
Toolbar.ToggleVisibility();
return true;
case GlobalAction.ToggleSettings:
settings.ToggleVisibility();
return true;
case GlobalAction.ToggleDirect:
direct.ToggleVisibility();
return true; return true;
}
if (state.Keyboard.ControlPressed)
{
switch (args.Key)
{
case Key.R:
if (state.Keyboard.AltPressed)
{
var sensitivity = frameworkConfig.GetBindable<double>(FrameworkSetting.CursorSensitivity);
sensitivity.Disabled = false;
sensitivity.Value = 1;
sensitivity.Disabled = true;
frameworkConfig.Set(FrameworkSetting.ActiveInputHandlers, string.Empty);
return true;
}
break;
case Key.T:
Toolbar.ToggleVisibility();
return true;
case Key.O:
settings.ToggleVisibility();
return true;
case Key.D:
if (state.Keyboard.ShiftPressed || state.Keyboard.AltPressed)
return false;
direct.ToggleVisibility();
return true;
}
} }
return false; return false;
} }
public bool OnReleased(GlobalAction action) => false;
public event Action<Screen> ScreenChanged; public event Action<Screen> ScreenChanged;
private Container mainContent; private Container mainContent;

View File

@ -20,6 +20,7 @@ using SQLite.Net;
using osu.Framework.Graphics.Performance; using osu.Framework.Graphics.Performance;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Input; using osu.Game.Input;
using osu.Game.Input.Bindings;
using osu.Game.IO; using osu.Game.IO;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
@ -187,13 +188,14 @@ namespace osu.Game
Children = new Drawable[] Children = new Drawable[]
{ {
Cursor = new MenuCursor(), Cursor = new MenuCursor(),
new OsuTooltipContainer(Cursor) new GlobalBindingInputManager(this)
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Child = content = new OsuContextMenuContainer Child = new OsuTooltipContainer(Cursor)
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}, Child = content = new OsuContextMenuContainer { RelativeSizeAxes = Axes.Both },
}
} }
} }
}); });

View File

@ -245,7 +245,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Text = "Register new account", Text = "Register new account",
//Action = registerLink //Binding = registerLink
} }
}; };
} }

View File

@ -39,7 +39,7 @@ namespace osu.Game.Screens.Select
/// <param name="text">Text on the button.</param> /// <param name="text">Text on the button.</param>
/// <param name="colour">Colour of the button.</param> /// <param name="colour">Colour of the button.</param>
/// <param name="hotkey">Hotkey of the button.</param> /// <param name="hotkey">Hotkey of the button.</param>
/// <param name="action">Action the button does.</param> /// <param name="action">Binding the button does.</param>
/// <param name="depth"> /// <param name="depth">
/// <para>Higher depth to be put on the left, and lower to be put on the right.</para> /// <para>Higher depth to be put on the left, and lower to be put on the right.</para>
/// <para>Notice this is different to <see cref="Options.BeatmapOptionsOverlay"/>!</para> /// <para>Notice this is different to <see cref="Options.BeatmapOptionsOverlay"/>!</para>

View File

@ -86,7 +86,7 @@ namespace osu.Game.Screens.Select.Options
/// <param name="colour">Colour of the button.</param> /// <param name="colour">Colour of the button.</param>
/// <param name="icon">Icon of the button.</param> /// <param name="icon">Icon of the button.</param>
/// <param name="hotkey">Hotkey of the button.</param> /// <param name="hotkey">Hotkey of the button.</param>
/// <param name="action">Action the button does.</param> /// <param name="action">Binding the button does.</param>
/// <param name="depth"> /// <param name="depth">
/// <para>Lower depth to be put on the left, and higher to be put on the right.</para> /// <para>Lower depth to be put on the left, and higher to be put on the right.</para>
/// <para>Notice this is different to <see cref="Footer"/>!</para> /// <para>Notice this is different to <see cref="Footer"/>!</para>

View File

@ -92,8 +92,10 @@
<Compile Include="Graphics\UserInterface\MenuItemType.cs" /> <Compile Include="Graphics\UserInterface\MenuItemType.cs" />
<Compile Include="Graphics\UserInterface\OsuContextMenu.cs" /> <Compile Include="Graphics\UserInterface\OsuContextMenu.cs" />
<Compile Include="Graphics\UserInterface\OsuContextMenuItem.cs" /> <Compile Include="Graphics\UserInterface\OsuContextMenuItem.cs" />
<Compile Include="Input\Binding.cs" /> <Compile Include="Input\Bindings\DatabasedKeyBinding.cs" />
<Compile Include="Input\Bindings\DatabasedKeyBindingInputManager.cs" />
<Compile Include="Input\BindingStore.cs" /> <Compile Include="Input\BindingStore.cs" />
<Compile Include="Input\Bindings\GlobalBindingInputManager.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" />
@ -120,7 +122,6 @@
<Compile Include="Overlays\Profile\Sections\RecentSection.cs" /> <Compile Include="Overlays\Profile\Sections\RecentSection.cs" />
<Compile Include="Graphics\Containers\ConstrainedIconContainer.cs" /> <Compile Include="Graphics\Containers\ConstrainedIconContainer.cs" />
<Compile Include="Rulesets\Mods\IApplicableToDifficulty.cs" /> <Compile Include="Rulesets\Mods\IApplicableToDifficulty.cs" />
<Compile Include="Input\ActionMappingInputManager.cs" />
<Compile Include="Users\UserCoverBackground.cs" /> <Compile Include="Users\UserCoverBackground.cs" />
<Compile Include="Overlays\UserProfileOverlay.cs" /> <Compile Include="Overlays\UserProfileOverlay.cs" />
<Compile Include="Overlays\Profile\ProfileHeader.cs" /> <Compile Include="Overlays\Profile\ProfileHeader.cs" />
@ -142,8 +143,6 @@
<Compile Include="Rulesets\RulesetInfo.cs" /> <Compile Include="Rulesets\RulesetInfo.cs" />
<Compile Include="Rulesets\Scoring\ScoreStore.cs" /> <Compile Include="Rulesets\Scoring\ScoreStore.cs" />
<Compile Include="Graphics\Backgrounds\Triangles.cs" /> <Compile Include="Graphics\Backgrounds\Triangles.cs" />
<Compile Include="Graphics\Cursor\CursorTrail.cs" />
<Compile Include="Graphics\Cursor\GameplayCursor.cs" />
<Compile Include="Graphics\IHasAccentColour.cs" /> <Compile Include="Graphics\IHasAccentColour.cs" />
<Compile Include="Graphics\Sprites\OsuSpriteText.cs" /> <Compile Include="Graphics\Sprites\OsuSpriteText.cs" />
<Compile Include="Graphics\UserInterface\BackButton.cs" /> <Compile Include="Graphics\UserInterface\BackButton.cs" />