mirror of
https://github.com/ppy/osu.git
synced 2024-11-14 15:17:27 +08:00
Merge branch 'master' into availability-fixes
This commit is contained in:
commit
21f758947d
@ -18,6 +18,7 @@ using osu.Game.Extensions;
|
||||
using osu.Game.Models;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Tests.Resources;
|
||||
using Realms;
|
||||
using SharpCompress.Archives;
|
||||
@ -416,6 +417,53 @@ namespace osu.Game.Tests.Database
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestImport_ThenModifyMapWithScore_ThenImport()
|
||||
{
|
||||
RunTestWithRealmAsync(async (realm, storage) =>
|
||||
{
|
||||
var importer = new BeatmapImporter(storage, realm);
|
||||
using var store = new RealmRulesetStore(realm, storage);
|
||||
|
||||
string? temp = TestResources.GetTestBeatmapForImport();
|
||||
|
||||
var imported = await LoadOszIntoStore(importer, realm.Realm);
|
||||
|
||||
await createScoreForBeatmap(realm.Realm, imported.Beatmaps.First());
|
||||
|
||||
// imitate making local changes via editor
|
||||
// ReSharper disable once MethodHasAsyncOverload
|
||||
realm.Write(_ =>
|
||||
{
|
||||
BeatmapInfo beatmap = imported.Beatmaps.First();
|
||||
beatmap.Hash = "new_hash";
|
||||
beatmap.ResetOnlineInfo();
|
||||
});
|
||||
|
||||
// for now, making changes to a beatmap doesn't remove the backlink from the score to the beatmap.
|
||||
// the logic of ensuring that scores match the beatmap is upheld via comparing the hash in usages (see: https://github.com/ppy/osu/pull/22539).
|
||||
// TODO: revisit when fixing https://github.com/ppy/osu/issues/24069.
|
||||
Assert.That(imported.Beatmaps.First().Scores.Any());
|
||||
|
||||
var importedSecondTime = await importer.Import(new ImportTask(temp));
|
||||
|
||||
EnsureLoaded(realm.Realm);
|
||||
|
||||
// check the newly "imported" beatmap is not the original.
|
||||
Assert.NotNull(importedSecondTime);
|
||||
Debug.Assert(importedSecondTime != null);
|
||||
Assert.That(imported.ID != importedSecondTime.ID);
|
||||
|
||||
var importedFirstTimeBeatmap = imported.Beatmaps.First();
|
||||
var importedSecondTimeBeatmap = importedSecondTime.PerformRead(s => s.Beatmaps.First());
|
||||
|
||||
Assert.That(importedFirstTimeBeatmap.ID != importedSecondTimeBeatmap.ID);
|
||||
Assert.That(importedFirstTimeBeatmap.Hash != importedSecondTimeBeatmap.Hash);
|
||||
Assert.That(!importedFirstTimeBeatmap.Scores.Any());
|
||||
Assert.That(importedSecondTimeBeatmap.Scores.Count() == 1);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestImportThenImportWithChangedFile()
|
||||
{
|
||||
@ -1074,18 +1122,16 @@ namespace osu.Game.Tests.Database
|
||||
Assert.IsTrue(realm.All<BeatmapSetInfo>().First(_ => true).DeletePending);
|
||||
}
|
||||
|
||||
private static Task createScoreForBeatmap(Realm realm, BeatmapInfo beatmap)
|
||||
private static Task createScoreForBeatmap(Realm realm, BeatmapInfo beatmap) =>
|
||||
realm.WriteAsync(() =>
|
||||
{
|
||||
// TODO: reimplement when we have score support in realm.
|
||||
// return ImportScoreTest.LoadScoreIntoOsu(osu, new ScoreInfo
|
||||
// {
|
||||
// OnlineID = 2,
|
||||
// Beatmap = beatmap,
|
||||
// BeatmapInfoID = beatmap.ID
|
||||
// }, new ImportScoreTest.TestArchiveReader());
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
realm.Add(new ScoreInfo
|
||||
{
|
||||
OnlineID = 2,
|
||||
BeatmapInfo = beatmap,
|
||||
BeatmapHash = beatmap.Hash
|
||||
});
|
||||
});
|
||||
|
||||
private static void checkBeatmapSetCount(Realm realm, int expected, bool includeDeletePending = false)
|
||||
{
|
||||
|
@ -347,6 +347,73 @@ namespace osu.Game.Tests.Database
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDanglingScoreTransferred()
|
||||
{
|
||||
RunTestWithRealmAsync(async (realm, storage) =>
|
||||
{
|
||||
var importer = new BeatmapImporter(storage, realm);
|
||||
using var rulesets = new RealmRulesetStore(realm, storage);
|
||||
|
||||
using var __ = getBeatmapArchive(out string pathOriginal);
|
||||
using var _ = getBeatmapArchive(out string pathOnlineCopy);
|
||||
|
||||
var importBeforeUpdate = await importer.Import(new ImportTask(pathOriginal));
|
||||
|
||||
Assert.That(importBeforeUpdate, Is.Not.Null);
|
||||
Debug.Assert(importBeforeUpdate != null);
|
||||
|
||||
string scoreTargetBeatmapHash = string.Empty;
|
||||
|
||||
// set a score on the beatmap
|
||||
importBeforeUpdate.PerformWrite(s =>
|
||||
{
|
||||
var beatmapInfo = s.Beatmaps.First();
|
||||
|
||||
scoreTargetBeatmapHash = beatmapInfo.Hash;
|
||||
|
||||
s.Realm.Add(new ScoreInfo(beatmapInfo, s.Realm.All<RulesetInfo>().First(), new RealmUser()));
|
||||
});
|
||||
|
||||
// locally modify beatmap
|
||||
const string new_beatmap_hash = "new_hash";
|
||||
importBeforeUpdate.PerformWrite(s =>
|
||||
{
|
||||
var beatmapInfo = s.Beatmaps.First(b => b.Hash == scoreTargetBeatmapHash);
|
||||
|
||||
beatmapInfo.Hash = new_beatmap_hash;
|
||||
beatmapInfo.ResetOnlineInfo();
|
||||
});
|
||||
|
||||
realm.Run(r => r.Refresh());
|
||||
|
||||
// for now, making changes to a beatmap doesn't remove the backlink from the score to the beatmap.
|
||||
// the logic of ensuring that scores match the beatmap is upheld via comparing the hash in usages (https://github.com/ppy/osu/pull/22539).
|
||||
// TODO: revisit when fixing https://github.com/ppy/osu/issues/24069.
|
||||
checkCount<ScoreInfo>(realm, 1);
|
||||
|
||||
// reimport the original beatmap before local modifications
|
||||
var importAfterUpdate = await importer.ImportAsUpdate(new ProgressNotification(), new ImportTask(pathOnlineCopy), importBeforeUpdate.Value);
|
||||
|
||||
Assert.That(importAfterUpdate, Is.Not.Null);
|
||||
Debug.Assert(importAfterUpdate != null);
|
||||
|
||||
realm.Run(r => r.Refresh());
|
||||
|
||||
// both original and locally modified versions present
|
||||
checkCount<BeatmapInfo>(realm, count_beatmaps + 1);
|
||||
checkCount<BeatmapMetadata>(realm, count_beatmaps + 1);
|
||||
checkCount<BeatmapSetInfo>(realm, 2);
|
||||
|
||||
// score is preserved
|
||||
checkCount<ScoreInfo>(realm, 1);
|
||||
|
||||
// score is transferred to new beatmap
|
||||
Assert.That(importBeforeUpdate.Value.Beatmaps.First(b => b.Hash == new_beatmap_hash).Scores, Has.Count.EqualTo(0));
|
||||
Assert.That(importAfterUpdate.Value.Beatmaps.First(b => b.Hash == scoreTargetBeatmapHash).Scores, Has.Count.EqualTo(1));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestScoreLostOnModification()
|
||||
{
|
||||
|
@ -133,6 +133,32 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
AddAssert("objects reverted to original position", () => addedObjects[0].Position == new Vector2(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGlobalFlipHotkeys()
|
||||
{
|
||||
HitCircle addedObject = null;
|
||||
|
||||
AddStep("add hitobjects", () => EditorBeatmap.Add(addedObject = new HitCircle { StartTime = 100 }));
|
||||
|
||||
AddStep("select objects", () => EditorBeatmap.SelectedHitObjects.Add(addedObject));
|
||||
|
||||
AddStep("flip horizontally across playfield", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.ControlLeft);
|
||||
InputManager.Key(Key.H);
|
||||
InputManager.ReleaseKey(Key.ControlLeft);
|
||||
});
|
||||
AddAssert("objects flipped horizontally", () => addedObject.Position == new Vector2(OsuPlayfield.BASE_SIZE.X, 0));
|
||||
|
||||
AddStep("flip vertically across playfield", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.ControlLeft);
|
||||
InputManager.Key(Key.J);
|
||||
InputManager.ReleaseKey(Key.ControlLeft);
|
||||
});
|
||||
AddAssert("objects flipped vertically", () => addedObject.Position == OsuPlayfield.BASE_SIZE);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBasicSelect()
|
||||
{
|
||||
|
@ -188,7 +188,7 @@ namespace osu.Game.Tournament.Components
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DiffPiece(stats),
|
||||
new DiffPiece(("Star Rating", $"{beatmap.StarRating:0.##}{srExtra}"))
|
||||
new DiffPiece(("Star Rating", $"{beatmap.StarRating:0.00}{srExtra}"))
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
|
@ -20,6 +20,7 @@ using osu.Game.IO;
|
||||
using osu.Game.IO.Archives;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring;
|
||||
using Realms;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
@ -204,6 +205,15 @@ namespace osu.Game.Beatmaps
|
||||
protected override void PostImport(BeatmapSetInfo model, Realm realm, ImportParameters parameters)
|
||||
{
|
||||
base.PostImport(model, realm, parameters);
|
||||
|
||||
// Scores are stored separately from beatmaps, and persist even when a beatmap is modified or deleted.
|
||||
// Let's reattach any matching scores that exist in the database, based on hash.
|
||||
foreach (BeatmapInfo beatmap in model.Beatmaps)
|
||||
{
|
||||
foreach (var score in realm.All<ScoreInfo>().Where(score => score.BeatmapHash == beatmap.Hash))
|
||||
score.BeatmapInfo = beatmap;
|
||||
}
|
||||
|
||||
ProcessBeatmap?.Invoke(model, parameters.Batch ? MetadataLookupScope.LocalCacheFirst : MetadataLookupScope.OnlineFirst);
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ namespace osu.Game.Collections
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
X = -OsuScrollContainer.SCROLL_BAR_HEIGHT,
|
||||
X = -OsuScrollContainer.SCROLL_BAR_WIDTH,
|
||||
Scale = new Vector2(0.65f),
|
||||
Action = addOrRemove,
|
||||
});
|
||||
|
@ -3,10 +3,12 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using AutoMapper;
|
||||
using AutoMapper.Internal;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Models;
|
||||
@ -52,10 +54,23 @@ namespace osu.Game.Database
|
||||
{
|
||||
foreach (var beatmap in s.Beatmaps)
|
||||
{
|
||||
var existing = d.Beatmaps.FirstOrDefault(b => b.ID == beatmap.ID);
|
||||
// Importantly, search all of realm for the beatmap (not just the set's beatmaps).
|
||||
// It may have gotten detached, and if that's the case let's use this opportunity to fix
|
||||
// things up.
|
||||
var existingBeatmap = d.Realm.Find<BeatmapInfo>(beatmap.ID);
|
||||
|
||||
if (existing != null)
|
||||
copyChangesToRealm(beatmap, existing);
|
||||
if (existingBeatmap != null)
|
||||
{
|
||||
// As above, reattach if it happens to not be in the set's beatmaps.
|
||||
if (!d.Beatmaps.Contains(existingBeatmap))
|
||||
{
|
||||
Debug.Fail("Beatmaps should never become detached under normal circumstances. If this ever triggers, it should be investigated further.");
|
||||
Logger.Log("WARNING: One of the difficulties in a beatmap was detached from its set. Please save a copy of logs and report this to devs.", LoggingTarget.Database, LogLevel.Important);
|
||||
d.Beatmaps.Add(existingBeatmap);
|
||||
}
|
||||
|
||||
copyChangesToRealm(beatmap, existingBeatmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
var newBeatmap = new BeatmapInfo
|
||||
@ -64,6 +79,7 @@ namespace osu.Game.Database
|
||||
BeatmapSet = d,
|
||||
Ruleset = d.Realm.Find<RulesetInfo>(beatmap.Ruleset.ShortName)
|
||||
};
|
||||
|
||||
d.Beatmaps.Add(newBeatmap);
|
||||
copyChangesToRealm(beatmap, newBeatmap);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace osu.Game.Graphics.Containers
|
||||
|
||||
public partial class OsuScrollContainer<T> : ScrollContainer<T> where T : Drawable
|
||||
{
|
||||
public const float SCROLL_BAR_HEIGHT = 10;
|
||||
public const float SCROLL_BAR_WIDTH = 10;
|
||||
public const float SCROLL_BAR_PADDING = 3;
|
||||
|
||||
/// <summary>
|
||||
@ -139,6 +139,8 @@ namespace osu.Game.Graphics.Containers
|
||||
|
||||
private readonly Box box;
|
||||
|
||||
protected override float MinimumDimSize => SCROLL_BAR_WIDTH * 3;
|
||||
|
||||
public OsuScrollbar(Direction scrollDir)
|
||||
: base(scrollDir)
|
||||
{
|
||||
@ -147,7 +149,7 @@ namespace osu.Game.Graphics.Containers
|
||||
CornerRadius = 5;
|
||||
|
||||
// needs to be set initially for the ResizeTo to respect minimum size
|
||||
Size = new Vector2(SCROLL_BAR_HEIGHT);
|
||||
Size = new Vector2(SCROLL_BAR_WIDTH);
|
||||
|
||||
const float margin = 3;
|
||||
|
||||
@ -173,11 +175,10 @@ namespace osu.Game.Graphics.Containers
|
||||
|
||||
public override void ResizeTo(float val, int duration = 0, Easing easing = Easing.None)
|
||||
{
|
||||
Vector2 size = new Vector2(SCROLL_BAR_HEIGHT)
|
||||
this.ResizeTo(new Vector2(SCROLL_BAR_WIDTH)
|
||||
{
|
||||
[(int)ScrollDirection] = val
|
||||
};
|
||||
this.ResizeTo(size, duration, easing);
|
||||
}, duration, easing);
|
||||
}
|
||||
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
|
@ -24,6 +24,11 @@ namespace osu.Game.Localisation
|
||||
/// </summary>
|
||||
public static LocalisableString SignedIn => new TranslatableString(getKey(@"signed_in"), @"Signed in");
|
||||
|
||||
/// <summary>
|
||||
/// "Sign out"
|
||||
/// </summary>
|
||||
public static LocalisableString SignOut => new TranslatableString(getKey(@"sign_out"), @"Sign out");
|
||||
|
||||
/// <summary>
|
||||
/// "Account"
|
||||
/// </summary>
|
||||
|
@ -88,6 +88,16 @@ Please try changing your audio device to a working setting.");
|
||||
/// </summary>
|
||||
public static LocalisableString LinkTypeNotSupported => new TranslatableString(getKey(@"unsupported_link_type"), @"This link type is not yet supported!");
|
||||
|
||||
/// <summary>
|
||||
/// "You received a private message from '{0}'. Click to read it!"
|
||||
/// </summary>
|
||||
public static LocalisableString PrivateMessageReceived(string username) => new TranslatableString(getKey(@"private_message_received"), @"You received a private message from '{0}'. Click to read it!", username);
|
||||
|
||||
/// <summary>
|
||||
/// "Your name was mentioned in chat by '{0}'. Click to find out why!"
|
||||
/// </summary>
|
||||
public static LocalisableString YourNameWasMentioned(string username) => new TranslatableString(getKey(@"your_name_was_mentioned"), @"Your name was mentioned in chat by '{0}'. Click to find out why!", username);
|
||||
|
||||
private static string getKey(string key) => $@"{prefix}:{key}";
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays;
|
||||
@ -154,7 +155,7 @@ namespace osu.Game.Online.Chat
|
||||
: base(message, channel)
|
||||
{
|
||||
Icon = FontAwesome.Solid.Envelope;
|
||||
Text = $"You received a private message from '{message.Sender.Username}'. Click to read it!";
|
||||
Text = NotificationsStrings.PrivateMessageReceived(message.Sender.Username);
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,7 +165,7 @@ namespace osu.Game.Online.Chat
|
||||
: base(message, channel)
|
||||
{
|
||||
Icon = FontAwesome.Solid.At;
|
||||
Text = $"Your name was mentioned in chat by '{message.Sender.Username}'. Click to find out why!";
|
||||
Text = NotificationsStrings.YourNameWasMentioned(message.Sender.Username);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1164,7 +1164,9 @@ namespace osu.Game
|
||||
private void forwardTabletLogsToNotifications()
|
||||
{
|
||||
const string tablet_prefix = @"[Tablet] ";
|
||||
|
||||
bool notifyOnWarning = true;
|
||||
bool notifyOnError = true;
|
||||
|
||||
Logger.NewEntry += entry =>
|
||||
{
|
||||
@ -1175,6 +1177,11 @@ namespace osu.Game
|
||||
|
||||
if (entry.Level == LogLevel.Error)
|
||||
{
|
||||
if (!notifyOnError)
|
||||
return;
|
||||
|
||||
notifyOnError = false;
|
||||
|
||||
Schedule(() =>
|
||||
{
|
||||
Notifications.Post(new SimpleNotification
|
||||
@ -1213,7 +1220,11 @@ namespace osu.Game
|
||||
Schedule(() =>
|
||||
{
|
||||
ITabletHandler tablet = Host.AvailableInputHandlers.OfType<ITabletHandler>().SingleOrDefault();
|
||||
tablet?.Tablet.BindValueChanged(_ => notifyOnWarning = true, true);
|
||||
tablet?.Tablet.BindValueChanged(_ =>
|
||||
{
|
||||
notifyOnWarning = true;
|
||||
notifyOnError = true;
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -185,7 +185,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
OnHovered = beatmap =>
|
||||
{
|
||||
showBeatmap(beatmap);
|
||||
starRating.Text = beatmap.StarRating.ToLocalisableString(@"0.##");
|
||||
starRating.Text = beatmap.StarRating.ToLocalisableString(@"0.00");
|
||||
starRatingContainer.FadeIn(100);
|
||||
},
|
||||
OnClicked = beatmap => { Beatmap.Value = beatmap; },
|
||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Login
|
||||
[LocalisableDescription(typeof(LoginPanelStrings), nameof(LoginPanelStrings.AppearOffline))]
|
||||
AppearOffline,
|
||||
|
||||
[LocalisableDescription(typeof(UserVerificationStrings), nameof(UserVerificationStrings.BoxInfoLogoutLink))]
|
||||
[LocalisableDescription(typeof(LoginPanelStrings), nameof(LoginPanelStrings.SignOut))]
|
||||
SignOut,
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace osu.Game.Overlays
|
||||
scrollbarBackground = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = OsuScrollContainer.SCROLL_BAR_HEIGHT,
|
||||
Width = OsuScrollContainer.SCROLL_BAR_WIDTH,
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Alpha = 0.5f
|
||||
|
@ -82,6 +82,7 @@ namespace osu.Game.Scoring
|
||||
{
|
||||
Ruleset = ruleset ?? new RulesetInfo();
|
||||
BeatmapInfo = beatmap ?? new BeatmapInfo();
|
||||
BeatmapHash = BeatmapInfo.Hash;
|
||||
RealmUser = realmUser ?? new RealmUser();
|
||||
ID = Guid.NewGuid();
|
||||
}
|
||||
|
@ -377,10 +377,13 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
float leftExcess = thisQuad.TopLeft.X - parentQuad.TopLeft.X;
|
||||
float rightExcess = parentQuad.TopRight.X - thisQuad.TopRight.X;
|
||||
|
||||
if (topExcess + bottomExcess < buttons.Height + button_padding)
|
||||
float minHeight = buttons.ScreenSpaceDrawQuad.Height;
|
||||
|
||||
if (topExcess < minHeight && bottomExcess < minHeight)
|
||||
{
|
||||
buttons.Anchor = Anchor.BottomCentre;
|
||||
buttons.Origin = Anchor.BottomCentre;
|
||||
buttons.Y = Math.Min(0, ToLocalSpace(Parent.ScreenSpaceDrawQuad.BottomLeft).Y - DrawHeight);
|
||||
}
|
||||
else if (topExcess > bottomExcess)
|
||||
{
|
||||
|
@ -160,13 +160,23 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
if (e.Repeat)
|
||||
return false;
|
||||
|
||||
bool handled;
|
||||
|
||||
switch (e.Action)
|
||||
{
|
||||
case GlobalAction.EditorFlipHorizontally:
|
||||
return HandleFlip(Direction.Horizontal, true);
|
||||
ChangeHandler?.BeginChange();
|
||||
handled = HandleFlip(Direction.Horizontal, true);
|
||||
ChangeHandler?.EndChange();
|
||||
|
||||
return handled;
|
||||
|
||||
case GlobalAction.EditorFlipVertically:
|
||||
return HandleFlip(Direction.Vertical, true);
|
||||
ChangeHandler?.BeginChange();
|
||||
handled = HandleFlip(Direction.Vertical, true);
|
||||
ChangeHandler?.EndChange();
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Screens.OnlinePlay.Components
|
||||
RelativeSizeAxes = Axes.X;
|
||||
|
||||
scroll.RelativeSizeAxes = Axes.X;
|
||||
scroll.Height = ParticipantsList.TILE_SIZE + OsuScrollContainer.SCROLL_BAR_HEIGHT + OsuScrollContainer.SCROLL_BAR_PADDING * 2;
|
||||
scroll.Height = ParticipantsList.TILE_SIZE + OsuScrollContainer.SCROLL_BAR_WIDTH + OsuScrollContainer.SCROLL_BAR_PADDING * 2;
|
||||
|
||||
list.RelativeSizeAxes = Axes.Y;
|
||||
list.AutoSizeAxes = Axes.X;
|
||||
|
Loading…
Reference in New Issue
Block a user