Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change ObjectInspector to work via object selection #208

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ee7ec3c
osu select by cursor inspector function
Givikap120 Jun 28, 2024
4f2d98a
new way of doing things
Givikap120 Jul 12, 2024
e6ddcf3
removed unnecessary things
Givikap120 Jul 12, 2024
fd1deb7
removed temporary unused things
Givikap120 Jul 12, 2024
c1e8c38
fixed issues with osu inspector
Givikap120 Jul 13, 2024
35fef60
moved inspectors to ruleset-respective folders
Givikap120 Jul 13, 2024
3a9d68d
Added basic taiko functionality
Givikap120 Jul 18, 2024
8d3eadd
implemented catch
Givikap120 Jul 18, 2024
f073b85
Merge branch 'ppy:master' into pp_dev_helper
Givikap120 Jul 18, 2024
af0c080
Update PerformanceCalculatorGUI.csproj
Givikap120 Jul 18, 2024
2659546
Update CatchSelectableDrawableObject.cs
Givikap120 Jul 18, 2024
2b8cab4
changed abstractions structure
Givikap120 Jul 19, 2024
c1a3b39
Added catch support and pooling
Givikap120 Jul 19, 2024
0830dd1
reverted useless ObjectInspector changes
Givikap120 Jul 19, 2024
1cea094
code factor fix
Givikap120 Jul 19, 2024
7a1a2fd
minor fixes
Givikap120 Jul 19, 2024
0b37191
moved selection logic to the object itself
Givikap120 Aug 1, 2024
c513681
fixed pausing/resuming working incorrectly
Givikap120 Aug 2, 2024
d248e51
Fixed Strong notes being outlined incorrectly
Givikap120 Aug 2, 2024
66e41d1
Merge branch 'master' into pp_dev_helper
stanriders Dec 4, 2024
e9ef567
Cleanup
stanriders Dec 4, 2024
08cc7d3
Change catch inspector to use bindables for selection, remove pooling…
stanriders Dec 4, 2024
701e327
Remove unused class
stanriders Dec 5, 2024
1c6359e
remvoe outdated comments
Givikap120 Dec 5, 2024
61e1ce0
Refactor taiko
stanriders Dec 5, 2024
3d62ad1
Merge branch 'pp_dev_helper' of https://github.com/Givikap120/osu-too…
stanriders Dec 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ namespace PerformanceCalculatorGUI.Components
{
public partial class ExtendedUserModSelectOverlay : UserModSelectOverlay
{
protected override bool ShowModEffects => false;

public ExtendedUserModSelectOverlay()
: base(OverlayColourScheme.Blue)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Pooling;
using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Beatmaps;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Catch.Difficulty.Preprocessing;
using osu.Game.Rulesets.Catch.Edit;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.UI;
using osuTK.Input;

namespace PerformanceCalculatorGUI.Screens.ObjectInspection.Catch
{
public partial class CatchObjectInspectorRuleset : DrawableCatchEditorRuleset
{
private readonly CatchDifficultyHitObject[] difficultyHitObjects;

[Resolved]
private ObjectDifficultyValuesContainer difficultyValuesContainer { get; set; }

public CatchObjectInspectorRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods, ExtendedCatchDifficultyCalculator difficultyCalculator, double clockRate)
: base(ruleset, beatmap, mods)
{
difficultyHitObjects = difficultyCalculator.GetDifficultyHitObjects(beatmap, clockRate)
.Cast<CatchDifficultyHitObject>().ToArray();
}

protected override void LoadComplete()
{
base.LoadComplete();
((CatchObjectInspectorPlayfield)Playfield).SelectedObject.BindValueChanged(
value => difficultyValuesContainer.CurrentDifficultyHitObject.Value = difficultyHitObjects.FirstOrDefault(x => x.BaseObject.StartTime == value.NewValue?.StartTime));
}

public override bool PropagatePositionalInputSubTree => true;

public override bool PropagateNonPositionalInputSubTree => false;

public override bool AllowBackwardsSeeks => true;

protected override PassThroughInputManager CreateInputManager() => new CatchObjectInspectorInputManager(Ruleset.RulesetInfo);

protected override Playfield CreatePlayfield() => new CatchObjectInspectorPlayfield(Beatmap.Difficulty);

private partial class CatchObjectInspectorInputManager : CatchInputManager
{
public CatchObjectInspectorInputManager(RulesetInfo ruleset) : base(ruleset)
{
}

protected override KeyBindingContainer<CatchAction> CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique)
=> new EmptyKeyBindingContainer(ruleset, variant, unique);

private partial class EmptyKeyBindingContainer : RulesetKeyBindingContainer
{
public EmptyKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) : base(ruleset, variant, unique)
{
}

protected override void ReloadMappings(IQueryable<RealmKeyBinding> realmKeyBindings)
{
base.ReloadMappings(realmKeyBindings);
KeyBindings = Enumerable.Empty<IKeyBinding>();
}
}
}

private partial class CatchObjectInspectorPlayfield : CatchEditorPlayfield
{
public readonly Bindable<CatchHitObject> SelectedObject = new();

private List<CatchSelectableHitObject> selectables = new();
public CatchObjectInspectorPlayfield(IBeatmapDifficultyInfo difficulty)
: base(difficulty)
{
DisplayJudgements.Value = false;
}

private DrawablePool<CatchSelectableHitObject> selectablesPool;

[BackgroundDependencyLoader]
private void load()
{
AddInternal(selectablesPool = new DrawablePool<CatchSelectableHitObject>(1, 200));
}

protected override void OnHitObjectAdded(HitObject hitObject)
{
base.OnHitObjectAdded(hitObject);

// Potential room for pooling here
switch (hitObject)
{
case Fruit fruit:
{
var newSelectable = selectablesPool.Get(a => a.UpdateFromHitObject((CatchHitObject)hitObject));
HitObjectContainer.Add(newSelectable);
selectables.Add(newSelectable);
break;
}
case JuiceStream juiceStream:
{
foreach (var nested in juiceStream.NestedHitObjects)
{
if (nested is TinyDroplet)
continue;

var newSelectable = selectablesPool.Get(a => a.UpdateFromHitObject((CatchHitObject)nested));
HitObjectContainer.Add(newSelectable);
selectables.Add(newSelectable);
}
break;
}
}
}

protected override GameplayCursorContainer CreateCursor() => null;
public override bool HandlePositionalInput => true;

protected override bool OnClick(ClickEvent e)
{
if (e.Button == MouseButton.Right)
return false;

CatchSelectableHitObject newSelectedObject = null;

// This search can be long if list of objects is very big. Potential for optimization
foreach (var selectable in selectables)
Givikap120 marked this conversation as resolved.
Show resolved Hide resolved
{
if (selectable.IsSelected)
{
selectable.Deselect();
continue;
}

if (!selectable.IsHovered)
continue;

if (newSelectedObject != null)
continue;

selectable.Select();
newSelectedObject = selectable;
}

SelectedObject.Value = newSelectedObject?.HitObject;
return true;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#nullable enable

using osu.Framework.Allocation;
using osu.Game.Rulesets.Catch.Objects.Drawables;
using osu.Game.Rulesets.Catch.Objects;
using osuTK;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components;

namespace PerformanceCalculatorGUI.Screens.ObjectInspection.Catch
{
public partial class CatchSelectableHitObject : DrawableCatchHitObject
{
// This is HitCirclePiece instead of FruitOutline because FruitOutline doesn't register input for some reason
private HitCirclePiece outline;
public CatchSelectableHitObject()
: base(new CatchDummyHitObject())
{
}

[BackgroundDependencyLoader]
private void load()
{
AddInternal(outline = new HitCirclePiece());
UpdateState();
}

public void UpdateFromHitObject(CatchHitObject hitObject)
{
Deselect();
HitObject.StartTime = hitObject.StartTime;
X = hitObject.EffectiveX;
outline.Scale = new Vector2(hitObject.Scale);

if (hitObject is Droplet)
outline.Scale *= 0.5f;
}

protected override void OnApply()
{
base.OnApply();
UpdateState();
}

public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => outline.ReceivePositionalInputAt(screenSpacePos);

private class CatchDummyHitObject : CatchHitObject
{
public CatchDummyHitObject()
{
}
}

#region Selection Logic
public override bool HandlePositionalInput => ShouldBeAlive || IsPresent;

private SelectionState state;

public SelectionState State
{
get => state;
set
{
if (state == value)
return;

state = value;

if (IsLoaded)
UpdateState();
}
}

public void UpdateState()
{
switch (state)
{
case SelectionState.Selected:
OnSelected();
break;

case SelectionState.NotSelected:
OnDeselected();
break;
}
}

protected void OnDeselected()
{
foreach (var d in InternalChildren)
d.Hide();
}

protected void OnSelected()
{
foreach (var d in InternalChildren)
d.Show();
}
public void Select() => State = SelectionState.Selected;
public void Deselect() => State = SelectionState.NotSelected;
public bool IsSelected => State == SelectionState.Selected;

#endregion
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ private void updateValues(DifficultyHitObject hitObject)
}

hitObjectTypeText.Text = hitObject.BaseObject.GetType().Name;
flowContainer.Add(new ObjectInspectorDifficultyValue("Start Time", hitObject.StartTime));

switch (hitObject)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using PerformanceCalculatorGUI.Components.TextBoxes;

namespace PerformanceCalculatorGUI.Screens.ObjectInspection
{
public partial class ObjectInspectionPanel : Container
{
private OsuTextFlowContainer textFlow;

[BackgroundDependencyLoader]
private void load()
{
AddInternal(new Container
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
AutoSizeAxes = Axes.Both,
Masking = true,
CornerRadius = ExtendedLabelledTextBox.CORNER_RADIUS,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0.95f,
Colour = OsuColour.Gray(0.1f)
},
textFlow = new OsuTextFlowContainer
{
Padding = new MarginPadding(5f),
AutoSizeAxes = Axes.Both,
}
}
});
}

public void AddParagraph(string text, int fontSize = 10)
{
textFlow.AddParagraph(text, p => p.Font = OsuFont.GetFont(size: fontSize - 3));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Generic;
using System.Linq;
using NuGet.Packaging.Rules;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
Expand All @@ -24,6 +25,9 @@
using osu.Game.Screens.Edit.Components;
using osu.Game.Screens.Edit.Components.Timelines.Summary;
using osuTK.Input;
using PerformanceCalculatorGUI.Screens.ObjectInspection.Catch;
using PerformanceCalculatorGUI.Screens.ObjectInspection.Osu;
using PerformanceCalculatorGUI.Screens.ObjectInspection.Taiko;

namespace PerformanceCalculatorGUI.Screens.ObjectInspection
{
Expand Down
Loading