2019-10-18 16:59:54 +08:00
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
2021-04-19 17:25:30 +08:00
using System ;
2019-10-18 16:59:54 +08:00
using System.Linq ;
using osu.Framework.Allocation ;
using osu.Framework.Bindables ;
using osu.Framework.Graphics ;
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
using osu.Framework.Graphics.Colour ;
2019-10-18 16:59:54 +08:00
using osu.Framework.Graphics.Containers ;
2024-06-21 16:54:40 +08:00
using osu.Framework.Graphics.Pooling ;
using osu.Framework.Graphics.Shapes ;
using osu.Framework.Graphics.UserInterface ;
using osu.Framework.Input.Events ;
using osu.Framework.Localisation ;
2019-10-18 16:59:54 +08:00
using osu.Game.Beatmaps.ControlPoints ;
2020-09-30 11:45:43 +08:00
using osu.Game.Extensions ;
2019-10-18 16:59:54 +08:00
using osu.Game.Graphics ;
2024-06-21 16:54:40 +08:00
using osu.Game.Graphics.Containers ;
2019-10-18 16:59:54 +08:00
using osu.Game.Graphics.Sprites ;
2024-06-21 16:54:40 +08:00
using osu.Game.Overlays ;
2021-04-19 14:06:07 +08:00
using osu.Game.Screens.Edit.Timing.RowAttributes ;
2019-10-18 16:59:54 +08:00
using osuTK ;
namespace osu.Game.Screens.Edit.Timing
{
2024-06-21 16:54:40 +08:00
public partial class ControlPointTable : CompositeDrawable
2019-10-18 16:59:54 +08:00
{
2024-06-21 16:54:40 +08:00
public BindableList < ControlPointGroup > Groups { get ; } = new BindableList < ControlPointGroup > ( ) ;
2019-10-18 16:59:54 +08:00
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
[Cached]
private Bindable < TimingControlPoint ? > activeTimingPoint { get ; } = new Bindable < TimingControlPoint ? > ( ) ;
[Cached]
private Bindable < EffectControlPoint ? > activeEffectPoint { get ; } = new Bindable < EffectControlPoint ? > ( ) ;
[Resolved]
private EditorBeatmap beatmap { get ; set ; } = null ! ;
[Resolved]
private Bindable < ControlPointGroup ? > selectedGroup { get ; set ; } = null ! ;
[Resolved]
private EditorClock editorClock { get ; set ; } = null ! ;
2024-06-21 16:54:40 +08:00
private const float timing_column_width = 300 ;
private const float row_height = 25 ;
private const float row_horizontal_padding = 20 ;
2021-04-13 22:26:19 +08:00
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
private ControlPointRowList list = null ! ;
2024-06-21 16:54:40 +08:00
[BackgroundDependencyLoader]
private void load ( OverlayColourProvider colours )
2019-10-18 16:59:54 +08:00
{
2024-06-21 16:54:40 +08:00
RelativeSizeAxes = Axes . Both ;
2024-09-07 22:23:23 +08:00
Padding = new MarginPadding { Bottom = 50 } ;
2019-10-18 16:59:54 +08:00
2024-06-21 16:54:40 +08:00
InternalChildren = new Drawable [ ]
{
new Box
{
Colour = colours . Background4 ,
RelativeSizeAxes = Axes . Both ,
} ,
new Box
2019-10-18 16:59:54 +08:00
{
2024-06-21 16:54:40 +08:00
Colour = colours . Background3 ,
RelativeSizeAxes = Axes . Y ,
Width = timing_column_width + 10 ,
} ,
new Container
{
RelativeSizeAxes = Axes . X ,
Height = row_height ,
Padding = new MarginPadding { Horizontal = row_horizontal_padding } ,
Children = new Drawable [ ]
2021-04-13 22:26:19 +08:00
{
2024-06-21 16:54:40 +08:00
new TableHeaderText ( "Time" )
{
Anchor = Anchor . CentreLeft ,
Origin = Anchor . CentreLeft ,
} ,
new TableHeaderText ( "Attributes" )
2021-04-13 22:26:19 +08:00
{
2024-06-21 16:54:40 +08:00
Anchor = Anchor . CentreLeft ,
Origin = Anchor . CentreLeft ,
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
Margin = new MarginPadding { Left = timing_column_width }
2024-06-21 16:54:40 +08:00
} ,
}
} ,
new Container
{
RelativeSizeAxes = Axes . Both ,
Padding = new MarginPadding { Top = row_height } ,
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
Child = list = new ControlPointRowList
2024-06-21 16:54:40 +08:00
{
RelativeSizeAxes = Axes . Both ,
RowData = { BindTarget = Groups , } ,
} ,
} ,
} ;
}
2019-10-18 16:59:54 +08:00
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
protected override void LoadComplete ( )
2024-06-21 16:54:40 +08:00
{
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
base . LoadComplete ( ) ;
selectedGroup . BindValueChanged ( _ = > scrollToMostRelevantRow ( force : true ) , true ) ;
}
protected override void Update ( )
{
base . Update ( ) ;
scrollToMostRelevantRow ( force : false ) ;
}
private void scrollToMostRelevantRow ( bool force )
{
double accurateTime = editorClock . CurrentTimeAccurate ;
activeTimingPoint . Value = beatmap . ControlPointInfo . TimingPointAt ( accurateTime ) ;
activeEffectPoint . Value = beatmap . ControlPointInfo . EffectPointAt ( accurateTime ) ;
double latestActiveTime = Math . Max ( activeTimingPoint . Value ? . Time ? ? double . NegativeInfinity , activeEffectPoint . Value ? . Time ? ? double . NegativeInfinity ) ;
var groupToShow = selectedGroup . Value ? ? beatmap . ControlPointInfo . GroupAt ( latestActiveTime ) ;
list . ScrollTo ( groupToShow , force ) ;
}
2024-06-21 16:54:40 +08:00
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
private partial class ControlPointRowList : VirtualisedListContainer < ControlPointGroup , DrawableControlGroup >
{
2024-06-21 16:54:40 +08:00
public ControlPointRowList ( )
: base ( row_height , 50 )
{
}
2022-06-21 11:53:06 +08:00
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
protected override ScrollContainer < Drawable > CreateScrollContainer ( ) = > new UserTrackingScrollContainer ( ) ;
2023-12-26 20:20:18 +08:00
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
protected new UserTrackingScrollContainer Scroll = > ( UserTrackingScrollContainer ) base . Scroll ;
public void ScrollTo ( ControlPointGroup group , bool force )
2024-06-21 16:54:40 +08:00
{
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
if ( Scroll . UserScrolling & & ! force )
return ;
2023-12-26 20:20:18 +08:00
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
// can't use `.ScrollIntoView()` here because of the list virtualisation not giving
// child items valid coordinates from the start, so ballpark something similar
// using estimated row height.
var row = Items . FlowingChildren . SingleOrDefault ( item = > item . Row . Equals ( group ) ) ;
2024-07-16 17:20:33 +08:00
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
if ( row = = null )
return ;
2024-06-27 15:46:35 +08:00
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
float minPos = row . Y ;
float maxPos = minPos + row_height ;
2024-06-27 15:46:35 +08:00
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
if ( minPos < Scroll . Current )
Scroll . ScrollTo ( minPos ) ;
else if ( maxPos > Scroll . Current + Scroll . DisplayableContent )
Scroll . ScrollTo ( maxPos - Scroll . DisplayableContent ) ;
2019-10-18 16:59:54 +08:00
}
}
2024-06-21 16:54:40 +08:00
public partial class DrawableControlGroup : PoolableDrawable , IHasCurrentValue < ControlPointGroup >
2021-04-13 22:26:19 +08:00
{
2024-06-21 16:54:40 +08:00
public Bindable < ControlPointGroup > Current
{
get = > current . Current ;
set = > current . Current = value ;
}
2021-04-13 22:26:19 +08:00
2024-06-21 16:54:40 +08:00
private readonly BindableWithCurrent < ControlPointGroup > current = new BindableWithCurrent < ControlPointGroup > ( ) ;
2023-12-26 20:20:18 +08:00
2024-06-21 16:54:40 +08:00
private Box background = null ! ;
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
private Box currentIndicator = null ! ;
2023-12-26 20:20:18 +08:00
2024-06-21 16:54:40 +08:00
[Resolved]
private OverlayColourProvider colourProvider { get ; set ; } = null ! ;
2021-04-13 22:26:19 +08:00
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
[Resolved]
private OsuColour colours { get ; set ; } = null ! ;
2024-06-21 16:54:40 +08:00
[Resolved]
private Bindable < ControlPointGroup ? > selectedGroup { get ; set ; } = null ! ;
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
[Resolved]
private Bindable < TimingControlPoint ? > activeTimingPoint { get ; set ; } = null ! ;
[Resolved]
private Bindable < EffectControlPoint ? > activeEffectPoint { get ; set ; } = null ! ;
2024-06-21 16:54:40 +08:00
[Resolved]
private EditorClock editorClock { get ; set ; } = null ! ;
[BackgroundDependencyLoader]
private void load ( )
2019-10-18 16:59:54 +08:00
{
2024-06-21 16:54:40 +08:00
RelativeSizeAxes = Axes . Both ;
2019-10-18 16:59:54 +08:00
2024-06-21 16:54:40 +08:00
InternalChildren = new Drawable [ ]
{
background = new Box
{
RelativeSizeAxes = Axes . Both ,
Colour = colourProvider . Background1 ,
Alpha = 0 ,
} ,
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
currentIndicator = new Box
{
RelativeSizeAxes = Axes . Y ,
Width = 5 ,
Alpha = 0 ,
} ,
2024-06-21 16:54:40 +08:00
new Container
{
RelativeSizeAxes = Axes . Both ,
Padding = new MarginPadding { Horizontal = row_horizontal_padding , } ,
Children = new Drawable [ ]
{
new ControlGroupTiming { Group = { BindTarget = current } , } ,
new ControlGroupAttributes ( point = > point is not TimingControlPoint )
{
Group = { BindTarget = current } ,
Margin = new MarginPadding { Left = timing_column_width }
}
}
}
} ;
}
2019-10-18 16:59:54 +08:00
2024-06-21 16:54:40 +08:00
protected override void LoadComplete ( )
2019-10-18 16:59:54 +08:00
{
2024-06-21 16:54:40 +08:00
base . LoadComplete ( ) ;
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
selectedGroup . BindValueChanged ( _ = > updateState ( ) ) ;
activeEffectPoint . BindValueChanged ( _ = > updateState ( ) ) ;
activeTimingPoint . BindValueChanged ( _ = > updateState ( ) , true ) ;
2024-06-21 16:54:40 +08:00
FinishTransforms ( true ) ;
}
protected override void PrepareForUse ( )
{
base . PrepareForUse ( ) ;
updateState ( ) ;
}
protected override bool OnHover ( HoverEvent e )
{
updateState ( ) ;
return true ;
}
protected override void OnHoverLost ( HoverLostEvent e )
{
base . OnHoverLost ( e ) ;
updateState ( ) ;
}
protected override bool OnClick ( ClickEvent e )
{
// schedule to give time for any modified focused text box to lose focus and commit changes (e.g. BPM / time signature textboxes) before switching to new point.
var currentGroup = Current . Value ;
Schedule ( ( ) = >
{
selectedGroup . Value = currentGroup ;
editorClock . SeekSmoothlyTo ( currentGroup . Time ) ;
} ) ;
return true ;
}
private void updateState ( )
{
bool isSelected = selectedGroup . Value ? . Equals ( current . Value ) = = true ;
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
bool hasCurrentTimingPoint = activeTimingPoint . Value ! = null & & current . Value . ControlPoints . Contains ( activeTimingPoint . Value ) ;
bool hasCurrentEffectPoint = activeEffectPoint . Value ! = null & & current . Value . ControlPoints . Contains ( activeEffectPoint . Value ) ;
2024-06-21 16:54:40 +08:00
if ( IsHovered | | isSelected )
background . FadeIn ( 100 , Easing . OutQuint ) ;
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
else if ( hasCurrentTimingPoint | | hasCurrentEffectPoint )
background . FadeTo ( 0.2f , 100 , Easing . OutQuint ) ;
2024-06-21 16:54:40 +08:00
else
background . FadeOut ( 100 , Easing . OutQuint ) ;
background . Colour = isSelected ? colourProvider . Colour3 : colourProvider . Background1 ;
Redesign timing table tracking
- On entering the screen, the timing point active at the current instant
of the map is selected. This is the *only* time where the selected
point is changed automatically for the user.
- The ongoing automatic tracking of the relevant point after the initial
selection is *gone*. Even knowing the fact that it was supposed to
track the supposedly relevant "last selected type" of control point,
I always found the tracking to be fairly arbitrary in how it works.
Removing this behaviour also incidentally fixes
https://github.com/ppy/osu/issues/23147.
In its stead, to indicate which timing groups are having an effect,
they receive an indicator line on the left (coloured using the
relevant control points' representing colours), as well as a slight
highlight effect.
- If there is no control point selected, the table will autoscroll to
the latest timing group, unless the user manually scrolled the table
before.
- If the selected control point changes, the table will autoscroll to
the newly selected point, *regardless* of whether the user manually
scrolled the table before.
- A new button is added which permits the user to select the latest
timing group. As per the point above, this will autoscroll the user
to that group at the same time.
2024-08-20 17:14:42 +08:00
if ( hasCurrentTimingPoint | | hasCurrentEffectPoint )
{
currentIndicator . FadeIn ( 100 , Easing . OutQuint ) ;
if ( hasCurrentTimingPoint & & hasCurrentEffectPoint )
currentIndicator . Colour = ColourInfo . GradientVertical ( activeTimingPoint . Value ! . GetRepresentingColour ( colours ) , activeEffectPoint . Value ! . GetRepresentingColour ( colours ) ) ;
else if ( hasCurrentTimingPoint )
currentIndicator . Colour = activeTimingPoint . Value ! . GetRepresentingColour ( colours ) ;
else
currentIndicator . Colour = activeEffectPoint . Value ! . GetRepresentingColour ( colours ) ;
}
else
currentIndicator . FadeOut ( 100 , Easing . OutQuint ) ;
2024-06-21 16:54:40 +08:00
}
2022-11-27 10:47:02 +08:00
}
private partial class ControlGroupTiming : FillFlowContainer
{
2024-06-21 16:54:40 +08:00
public Bindable < ControlPointGroup > Group { get ; } = new Bindable < ControlPointGroup > ( ) ;
private OsuSpriteText timeText = null ! ;
[BackgroundDependencyLoader]
private void load ( )
2022-11-27 10:47:02 +08:00
{
Name = @"ControlGroupTiming" ;
RelativeSizeAxes = Axes . Y ;
2024-06-21 16:54:40 +08:00
Width = timing_column_width ;
2022-11-27 10:47:02 +08:00
Spacing = new Vector2 ( 5 ) ;
Children = new Drawable [ ]
2021-04-19 17:25:30 +08:00
{
2024-06-21 16:54:40 +08:00
timeText = new OsuSpriteText
2021-04-19 17:25:30 +08:00
{
2024-06-21 16:54:40 +08:00
Font = OsuFont . GetFont ( size : 14 , weight : FontWeight . Bold ) ,
2022-11-27 10:47:02 +08:00
Width = 70 ,
Anchor = Anchor . CentreLeft ,
Origin = Anchor . CentreLeft ,
} ,
2024-06-21 16:54:40 +08:00
new ControlGroupAttributes ( c = > c is TimingControlPoint )
2022-11-27 10:47:02 +08:00
{
Anchor = Anchor . CentreLeft ,
Origin = Anchor . CentreLeft ,
2024-06-21 16:54:40 +08:00
Group = { BindTarget = Group } ,
2021-04-19 17:25:30 +08:00
}
2022-11-27 10:47:02 +08:00
} ;
}
2024-06-21 16:54:40 +08:00
protected override void LoadComplete ( )
{
base . LoadComplete ( ) ;
Group . BindValueChanged ( _ = > timeText . Text = Group . Value ? . Time . ToEditorFormattedString ( ) ? ? default ( LocalisableString ) , true ) ;
}
2021-04-19 17:25:30 +08:00
}
2019-10-18 16:59:54 +08:00
2019-10-27 14:19:36 +08:00
private partial class ControlGroupAttributes : CompositeDrawable
2019-10-18 16:59:54 +08:00
{
2024-06-21 16:54:40 +08:00
public Bindable < ControlPointGroup > Group { get ; } = new Bindable < ControlPointGroup > ( ) ;
private BindableList < ControlPoint > controlPoints { get ; } = new BindableList < ControlPoint > ( ) ;
2021-04-19 17:25:30 +08:00
2024-06-21 16:54:40 +08:00
private readonly Func < ControlPoint , bool > matchFunction ;
2019-10-18 16:59:54 +08:00
2024-06-21 16:54:40 +08:00
private FillFlowContainer fill = null ! ;
2019-10-18 16:59:54 +08:00
2024-06-21 16:54:40 +08:00
public ControlGroupAttributes ( Func < ControlPoint , bool > matchFunction )
2019-10-27 14:19:36 +08:00
{
2021-04-19 17:25:30 +08:00
this . matchFunction = matchFunction ;
2024-06-21 16:54:40 +08:00
}
2021-04-19 17:25:30 +08:00
2024-06-21 16:54:40 +08:00
[BackgroundDependencyLoader]
private void load ( )
{
2021-04-19 17:25:30 +08:00
AutoSizeAxes = Axes . X ;
RelativeSizeAxes = Axes . Y ;
2022-11-27 10:47:02 +08:00
Name = @"ControlGroupAttributes" ;
2021-04-19 17:25:30 +08:00
2019-10-27 14:19:36 +08:00
InternalChild = fill = new FillFlowContainer
{
2021-04-19 17:25:30 +08:00
AutoSizeAxes = Axes . X ,
RelativeSizeAxes = Axes . Y ,
2019-10-27 14:19:36 +08:00
Direction = FillDirection . Horizontal ,
Spacing = new Vector2 ( 2 )
} ;
}
2019-10-18 16:59:54 +08:00
2020-10-08 04:57:20 +08:00
protected override void LoadComplete ( )
{
base . LoadComplete ( ) ;
2024-06-21 16:54:40 +08:00
Group . BindValueChanged ( _ = >
{
controlPoints . UnbindBindings ( ) ;
controlPoints . Clear ( ) ;
if ( Group . Value ! = null )
( ( IBindableList < ControlPoint > ) controlPoints ) . BindTo ( Group . Value . ControlPoints ) ;
} , true ) ;
controlPoints . BindCollectionChanged ( ( _ , _ ) = > createChildren ( ) , true ) ;
2020-10-08 04:57:20 +08:00
}
2019-10-27 14:19:36 +08:00
private void createChildren ( )
{
2021-04-19 14:06:07 +08:00
fill . ChildrenEnumerable = controlPoints
2021-04-19 17:25:30 +08:00
. Where ( matchFunction )
2021-04-19 14:06:07 +08:00
. Select ( createAttribute )
// arbitrary ordering to make timing points first.
// probably want to explicitly define order in the future.
. OrderByDescending ( c = > c . GetType ( ) . Name ) ;
2019-10-18 16:59:54 +08:00
}
2022-11-30 13:20:54 +08:00
private Drawable createAttribute ( ControlPoint controlPoint )
2019-10-27 14:19:36 +08:00
{
switch ( controlPoint )
{
case TimingControlPoint timing :
2021-04-19 14:06:07 +08:00
return new TimingRowAttribute ( timing ) ;
2019-10-27 14:19:36 +08:00
case EffectControlPoint effect :
2021-04-19 15:28:18 +08:00
return new EffectRowAttribute ( effect ) ;
2022-11-27 10:45:56 +08:00
}
2022-11-30 13:20:54 +08:00
throw new ArgumentOutOfRangeException ( nameof ( controlPoint ) , $"Control point type {controlPoint.GetType()} is not supported" ) ;
2019-10-27 14:19:36 +08:00
}
2019-10-18 16:59:54 +08:00
}
}
}