mirror of
https://github.com/osukey/osukey.git
synced 2025-05-29 01:17:35 +09:00
Move value change logic to bindable
Also add drag support
This commit is contained in:
parent
786e6242e1
commit
6fd650777c
@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Screens.Edit.Screens.Compose;
|
using osu.Game.Screens.Edit.Screens.Compose;
|
||||||
@ -10,6 +12,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
public class TestCaseDrawableBeatDivisor : OsuTestCase
|
public class TestCaseDrawableBeatDivisor : OsuTestCase
|
||||||
{
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(BindableBeatDivisor) };
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -1,15 +1,55 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 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.Linq;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Screens.Compose
|
namespace osu.Game.Screens.Edit.Screens.Compose
|
||||||
{
|
{
|
||||||
public class BindableBeatDivisor : Bindable<int>
|
public class BindableBeatDivisor : BindableNumber<int>
|
||||||
{
|
{
|
||||||
|
public static readonly int[] VALID_DIVISORS = { 1, 2, 3, 4, 6, 8, 12, 16 };
|
||||||
|
|
||||||
public BindableBeatDivisor(int value = 1)
|
public BindableBeatDivisor(int value = 1)
|
||||||
: base(value)
|
: base(value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Next() => Value = VALID_DIVISORS[Math.Min(VALID_DIVISORS.Length - 1, Array.IndexOf(VALID_DIVISORS, Value) + 1)];
|
||||||
|
|
||||||
|
public void Previous() => Value = VALID_DIVISORS[Math.Max(0, Array.IndexOf(VALID_DIVISORS, Value) - 1)];
|
||||||
|
|
||||||
|
public override int Value
|
||||||
|
{
|
||||||
|
get { return base.Value; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
int snapped = 1;
|
||||||
|
|
||||||
|
for (int i = 1; i < VALID_DIVISORS.Length; i++)
|
||||||
|
{
|
||||||
|
var curr = VALID_DIVISORS[i];
|
||||||
|
var prev = VALID_DIVISORS[i - 1];
|
||||||
|
if (value < prev + (curr - prev) / 2f)
|
||||||
|
{
|
||||||
|
snapped = prev;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
snapped = curr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snapped == Value)
|
||||||
|
// it may be that we are already at the snapped value, but we want bound components to still be made aware that we possibly modified an incoming ValueChanged.
|
||||||
|
TriggerValueChange();
|
||||||
|
else
|
||||||
|
base.Value = snapped;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override int DefaultMinValue => VALID_DIVISORS.First();
|
||||||
|
protected override int DefaultMaxValue => VALID_DIVISORS.Last();
|
||||||
|
protected override int DefaultPrecision => 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 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.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
@ -17,10 +18,9 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
|||||||
{
|
{
|
||||||
public class DrawableBeatDivisor : CompositeDrawable
|
public class DrawableBeatDivisor : CompositeDrawable
|
||||||
{
|
{
|
||||||
private static readonly int[] available_divisors = { 1, 2, 3, 4, 6, 8, 12, 16 };
|
|
||||||
|
|
||||||
private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor();
|
private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor();
|
||||||
private int currentDivisorIndex;
|
private int currentDivisorIndex;
|
||||||
|
private TickSliderBar slider;
|
||||||
|
|
||||||
public DrawableBeatDivisor(BindableBeatDivisor beatDivisor)
|
public DrawableBeatDivisor(BindableBeatDivisor beatDivisor)
|
||||||
{
|
{
|
||||||
@ -48,7 +48,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
|||||||
{
|
{
|
||||||
new Drawable[]
|
new Drawable[]
|
||||||
{
|
{
|
||||||
new TickContainer(beatDivisor, 1, 2, 3, 4, 6, 8, 12, 16)
|
slider = new TickSliderBar(beatDivisor, 1, 2, 3, 4, 6, 8, 12, 16)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Padding = new MarginPadding { Horizontal = 5 }
|
Padding = new MarginPadding { Horizontal = 5 }
|
||||||
@ -80,13 +80,13 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
|||||||
new DivisorButton
|
new DivisorButton
|
||||||
{
|
{
|
||||||
Icon = FontAwesome.fa_chevron_left,
|
Icon = FontAwesome.fa_chevron_left,
|
||||||
Action = selectPrevious
|
Action = beatDivisor.Previous
|
||||||
},
|
},
|
||||||
new DivisorText(beatDivisor),
|
new DivisorText(beatDivisor),
|
||||||
new DivisorButton
|
new DivisorButton
|
||||||
{
|
{
|
||||||
Icon = FontAwesome.fa_chevron_right,
|
Icon = FontAwesome.fa_chevron_right,
|
||||||
Action = selectNext
|
Action = beatDivisor.Next
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Drawable[]
|
new Drawable[]
|
||||||
@ -118,20 +118,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
private void selectPrevious()
|
slider.Current.BindTo(beatDivisor);
|
||||||
{
|
|
||||||
if (currentDivisorIndex == 0)
|
|
||||||
return;
|
|
||||||
beatDivisor.Value = available_divisors[--currentDivisorIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectNext()
|
|
||||||
{
|
|
||||||
if (currentDivisorIndex == available_divisors.Length - 1)
|
|
||||||
return;
|
|
||||||
beatDivisor.Value = available_divisors[++currentDivisorIndex];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DivisorText : SpriteText
|
private class DivisorText : SpriteText
|
||||||
@ -186,61 +174,46 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TickContainer : CompositeDrawable
|
private class TickSliderBar : SliderBar<int>
|
||||||
{
|
{
|
||||||
private readonly Bindable<int> beatDivisor = new Bindable<int>();
|
public new MarginPadding Padding
|
||||||
|
{
|
||||||
|
set => base.Padding = value;
|
||||||
|
}
|
||||||
|
|
||||||
public new MarginPadding Padding { set => base.Padding = value; }
|
private Drawable marker;
|
||||||
|
|
||||||
private EquilateralTriangle marker;
|
|
||||||
|
|
||||||
private readonly int[] availableDivisors;
|
private readonly int[] availableDivisors;
|
||||||
private readonly float tickSpacing;
|
|
||||||
|
|
||||||
public TickContainer(BindableBeatDivisor beatDivisor, params int[] divisors)
|
public TickSliderBar(params int[] divisors)
|
||||||
{
|
{
|
||||||
this.beatDivisor.BindTo(beatDivisor);
|
|
||||||
|
|
||||||
availableDivisors = divisors;
|
availableDivisors = divisors;
|
||||||
tickSpacing = 1f / (availableDivisors.Length + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load()
|
||||||
{
|
{
|
||||||
InternalChild = marker = new EquilateralTriangle
|
InternalChild = marker = new Marker();
|
||||||
{
|
|
||||||
Anchor = Anchor.BottomLeft,
|
|
||||||
Origin = Anchor.BottomCentre,
|
|
||||||
RelativePositionAxes = Axes.X,
|
|
||||||
Height = 7,
|
|
||||||
EdgeSmoothness = new Vector2(1),
|
|
||||||
Colour = colours.Gray4,
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < availableDivisors.Length; i++)
|
foreach (var t in availableDivisors)
|
||||||
{
|
{
|
||||||
AddInternal(new Tick(availableDivisors[i])
|
AddInternal(new Tick(t)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopLeft,
|
Anchor = Anchor.TopLeft,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
RelativePositionAxes = Axes.X,
|
RelativePositionAxes = Axes.X,
|
||||||
X = getTickPosition(i)
|
X = getTickPosition(t)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CurrentNumber.ValueChanged += v => marker.MoveToX(getTickPosition(v), 100, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void UpdateValue(float value)
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
beatDivisor.ValueChanged += v => updatePosition();
|
|
||||||
updatePosition();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updatePosition() => marker.MoveToX(getTickPosition(Array.IndexOf(availableDivisors, beatDivisor.Value)), 100, Easing.OutQuint);
|
private float getTickPosition(float divisor) => (divisor - 1) / availableDivisors.Last();
|
||||||
|
|
||||||
private float getTickPosition(int index) => (index + 1) * tickSpacing;
|
|
||||||
|
|
||||||
private class Tick : Box
|
private class Tick : Box
|
||||||
{
|
{
|
||||||
@ -249,7 +222,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
|||||||
public Tick(int divisor)
|
public Tick(int divisor)
|
||||||
{
|
{
|
||||||
this.divisor = divisor;
|
this.divisor = divisor;
|
||||||
|
|
||||||
Size = new Vector2(2, 10);
|
Size = new Vector2(2, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,6 +236,44 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
|||||||
Colour = colours.Gray4;
|
Colour = colours.Gray4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class Marker : CompositeDrawable
|
||||||
|
{
|
||||||
|
private const float size = 7;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
Colour = colours.Gray4;
|
||||||
|
Anchor = Anchor.TopLeft;
|
||||||
|
Origin = Anchor.TopCentre;
|
||||||
|
|
||||||
|
Width = size;
|
||||||
|
RelativeSizeAxes = Axes.Y;
|
||||||
|
RelativePositionAxes = Axes.X;
|
||||||
|
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Width = 1,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
|
Anchor = Anchor.BottomCentre,
|
||||||
|
Colour = Color4.White,
|
||||||
|
},
|
||||||
|
new EquilateralTriangle
|
||||||
|
{
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
|
Anchor = Anchor.BottomCentre,
|
||||||
|
Height = size,
|
||||||
|
EdgeSmoothness = new Vector2(1),
|
||||||
|
Colour = Color4.White,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user