mirror of
https://github.com/par274/sharpemu.git
synced 2026-08-03 16:39:51 +08:00
[GUI] Update library page layout (#690)
* [GUI] Add horizontal game tiles * [GUI] Update launching elements layout * [GUI] Change cards format to squares
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace SharpEmu.GUI;
|
||||
|
||||
/// <summary>
|
||||
/// Read-only view of the visible games with one persistent action tile at
|
||||
/// the end. Game collection changes keep their original indices, so Avalonia
|
||||
/// can update and virtualize the rail without rebuilding every item.
|
||||
/// </summary>
|
||||
public sealed class LibraryTileCollection : IReadOnlyList<LibraryTile>, IList, INotifyCollectionChanged
|
||||
{
|
||||
private readonly ObservableCollection<GameEntry> _games;
|
||||
|
||||
public LibraryTileCollection(ObservableCollection<GameEntry> games)
|
||||
{
|
||||
_games = games;
|
||||
_games.CollectionChanged += OnGamesCollectionChanged;
|
||||
}
|
||||
|
||||
public event NotifyCollectionChangedEventHandler? CollectionChanged;
|
||||
|
||||
public int Count => _games.Count + 1;
|
||||
|
||||
bool IList.IsFixedSize => false;
|
||||
|
||||
bool IList.IsReadOnly => true;
|
||||
|
||||
bool ICollection.IsSynchronized => false;
|
||||
|
||||
object ICollection.SyncRoot => this;
|
||||
|
||||
public LibraryTile this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((uint)index < (uint)_games.Count)
|
||||
{
|
||||
return _games[index];
|
||||
}
|
||||
|
||||
if (index == _games.Count)
|
||||
{
|
||||
return AddFolderTile.Instance;
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
}
|
||||
|
||||
object? IList.this[int index]
|
||||
{
|
||||
get => this[index];
|
||||
set => throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public IEnumerator<LibraryTile> GetEnumerator()
|
||||
{
|
||||
foreach (var game in _games)
|
||||
{
|
||||
yield return game;
|
||||
}
|
||||
|
||||
yield return AddFolderTile.Instance;
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
int IList.Add(object? value) => throw new NotSupportedException();
|
||||
|
||||
void IList.Clear() => throw new NotSupportedException();
|
||||
|
||||
bool IList.Contains(object? value) => ((IList)this).IndexOf(value) >= 0;
|
||||
|
||||
int IList.IndexOf(object? value) => value switch
|
||||
{
|
||||
GameEntry game => _games.IndexOf(game),
|
||||
AddFolderTile => _games.Count,
|
||||
_ => -1,
|
||||
};
|
||||
|
||||
void IList.Insert(int index, object? value) => throw new NotSupportedException();
|
||||
|
||||
void IList.Remove(object? value) => throw new NotSupportedException();
|
||||
|
||||
void IList.RemoveAt(int index) => throw new NotSupportedException();
|
||||
|
||||
void ICollection.CopyTo(Array array, int index)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(array);
|
||||
foreach (var tile in this)
|
||||
{
|
||||
array.SetValue(tile, index++);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGamesCollectionChanged(object? sender, NotifyCollectionChangedEventArgs args) =>
|
||||
CollectionChanged?.Invoke(this, args);
|
||||
}
|
||||
Reference in New Issue
Block a user