mirror of
https://github.com/ppy/osu.git
synced 2025-02-21 18:42:56 +08:00
Merge branch 'master' into mania-hitobject-object-conversion
This commit is contained in:
commit
51728e48be
@ -140,6 +140,26 @@ namespace osu.Game.Rulesets.Mania.Judgements
|
|||||||
Miss = BeatmapDifficulty.DifficultyRange(difficulty, miss_max, miss_mid, miss_min);
|
Miss = BeatmapDifficulty.DifficultyRange(difficulty, miss_max, miss_mid, miss_min);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the hit result for a time offset.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitOffset">The time offset.</param>
|
||||||
|
/// <returns>The hit result, or null if the time offset results in a miss.</returns>
|
||||||
|
public ManiaHitResult? ResultFor(double hitOffset)
|
||||||
|
{
|
||||||
|
if (hitOffset <= Perfect / 2)
|
||||||
|
return ManiaHitResult.Perfect;
|
||||||
|
if (hitOffset <= Great / 2)
|
||||||
|
return ManiaHitResult.Great;
|
||||||
|
if (hitOffset <= Good / 2)
|
||||||
|
return ManiaHitResult.Good;
|
||||||
|
if (hitOffset <= Ok / 2)
|
||||||
|
return ManiaHitResult.Ok;
|
||||||
|
if (hitOffset <= Bad / 2)
|
||||||
|
return ManiaHitResult.Bad;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs new hit windows which have been multiplied by a value.
|
/// Constructs new hit windows which have been multiplied by a value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
21
osu.Game.Rulesets.Mania/Judgements/ManiaHitResult.cs
Normal file
21
osu.Game.Rulesets.Mania/Judgements/ManiaHitResult.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 System.ComponentModel;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Judgements
|
||||||
|
{
|
||||||
|
public enum ManiaHitResult
|
||||||
|
{
|
||||||
|
[Description("PERFECT")]
|
||||||
|
Perfect,
|
||||||
|
[Description("GREAT")]
|
||||||
|
Great,
|
||||||
|
[Description("GOOD")]
|
||||||
|
Good,
|
||||||
|
[Description("OK")]
|
||||||
|
Ok,
|
||||||
|
[Description("BAD")]
|
||||||
|
Bad
|
||||||
|
}
|
||||||
|
}
|
@ -10,5 +10,10 @@ namespace osu.Game.Rulesets.Mania.Judgements
|
|||||||
public override string ResultString => string.Empty;
|
public override string ResultString => string.Empty;
|
||||||
|
|
||||||
public override string MaxResultString => string.Empty;
|
public override string MaxResultString => string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The hit result.
|
||||||
|
/// </summary>
|
||||||
|
public ManiaHitResult ManiaResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ using osu.Game.Rulesets.Objects.Drawables;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using OpenTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||||
{
|
{
|
||||||
@ -14,8 +16,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
private readonly BodyPiece bodyPiece;
|
private readonly BodyPiece bodyPiece;
|
||||||
private readonly NotePiece tailPiece;
|
private readonly NotePiece tailPiece;
|
||||||
|
|
||||||
public DrawableHoldNote(HoldNote hitObject)
|
public DrawableHoldNote(HoldNote hitObject, Bindable<Key> key = null)
|
||||||
: base(hitObject)
|
: base(hitObject, key)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
Height = (float)HitObject.Duration;
|
Height = (float)HitObject.Duration;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// 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.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
using OpenTK.Input;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.Judgements;
|
using osu.Game.Rulesets.Mania.Judgements;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
@ -11,13 +13,21 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
public abstract class DrawableManiaHitObject<TObject> : DrawableHitObject<ManiaHitObject, ManiaJudgement>
|
public abstract class DrawableManiaHitObject<TObject> : DrawableHitObject<ManiaHitObject, ManiaJudgement>
|
||||||
where TObject : ManiaHitObject
|
where TObject : ManiaHitObject
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The key that will trigger input for this hit object.
|
||||||
|
/// </summary>
|
||||||
|
protected Bindable<Key> Key { get; private set; } = new Bindable<Key>();
|
||||||
|
|
||||||
public new TObject HitObject;
|
public new TObject HitObject;
|
||||||
|
|
||||||
protected DrawableManiaHitObject(TObject hitObject)
|
protected DrawableManiaHitObject(TObject hitObject, Bindable<Key> key = null)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
HitObject = hitObject;
|
HitObject = hitObject;
|
||||||
|
|
||||||
|
if (key != null)
|
||||||
|
Key.BindTo(key);
|
||||||
|
|
||||||
RelativePositionAxes = Axes.Y;
|
RelativePositionAxes = Axes.Y;
|
||||||
Y = (float)HitObject.StartTime;
|
Y = (float)HitObject.StartTime;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// 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.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
using OpenTK.Input;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
@ -12,8 +14,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
{
|
{
|
||||||
private readonly NotePiece headPiece;
|
private readonly NotePiece headPiece;
|
||||||
|
|
||||||
public DrawableNote(Note hitObject)
|
public DrawableNote(Note hitObject, Bindable<Key> key = null)
|
||||||
: base(hitObject)
|
: base(hitObject, key)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
Height = 100;
|
Height = 100;
|
||||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Mania.Objects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The key-release hit windows for this hold note.
|
/// The key-release hit windows for this hold note.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected HitWindows ReleaseHitWindows = new HitWindows();
|
public HitWindows ReleaseHitWindows { get; protected set; } = new HitWindows();
|
||||||
|
|
||||||
public override void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty)
|
public override void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty)
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Objects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The key-press hit window for this note.
|
/// The key-press hit window for this note.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected HitWindows HitWindows = new HitWindows();
|
public HitWindows HitWindows { get; protected set; } = new HitWindows();
|
||||||
|
|
||||||
public override void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty)
|
public override void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty)
|
||||||
{
|
{
|
||||||
|
@ -22,5 +22,12 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
|||||||
protected override void OnNewJudgement(ManiaJudgement judgement)
|
protected override void OnNewJudgement(ManiaJudgement judgement)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Reset()
|
||||||
|
{
|
||||||
|
base.Reset();
|
||||||
|
|
||||||
|
Health.Value = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@ using osu.Game.Rulesets.Objects.Drawables;
|
|||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Mania.Judgements;
|
using osu.Game.Rulesets.Mania.Judgements;
|
||||||
using osu.Game.Beatmaps.Timing;
|
using osu.Game.Beatmaps.Timing;
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
{
|
{
|
||||||
@ -33,7 +35,10 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
private const float column_width = 45;
|
private const float column_width = 45;
|
||||||
private const float special_column_width = 70;
|
private const float special_column_width = 70;
|
||||||
|
|
||||||
public Key Key;
|
/// <summary>
|
||||||
|
/// The key that will trigger input actions for this column and hit objects contained inside it.
|
||||||
|
/// </summary>
|
||||||
|
public Bindable<Key> Key = new Bindable<Key>();
|
||||||
|
|
||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
private readonly Container hitTargetBar;
|
private readonly Container hitTargetBar;
|
||||||
@ -95,6 +100,12 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
Name = "Hit objects",
|
Name = "Hit objects",
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
|
// For column lighting, we need to capture input events before the notes
|
||||||
|
new InputTarget
|
||||||
|
{
|
||||||
|
KeyDown = onKeyDown,
|
||||||
|
KeyUp = onKeyUp
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Container
|
new Container
|
||||||
@ -178,12 +189,9 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(DrawableHitObject<ManiaHitObject, ManiaJudgement> hitObject)
|
public void Add(DrawableHitObject<ManiaHitObject, ManiaJudgement> hitObject) => ControlPointContainer.Add(hitObject);
|
||||||
{
|
|
||||||
ControlPointContainer.Add(hitObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
private bool onKeyDown(InputState state, KeyDownEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.Repeat)
|
if (args.Repeat)
|
||||||
return false;
|
return false;
|
||||||
@ -197,7 +205,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnKeyUp(InputState state, KeyUpEventArgs args)
|
private bool onKeyUp(InputState state, KeyUpEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.Key == Key)
|
if (args.Key == Key)
|
||||||
{
|
{
|
||||||
@ -207,5 +215,24 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is a simple container which delegates various input events that have to be captured before the notes.
|
||||||
|
/// </summary>
|
||||||
|
private class InputTarget : Container
|
||||||
|
{
|
||||||
|
public Func<InputState, KeyDownEventArgs, bool> KeyDown;
|
||||||
|
public Func<InputState, KeyUpEventArgs, bool> KeyUp;
|
||||||
|
|
||||||
|
public InputTarget()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
AlwaysPresent = true;
|
||||||
|
Alpha = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) => KeyDown?.Invoke(state, args) ?? false;
|
||||||
|
protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) => KeyUp?.Invoke(state, args) ?? false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
using OpenTK.Input;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.Timing;
|
using osu.Game.Beatmaps.Timing;
|
||||||
@ -76,13 +78,19 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
protected override DrawableHitObject<ManiaHitObject, ManiaJudgement> GetVisualRepresentation(ManiaHitObject h)
|
protected override DrawableHitObject<ManiaHitObject, ManiaJudgement> GetVisualRepresentation(ManiaHitObject h)
|
||||||
{
|
{
|
||||||
|
var maniaPlayfield = Playfield as ManiaPlayfield;
|
||||||
|
if (maniaPlayfield == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
Bindable<Key> key = maniaPlayfield.Columns.ElementAt(h.Column).Key;
|
||||||
|
|
||||||
var holdNote = h as HoldNote;
|
var holdNote = h as HoldNote;
|
||||||
if (holdNote != null)
|
if (holdNote != null)
|
||||||
return new DrawableHoldNote(holdNote);
|
return new DrawableHoldNote(holdNote, key);
|
||||||
|
|
||||||
var note = h as Note;
|
var note = h as Note;
|
||||||
if (note != null)
|
if (note != null)
|
||||||
return new DrawableNote(note);
|
return new DrawableNote(note, key);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly FlowContainer<Column> Columns;
|
private readonly FlowContainer<Column> columns;
|
||||||
|
public IEnumerable<Column> Columns => columns.Children;
|
||||||
|
|
||||||
private readonly ControlPointContainer barlineContainer;
|
private readonly ControlPointContainer barlineContainer;
|
||||||
|
|
||||||
@ -87,7 +88,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = Color4.Black
|
Colour = Color4.Black
|
||||||
},
|
},
|
||||||
Columns = new FillFlowContainer<Column>
|
columns = new FillFlowContainer<Column>
|
||||||
{
|
{
|
||||||
Name = "Columns",
|
Name = "Columns",
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
@ -114,7 +115,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < columnCount; i++)
|
for (int i = 0; i < columnCount; i++)
|
||||||
Columns.Add(new Column(timingChanges));
|
columns.Add(new Column(timingChanges));
|
||||||
|
|
||||||
TimeSpan = time_span_default;
|
TimeSpan = time_span_default;
|
||||||
}
|
}
|
||||||
@ -133,17 +134,17 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
// Set the special column + colour + key
|
// Set the special column + colour + key
|
||||||
for (int i = 0; i < columnCount; i++)
|
for (int i = 0; i < columnCount; i++)
|
||||||
{
|
{
|
||||||
Column column = Columns.Children.ElementAt(i);
|
Column column = Columns.ElementAt(i);
|
||||||
column.IsSpecial = isSpecialColumn(i);
|
column.IsSpecial = isSpecialColumn(i);
|
||||||
|
|
||||||
if (!column.IsSpecial)
|
if (!column.IsSpecial)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
column.Key = Key.Space;
|
column.Key.Value = Key.Space;
|
||||||
column.AccentColour = specialColumnColour;
|
column.AccentColour = specialColumnColour;
|
||||||
}
|
}
|
||||||
|
|
||||||
var nonSpecialColumns = Columns.Children.Where(c => !c.IsSpecial).ToList();
|
var nonSpecialColumns = Columns.Where(c => !c.IsSpecial).ToList();
|
||||||
|
|
||||||
// We'll set the colours of the non-special columns in a separate loop, because the non-special
|
// We'll set the colours of the non-special columns in a separate loop, because the non-special
|
||||||
// column colours are mirrored across their centre and special styles mess with this
|
// column colours are mirrored across their centre and special styles mess with this
|
||||||
@ -162,11 +163,11 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
int keyOffset = default_keys.Length / 2 - nonSpecialColumns.Count / 2 + i;
|
int keyOffset = default_keys.Length / 2 - nonSpecialColumns.Count / 2 + i;
|
||||||
if (keyOffset >= 0 && keyOffset < default_keys.Length)
|
if (keyOffset >= 0 && keyOffset < default_keys.Length)
|
||||||
column.Key = default_keys[keyOffset];
|
column.Key.Value = default_keys[keyOffset];
|
||||||
else
|
else
|
||||||
// There is no default key defined for this column. Let's set this to Unknown for now
|
// There is no default key defined for this column. Let's set this to Unknown for now
|
||||||
// however note that this will be gone after bindings are in place
|
// however note that this will be gone after bindings are in place
|
||||||
column.Key = Key.Unknown;
|
column.Key.Value = Key.Unknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +190,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Add(DrawableHitObject<ManiaHitObject, ManiaJudgement> h) => Columns.Children.ElementAt(h.HitObject.Column).Add(h);
|
public override void Add(DrawableHitObject<ManiaHitObject, ManiaJudgement> h) => Columns.ElementAt(h.HitObject.Column).Add(h);
|
||||||
|
|
||||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||||
{
|
{
|
||||||
@ -225,7 +226,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
timeSpan = MathHelper.Clamp(timeSpan, time_span_min, time_span_max);
|
timeSpan = MathHelper.Clamp(timeSpan, time_span_min, time_span_max);
|
||||||
|
|
||||||
barlineContainer.TimeSpan = value;
|
barlineContainer.TimeSpan = value;
|
||||||
Columns.Children.ForEach(c => c.ControlPointContainer.TimeSpan = value);
|
Columns.ForEach(c => c.ControlPointContainer.TimeSpan = value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
<Compile Include="Beatmaps\Patterns\Pattern.cs" />
|
<Compile Include="Beatmaps\Patterns\Pattern.cs" />
|
||||||
<Compile Include="MathUtils\FastRandom.cs" />
|
<Compile Include="MathUtils\FastRandom.cs" />
|
||||||
<Compile Include="Judgements\HitWindows.cs" />
|
<Compile Include="Judgements\HitWindows.cs" />
|
||||||
|
<Compile Include="Judgements\ManiaHitResult.cs" />
|
||||||
<Compile Include="Judgements\ManiaJudgement.cs" />
|
<Compile Include="Judgements\ManiaJudgement.cs" />
|
||||||
<Compile Include="ManiaDifficultyCalculator.cs" />
|
<Compile Include="ManiaDifficultyCalculator.cs" />
|
||||||
<Compile Include="Objects\Drawables\DrawableHoldNote.cs" />
|
<Compile Include="Objects\Drawables\DrawableHoldNote.cs" />
|
||||||
|
171
osu.Game/Graphics/Containers/SectionsContainer.cs
Normal file
171
osu.Game/Graphics/Containers/SectionsContainer.cs
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
// 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.Configuration;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
|
||||||
|
namespace osu.Game.Graphics.Containers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A container that can scroll to each section inside it.
|
||||||
|
/// </summary>
|
||||||
|
public class SectionsContainer : Container
|
||||||
|
{
|
||||||
|
private Drawable expandableHeader, fixedHeader, footer;
|
||||||
|
public readonly ScrollContainer ScrollContainer;
|
||||||
|
private readonly Container<Drawable> sectionsContainer;
|
||||||
|
|
||||||
|
public Drawable ExpandableHeader
|
||||||
|
{
|
||||||
|
get { return expandableHeader; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == expandableHeader) return;
|
||||||
|
|
||||||
|
if (expandableHeader != null)
|
||||||
|
Remove(expandableHeader);
|
||||||
|
expandableHeader = value;
|
||||||
|
if (value == null) return;
|
||||||
|
|
||||||
|
Add(expandableHeader);
|
||||||
|
lastKnownScroll = float.NaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Drawable FixedHeader
|
||||||
|
{
|
||||||
|
get { return fixedHeader; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == fixedHeader) return;
|
||||||
|
|
||||||
|
if (fixedHeader != null)
|
||||||
|
Remove(fixedHeader);
|
||||||
|
fixedHeader = value;
|
||||||
|
if (value == null) return;
|
||||||
|
|
||||||
|
Add(fixedHeader);
|
||||||
|
lastKnownScroll = float.NaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Drawable Footer
|
||||||
|
{
|
||||||
|
get { return footer; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == footer) return;
|
||||||
|
|
||||||
|
if (footer != null)
|
||||||
|
ScrollContainer.Remove(footer);
|
||||||
|
footer = value;
|
||||||
|
if (value == null) return;
|
||||||
|
|
||||||
|
footer.Anchor |= Anchor.y2;
|
||||||
|
footer.Origin |= Anchor.y2;
|
||||||
|
ScrollContainer.Add(footer);
|
||||||
|
lastKnownScroll = float.NaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bindable<Drawable> SelectedSection { get; } = new Bindable<Drawable>();
|
||||||
|
|
||||||
|
protected virtual Container<Drawable> CreateScrollContentContainer()
|
||||||
|
=> new FillFlowContainer
|
||||||
|
{
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
AutoSizeAxes = Axes.Both
|
||||||
|
};
|
||||||
|
|
||||||
|
private List<Drawable> sections = new List<Drawable>();
|
||||||
|
public IEnumerable<Drawable> Sections
|
||||||
|
{
|
||||||
|
get { return sections; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
foreach (var section in sections)
|
||||||
|
sectionsContainer.Remove(section);
|
||||||
|
|
||||||
|
sections = value.ToList();
|
||||||
|
if (sections.Count == 0) return;
|
||||||
|
|
||||||
|
sectionsContainer.Add(sections);
|
||||||
|
SelectedSection.Value = sections[0];
|
||||||
|
lastKnownScroll = float.NaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private float headerHeight, footerHeight;
|
||||||
|
private readonly MarginPadding originalSectionsMargin;
|
||||||
|
private void updateSectionsMargin()
|
||||||
|
{
|
||||||
|
if (sections.Count == 0) return;
|
||||||
|
|
||||||
|
var newMargin = originalSectionsMargin;
|
||||||
|
newMargin.Top += headerHeight;
|
||||||
|
newMargin.Bottom += footerHeight;
|
||||||
|
|
||||||
|
sectionsContainer.Margin = newMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SectionsContainer()
|
||||||
|
{
|
||||||
|
Add(ScrollContainer = new ScrollContainer()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Masking = false,
|
||||||
|
Children = new Drawable[] { sectionsContainer = CreateScrollContentContainer() }
|
||||||
|
});
|
||||||
|
originalSectionsMargin = sectionsContainer.Margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float lastKnownScroll;
|
||||||
|
protected override void UpdateAfterChildren()
|
||||||
|
{
|
||||||
|
base.UpdateAfterChildren();
|
||||||
|
|
||||||
|
float headerH = (ExpandableHeader?.LayoutSize.Y ?? 0) + (FixedHeader?.LayoutSize.Y ?? 0);
|
||||||
|
float footerH = Footer?.LayoutSize.Y ?? 0;
|
||||||
|
if (headerH != headerHeight || footerH != footerHeight)
|
||||||
|
{
|
||||||
|
headerHeight = headerH;
|
||||||
|
footerHeight = footerH;
|
||||||
|
updateSectionsMargin();
|
||||||
|
}
|
||||||
|
|
||||||
|
float currentScroll = Math.Max(0, ScrollContainer.Current);
|
||||||
|
if (currentScroll != lastKnownScroll)
|
||||||
|
{
|
||||||
|
lastKnownScroll = currentScroll;
|
||||||
|
|
||||||
|
if (expandableHeader != null && fixedHeader != null)
|
||||||
|
{
|
||||||
|
float offset = Math.Min(expandableHeader.LayoutSize.Y, currentScroll);
|
||||||
|
|
||||||
|
expandableHeader.Y = -offset;
|
||||||
|
fixedHeader.Y = -offset + expandableHeader.LayoutSize.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
Drawable bestMatch = null;
|
||||||
|
float minDiff = float.MaxValue;
|
||||||
|
|
||||||
|
foreach (var section in sections)
|
||||||
|
{
|
||||||
|
float diff = Math.Abs(ScrollContainer.GetChildPosInContent(section) - currentScroll);
|
||||||
|
if (diff < minDiff)
|
||||||
|
{
|
||||||
|
minDiff = diff;
|
||||||
|
bestMatch = section;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestMatch != null)
|
||||||
|
SelectedSection.Value = bestMatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,34 +1,16 @@
|
|||||||
// 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.Allocation;
|
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.Sprites;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
using OpenTK.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings
|
namespace osu.Game.Overlays.Settings
|
||||||
{
|
{
|
||||||
public class SettingsHeader : Container
|
public class SettingsHeader : Container
|
||||||
{
|
{
|
||||||
public SearchTextBox SearchTextBox;
|
|
||||||
|
|
||||||
private Box background;
|
|
||||||
|
|
||||||
private readonly Func<float> currentScrollOffset;
|
|
||||||
|
|
||||||
public Action Exit;
|
|
||||||
|
|
||||||
/// <param name="currentScrollOffset">A reference to the current scroll position of the ScrollContainer we are contained within.</param>
|
|
||||||
public SettingsHeader(Func<float> currentScrollOffset)
|
|
||||||
{
|
|
||||||
this.currentScrollOffset = currentScrollOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
@ -37,11 +19,6 @@ namespace osu.Game.Overlays.Settings
|
|||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
background = new Box
|
|
||||||
{
|
|
||||||
Colour = Color4.Black,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
},
|
|
||||||
new FillFlowContainer
|
new FillFlowContainer
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
@ -53,7 +30,8 @@ namespace osu.Game.Overlays.Settings
|
|||||||
{
|
{
|
||||||
Text = "settings",
|
Text = "settings",
|
||||||
TextSize = 40,
|
TextSize = 40,
|
||||||
Margin = new MarginPadding {
|
Margin = new MarginPadding
|
||||||
|
{
|
||||||
Left = SettingsOverlay.CONTENT_MARGINS,
|
Left = SettingsOverlay.CONTENT_MARGINS,
|
||||||
Top = Toolbar.Toolbar.TOOLTIP_HEIGHT
|
Top = Toolbar.Toolbar.TOOLTIP_HEIGHT
|
||||||
},
|
},
|
||||||
@ -63,45 +41,15 @@ namespace osu.Game.Overlays.Settings
|
|||||||
Colour = colours.Pink,
|
Colour = colours.Pink,
|
||||||
Text = "Change the way osu! behaves",
|
Text = "Change the way osu! behaves",
|
||||||
TextSize = 18,
|
TextSize = 18,
|
||||||
Margin = new MarginPadding {
|
Margin = new MarginPadding
|
||||||
|
{
|
||||||
Left = SettingsOverlay.CONTENT_MARGINS,
|
Left = SettingsOverlay.CONTENT_MARGINS,
|
||||||
Bottom = 30
|
Bottom = 30
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
SearchTextBox = new SearchTextBox
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Width = 0.95f,
|
|
||||||
Margin = new MarginPadding {
|
|
||||||
Top = 20,
|
|
||||||
Bottom = 20
|
|
||||||
},
|
|
||||||
Exit = () => Exit(),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateAfterChildren()
|
|
||||||
{
|
|
||||||
base.UpdateAfterChildren();
|
|
||||||
|
|
||||||
// the point at which we will start anchoring to the top.
|
|
||||||
float anchorOffset = SearchTextBox.Y;
|
|
||||||
|
|
||||||
float scrollPosition = currentScrollOffset();
|
|
||||||
|
|
||||||
// we want to anchor the search field to the top of the screen when scrolling.
|
|
||||||
Margin = new MarginPadding { Top = Math.Max(0, scrollPosition - anchorOffset) };
|
|
||||||
|
|
||||||
// we don't want the header to scroll when scrolling beyond the upper extent.
|
|
||||||
Y = Math.Min(0, scrollPosition);
|
|
||||||
|
|
||||||
// we get darker as scroll progresses
|
|
||||||
background.Alpha = Math.Min(1, scrollPosition / anchorOffset) * 0.5f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
private readonly Box backgroundBox;
|
private readonly Box backgroundBox;
|
||||||
private readonly Box selectionIndicator;
|
private readonly Box selectionIndicator;
|
||||||
private readonly Container text;
|
private readonly Container text;
|
||||||
public Action Action;
|
public Action<SettingsSection> Action;
|
||||||
|
|
||||||
private SettingsSection section;
|
private SettingsSection section;
|
||||||
public SettingsSection Section
|
public SettingsSection Section
|
||||||
@ -75,6 +75,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
{
|
{
|
||||||
Width = Sidebar.DEFAULT_WIDTH,
|
Width = Sidebar.DEFAULT_WIDTH,
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Colour = OsuColour.Gray(0.6f),
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
headerText = new OsuSpriteText
|
headerText = new OsuSpriteText
|
||||||
@ -110,7 +111,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
|
|
||||||
protected override bool OnClick(InputState state)
|
protected override bool OnClick(InputState state)
|
||||||
{
|
{
|
||||||
Action?.Invoke();
|
Action?.Invoke(section);
|
||||||
backgroundBox.FlashColour(Color4.White, 400);
|
backgroundBox.FlashColour(Color4.White, 400);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,11 @@ 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.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Overlays.Settings;
|
|
||||||
using System;
|
|
||||||
using osu.Game.Overlays.Settings.Sections;
|
|
||||||
using osu.Framework.Input;
|
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
|
namespace osu.Game.Overlays
|
||||||
{
|
{
|
||||||
@ -26,18 +27,13 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
private const float sidebar_padding = 10;
|
private const float sidebar_padding = 10;
|
||||||
|
|
||||||
private ScrollContainer scrollContainer;
|
|
||||||
private Sidebar sidebar;
|
private Sidebar sidebar;
|
||||||
private SidebarButton[] sidebarButtons;
|
private SidebarButton[] sidebarButtons;
|
||||||
private SettingsSection[] sections;
|
private SidebarButton selectedSidebarButton;
|
||||||
|
|
||||||
private SettingsHeader header;
|
private SettingsSectionsContainer sectionsContainer;
|
||||||
|
|
||||||
private SettingsFooter footer;
|
private SearchTextBox searchTextBox;
|
||||||
|
|
||||||
private SearchContainer searchContainer;
|
|
||||||
|
|
||||||
private float lastKnownScroll;
|
|
||||||
|
|
||||||
public SettingsOverlay()
|
public SettingsOverlay()
|
||||||
{
|
{
|
||||||
@ -48,7 +44,7 @@ namespace osu.Game.Overlays
|
|||||||
[BackgroundDependencyLoader(permitNulls: true)]
|
[BackgroundDependencyLoader(permitNulls: true)]
|
||||||
private void load(OsuGame game)
|
private void load(OsuGame game)
|
||||||
{
|
{
|
||||||
sections = new SettingsSection[]
|
var sections = new SettingsSection[]
|
||||||
{
|
{
|
||||||
new GeneralSection(),
|
new GeneralSection(),
|
||||||
new GraphicsSection(),
|
new GraphicsSection(),
|
||||||
@ -68,27 +64,27 @@ namespace osu.Game.Overlays
|
|||||||
Colour = Color4.Black,
|
Colour = Color4.Black,
|
||||||
Alpha = 0.6f,
|
Alpha = 0.6f,
|
||||||
},
|
},
|
||||||
scrollContainer = new ScrollContainer
|
sectionsContainer = new SettingsSectionsContainer
|
||||||
{
|
{
|
||||||
ScrollDraggerVisible = false,
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
Width = width,
|
Width = width,
|
||||||
Margin = new MarginPadding { Left = SIDEBAR_WIDTH },
|
Margin = new MarginPadding { Left = SIDEBAR_WIDTH },
|
||||||
Children = new Drawable[]
|
ExpandableHeader = new SettingsHeader(),
|
||||||
|
FixedHeader = searchTextBox = new SearchTextBox
|
||||||
{
|
{
|
||||||
searchContainer = new SearchContainer
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Width = 0.95f,
|
||||||
|
Margin = new MarginPadding
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Y,
|
Top = 20,
|
||||||
RelativeSizeAxes = Axes.X,
|
Bottom = 20
|
||||||
Direction = FillDirection.Vertical,
|
|
||||||
Children = sections,
|
|
||||||
},
|
},
|
||||||
footer = new SettingsFooter(),
|
Exit = Hide,
|
||||||
header = new SettingsHeader(() => scrollContainer.Current)
|
},
|
||||||
{
|
Sections = sections,
|
||||||
Exit = Hide,
|
Footer = new SettingsFooter()
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
sidebar = new Sidebar
|
sidebar = new Sidebar
|
||||||
{
|
{
|
||||||
@ -96,84 +92,89 @@ namespace osu.Game.Overlays
|
|||||||
Children = sidebarButtons = sections.Select(section =>
|
Children = sidebarButtons = sections.Select(section =>
|
||||||
new SidebarButton
|
new SidebarButton
|
||||||
{
|
{
|
||||||
Selected = sections[0] == section,
|
|
||||||
Section = section,
|
Section = section,
|
||||||
Action = () => scrollContainer.ScrollIntoView(section),
|
Action = sectionsContainer.ScrollContainer.ScrollIntoView,
|
||||||
}
|
}
|
||||||
).ToArray()
|
).ToArray()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
header.SearchTextBox.Current.ValueChanged += newValue => searchContainer.SearchTerm = newValue;
|
selectedSidebarButton = sidebarButtons[0];
|
||||||
|
selectedSidebarButton.Selected = true;
|
||||||
|
|
||||||
scrollContainer.Padding = new MarginPadding { Top = game?.Toolbar.DrawHeight ?? 0 };
|
sectionsContainer.SelectedSection.ValueChanged += section =>
|
||||||
}
|
|
||||||
|
|
||||||
protected override void UpdateAfterChildren()
|
|
||||||
{
|
|
||||||
base.UpdateAfterChildren();
|
|
||||||
|
|
||||||
//we need to update these manually because we can't put the SettingsHeader inside the SearchContainer (due to its anchoring).
|
|
||||||
searchContainer.Y = header.DrawHeight;
|
|
||||||
footer.Y = searchContainer.Y + searchContainer.DrawHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
base.Update();
|
|
||||||
|
|
||||||
float currentScroll = scrollContainer.Current;
|
|
||||||
if (currentScroll != lastKnownScroll)
|
|
||||||
{
|
{
|
||||||
lastKnownScroll = currentScroll;
|
selectedSidebarButton.Selected = false;
|
||||||
|
selectedSidebarButton = sidebarButtons.Single(b => b.Section == section);
|
||||||
|
selectedSidebarButton.Selected = true;
|
||||||
|
};
|
||||||
|
|
||||||
SettingsSection bestCandidate = null;
|
searchTextBox.Current.ValueChanged += newValue => sectionsContainer.SearchContainer.SearchTerm = newValue;
|
||||||
float bestDistance = float.MaxValue;
|
|
||||||
|
|
||||||
foreach (SettingsSection section in sections)
|
sectionsContainer.Padding = new MarginPadding { Top = game?.Toolbar.DrawHeight ?? 0 };
|
||||||
{
|
|
||||||
float distance = Math.Abs(scrollContainer.GetChildPosInContent(section) - currentScroll);
|
|
||||||
if (distance < bestDistance)
|
|
||||||
{
|
|
||||||
bestDistance = distance;
|
|
||||||
bestCandidate = section;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var previous = sidebarButtons.SingleOrDefault(sb => sb.Selected);
|
|
||||||
var next = sidebarButtons.SingleOrDefault(sb => sb.Section == bestCandidate);
|
|
||||||
if (previous != null) previous.Selected = false;
|
|
||||||
if (next != null) next.Selected = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
{
|
{
|
||||||
base.PopIn();
|
base.PopIn();
|
||||||
|
|
||||||
scrollContainer.MoveToX(0, TRANSITION_LENGTH, EasingTypes.OutQuint);
|
sectionsContainer.MoveToX(0, TRANSITION_LENGTH, EasingTypes.OutQuint);
|
||||||
sidebar.MoveToX(0, TRANSITION_LENGTH, EasingTypes.OutQuint);
|
sidebar.MoveToX(0, TRANSITION_LENGTH, EasingTypes.OutQuint);
|
||||||
FadeTo(1, TRANSITION_LENGTH / 2);
|
FadeTo(1, TRANSITION_LENGTH / 2);
|
||||||
|
|
||||||
header.SearchTextBox.HoldFocus = true;
|
searchTextBox.HoldFocus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopOut()
|
protected override void PopOut()
|
||||||
{
|
{
|
||||||
base.PopOut();
|
base.PopOut();
|
||||||
|
|
||||||
scrollContainer.MoveToX(-width, TRANSITION_LENGTH, EasingTypes.OutQuint);
|
sectionsContainer.MoveToX(-width, TRANSITION_LENGTH, EasingTypes.OutQuint);
|
||||||
sidebar.MoveToX(-SIDEBAR_WIDTH, TRANSITION_LENGTH, EasingTypes.OutQuint);
|
sidebar.MoveToX(-SIDEBAR_WIDTH, TRANSITION_LENGTH, EasingTypes.OutQuint);
|
||||||
FadeTo(0, TRANSITION_LENGTH / 2);
|
FadeTo(0, TRANSITION_LENGTH / 2);
|
||||||
|
|
||||||
header.SearchTextBox.HoldFocus = false;
|
searchTextBox.HoldFocus = false;
|
||||||
header.SearchTextBox.TriggerFocusLost();
|
searchTextBox.TriggerFocusLost();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnFocus(InputState state)
|
protected override bool OnFocus(InputState state)
|
||||||
{
|
{
|
||||||
header.SearchTextBox.TriggerFocus(state);
|
searchTextBox.TriggerFocus(state);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class SettingsSectionsContainer : SectionsContainer
|
||||||
|
{
|
||||||
|
public SearchContainer SearchContainer;
|
||||||
|
private readonly Box headerBackground;
|
||||||
|
|
||||||
|
protected override Container<Drawable> CreateScrollContentContainer()
|
||||||
|
=> SearchContainer = new SearchContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
};
|
||||||
|
|
||||||
|
public SettingsSectionsContainer()
|
||||||
|
{
|
||||||
|
ScrollContainer.ScrollDraggerVisible = false;
|
||||||
|
Add(headerBackground = new Box
|
||||||
|
{
|
||||||
|
Colour = Color4.Black,
|
||||||
|
RelativeSizeAxes = Axes.X
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void UpdateAfterChildren()
|
||||||
|
{
|
||||||
|
base.UpdateAfterChildren();
|
||||||
|
|
||||||
|
// no null check because the usage of this class is strict
|
||||||
|
headerBackground.Height = ExpandableHeader.LayoutSize.Y + FixedHeader.LayoutSize.Y;
|
||||||
|
headerBackground.Y = ExpandableHeader.Y;
|
||||||
|
headerBackground.Alpha = -ExpandableHeader.Y / ExpandableHeader.LayoutSize.Y * 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,7 @@
|
|||||||
<Compile Include="Overlays\Music\PlaylistItem.cs" />
|
<Compile Include="Overlays\Music\PlaylistItem.cs" />
|
||||||
<Compile Include="Overlays\Music\PlaylistList.cs" />
|
<Compile Include="Overlays\Music\PlaylistList.cs" />
|
||||||
<Compile Include="Overlays\OnScreenDisplay.cs" />
|
<Compile Include="Overlays\OnScreenDisplay.cs" />
|
||||||
|
<Compile Include="Graphics\Containers\SectionsContainer.cs" />
|
||||||
<Compile Include="Overlays\Settings\SettingsHeader.cs" />
|
<Compile Include="Overlays\Settings\SettingsHeader.cs" />
|
||||||
<Compile Include="Overlays\Settings\Sections\Audio\MainMenuSettings.cs" />
|
<Compile Include="Overlays\Settings\Sections\Audio\MainMenuSettings.cs" />
|
||||||
<Compile Include="Overlays\Toolbar\ToolbarChatButton.cs" />
|
<Compile Include="Overlays\Toolbar\ToolbarChatButton.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user