Skip to content

Commit

Permalink
Merge pull request #2335 from marticliment/listview-to-itemsview
Browse files Browse the repository at this point in the history
Replace ListView with ItemsView
  • Loading branch information
marticliment authored Jun 23, 2024
2 parents 3bd3971 + ce1dff3 commit 42d315d
Show file tree
Hide file tree
Showing 13 changed files with 249 additions and 178 deletions.
Original file line number Diff line number Diff line change
@@ -1,33 +1,46 @@
using System.Text.Json.Serialization.Metadata;

namespace UniGetUI.Core.Classes.Tests
{
public class SortableObservableCollectionTests
{
class SortableInt : IIndexableListItem
{
public int Value { get; set; }
public int Index { get; set; }
public SortableInt(int value) { Value = value; }
}

[Fact]
public void TestSortableCollection()
{
int EventTriggeredCount = 0;

SortableObservableCollection<int> SortableCollection = new();
SortableObservableCollection<SortableInt> SortableCollection = new();
SortableCollection.CollectionChanged += (s, e) => { EventTriggeredCount++; };
SortableCollection.SortingSelector = (s) => { return s; };
SortableCollection.Add(1);
SortableCollection.Add(3);
SortableCollection.Add(4);
SortableCollection.SortingSelector = (s) => { return s.Value; };
SortableCollection.Add(new(1));
SortableCollection.Add(new(2));
SortableCollection.Add(new(4));

SortableCollection.BlockSorting = true;
SortableCollection.Add(5);
SortableCollection.Add(2);
SortableCollection.Add(new(5));
SortableCollection.Add(new(2));
SortableCollection.BlockSorting = false;


SortableCollection.Sort();

Assert.Equal(7, EventTriggeredCount);
Assert.Equal(1, SortableCollection[0]);
Assert.Equal(2, SortableCollection[1]);
Assert.Equal(3, SortableCollection[2]);
Assert.Equal(4, SortableCollection[3]);
Assert.Equal(5, SortableCollection[4]);
Assert.Equal(5, SortableCollection.Count);
Assert.Equal(1, SortableCollection[0].Value);
Assert.Equal(2, SortableCollection[1].Value);
Assert.Equal(2, SortableCollection[2].Value);
Assert.Equal(4, SortableCollection[3].Value);
Assert.Equal(5, SortableCollection[4].Value);

for (int i = 0; i < SortableCollection.Count; i++)
Assert.Equal(i, SortableCollection[i].Index);
}
}
}
13 changes: 13 additions & 0 deletions src/UniGetUI.Core.Classes/IIndexableListItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UniGetUI.Core.Classes
{
public interface IIndexableListItem
{
public int Index { get; set; }
}
}
8 changes: 6 additions & 2 deletions src/UniGetUI.Core.Classes/SortableObservableCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace UniGetUI.Core.Classes
{
public class SortableObservableCollection<T> : ObservableCollection<T>
public class SortableObservableCollection<T> : ObservableCollection<T> where T: IIndexableListItem
{
public Func<T, object>? SortingSelector { get; set; }
public bool Descending { get; set; }
Expand All @@ -26,13 +26,17 @@ public void Sort()
BlockSorting = true;

if (SortingSelector == null)
throw new Exception("SortableObservableCollection<T>.SortingSelector must not be null when sorting a function");
throw new Exception("SortableObservableCollection<T>.SortingSelector must not be null when sorting");

List<T> sorted = Descending ? this.OrderByDescending(SortingSelector).ToList() : this.OrderBy(SortingSelector).ToList();
foreach (T item in sorted)
{
Move(IndexOf(item), sorted.IndexOf(item));
}

for(int i = 0; i < Count; i++)
this[i].Index = i;

BlockSorting = false;
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Runtime.CompilerServices;
using System.Text.Json.Nodes;
using UniGetUI.Core.Classes;
using UniGetUI.Core.Data;
using UniGetUI.Core.IconEngine;
using UniGetUI.Core.Logging;
Expand All @@ -10,10 +12,12 @@
using UniGetUI.PackageEngine.Classes.Packages;
using UniGetUI.PackageEngine.Enums;
using UniGetUI.PackageEngine.ManagerClasses.Manager;
using Windows.Globalization;
using Windows.Storage.Search;

namespace UniGetUI.PackageEngine.PackageClasses
{
public class Package : INotifyPropertyChanged
public class Package : INotifyPropertyChanged, IIndexableListItem
{
// Internal properties
private bool __is_checked = false;
Expand Down Expand Up @@ -132,6 +136,7 @@ public float ListedOpacity
set { __opacity = value; OnPropertyChanged(); }
}


public string IsCheckedAsString { get { return IsChecked ? "True" : "False"; } }
public string Name { get; }
public string Id { get; }
Expand All @@ -142,15 +147,13 @@ public float ListedOpacity
public PackageManager Manager { get; }
public string NewVersion { get; }
public virtual bool IsUpgradable { get; }
public PackageScope Scope { get; set; }
public string SourceAsString
{
get
{
if (Source != null) return Source.ToString();
else return "";
}
}
public PackageScope Scope { get; set; }
public string SourceAsString { get; private set; }

public int Index { get; set; }
public Package SelfInstance;

public string AutomationName { get; private set; }

/// <summary>
/// Constuct a package with a given name, id, version, source and manager, and an optional scope.
Expand All @@ -163,6 +166,7 @@ public string SourceAsString
/// <param name="scope"></param>
public Package(string name, string id, string version, ManagerSource source, PackageManager manager, PackageScope scope = PackageScope.Local)
{
SelfInstance = this;
Name = name;
Id = id;
Version = version;
Expand All @@ -172,6 +176,8 @@ public Package(string name, string id, string version, ManagerSource source, Pac
Scope = scope;
NewVersion = "";
Tag = PackageTag.Default;
SourceAsString = source.ToString();
AutomationName = CoreTools.Translate("Package {name} from {manager}", new Dictionary<string, object?> { {"name", Name },{ "manager", SourceAsString } });
__hash = CoreTools.HashStringAsLong(Manager.Name + "\\" + Source.Name + "\\" + Id);
__versioned_hash = CoreTools.HashStringAsLong(Manager.Name + "\\" + Source.Name + "\\" + Id + "\\" + Version);
IsUpgradable = false;
Expand Down
13 changes: 2 additions & 11 deletions src/UniGetUI/Interface/MainView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -396,9 +396,6 @@ public async Task<InstallationOptions> UpdateInstallationSettings(Package packag

private void NavigateToPage(Page TargetPage)
{
foreach (Page page in PageButtonReference.Keys)
if (page.Visibility == Visibility.Visible)
OldPage = page;
if (!PageButtonReference.ContainsKey(TargetPage))
{
PageButtonReference.Add(TargetPage, MoreNavButton);
Expand All @@ -418,14 +415,8 @@ private void NavigateToPage(Page TargetPage)
OldPage = CurrentPage;
CurrentPage = TargetPage;

if (CurrentPage == DiscoverPage)
DiscoverPage.PackageList.Focus(FocusState.Programmatic);
else if (CurrentPage == UpdatesPage)
UpdatesPage.PackageList.Focus(FocusState.Programmatic);
else if (CurrentPage == InstalledPage)
InstalledPage.PackageList.Focus(FocusState.Programmatic);
else if (CurrentPage == BundlesPage)
BundlesPage.PackageList.Focus(FocusState.Programmatic);
(CurrentPage as AbstractPackagesPage)?.FocusPackageList();
if (CurrentPage == BundlesPage) BundlesPage.PackageList.Focus(FocusState.Programmatic);
}

private async void ReleaseNotesMenu_Click(object sender, RoutedEventArgs e)
Expand Down
84 changes: 49 additions & 35 deletions src/UniGetUI/Interface/SoftwarePages/AbstractPackagesPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -498,91 +498,99 @@
</Style>

<DataTemplate x:Key="PackageTemplate" x:DataType="pkgClasses:Package">
<Grid ColumnSpacing="5" Opacity="{x:Bind ListedOpacity, Mode=OneWay}">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="*" MinWidth="100"/>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="*" MinWidth="100"/>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="*" MaxWidth="125"/>
<ColumnDefinition Width="24" MaxWidth="{x:Bind NewVersionIconWidth}"/>
<ColumnDefinition Width="*" MaxWidth="{x:Bind NewVersionLabelWidth}"/>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="*" MaxWidth="150"/>
</Grid.ColumnDefinitions>
<CheckBox
<widgets:PackageItemContainer AutomationProperties.Name="{x:Bind AutomationName}" CornerRadius="4"
Package="{x:Bind SelfInstance}"
RightTapped="PackageItemContainer_RightTapped"
DoubleTapped="PackageItemContainer_DoubleTapped"
KeyUp="PackageItemContainer_KeyUp"
>

<Grid ColumnSpacing="5" Opacity="{x:Bind ListedOpacity, Mode=OneWay}" Padding="12,3,8,3">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="*" MinWidth="100"/>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="*" MinWidth="100"/>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="*" MaxWidth="125"/>
<ColumnDefinition Width="24" MaxWidth="{x:Bind NewVersionIconWidth}"/>
<ColumnDefinition Width="*" MaxWidth="{x:Bind NewVersionLabelWidth}"/>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="*" MaxWidth="150"/>
</Grid.ColumnDefinitions>
<CheckBox
Grid.Column="0" Grid.Row="0"
VerticalAlignment="Center"
IsChecked="{x:Bind IsChecked, Mode=TwoWay}"
/>
<Canvas Grid.Column="1" Grid.Row="0" Height="24" Width="24">
<Border Background="{ThemeResource AccentAAFillColorTertiaryBrush}"
<Canvas Grid.Column="1" Grid.Row="0" Height="24" Width="24">
<Border Background="{ThemeResource AccentAAFillColorTertiaryBrush}"
Height="18" Width="18"
Canvas.Top="3" Canvas.Left="3"
CornerRadius="12" Visibility="{x:Bind ListIconShowHighlight, Mode=OneWay}"/>
<widgets:LocalIcon
<widgets:LocalIcon
IconName="{x:Bind ListedIconId, Mode=OneWay}"
Height="24" Width="24"
Canvas.Top="0" Canvas.Left="0"
VerticalAlignment="Center"
/>
</Canvas>
<TextBlock
</Canvas>
<TextBlock
Grid.Column="2" Grid.Row="0"
VerticalAlignment="Center"
Text="{x:Bind Name}" FontSize="13" FontFamily="Segoe UI Variable Text"
ToolTipService.ToolTip="{x:Bind ListedNameTooltip, Mode=OneWay}"
/>
<widgets:LocalIcon
<widgets:LocalIcon
IconName="ID"
Grid.Column="3" Grid.Row="0"
VerticalAlignment="Center"
/>
<TextBlock
<TextBlock
Grid.Column="4" Grid.Row="0"
VerticalAlignment="Center"
Text="{x:Bind Id}" FontSize="13" FontFamily="Segoe UI Variable Text"
ToolTipService.ToolTip="{x:Bind Id}"
/>
<widgets:LocalIcon
<widgets:LocalIcon
IconName="version"
Grid.Column="5" Grid.Row="0"
VerticalAlignment="Center"
/>
<TextBlock
<TextBlock
Grid.Column="6" Grid.Row="0"
VerticalAlignment="Center"
Text="{x:Bind Version}" FontSize="13" FontFamily="Segoe UI Variable Text"
ToolTipService.ToolTip="{x:Bind Version}"
/>
<widgets:LocalIcon
<widgets:LocalIcon
IconName="newversion" Visibility="{x:Bind IsUpgradable}"
Grid.Column="7" Grid.Row="0"
VerticalAlignment="Center"
/>
<TextBlock
<TextBlock
Grid.Column="8" Grid.Row="0"
VerticalAlignment="Center" Visibility="{x:Bind IsUpgradable}"
Text="{x:Bind NewVersion}" FontSize="13" FontFamily="Segoe UI Variable Text"
ToolTipService.ToolTip="{x:Bind NewVersion}"
/>
<widgets:LocalIcon
<widgets:LocalIcon
Grid.Column="9" Grid.Row="0"
VerticalAlignment="Center"
IconName="{x:Bind Source.IconId}"
/>
<TextBlock
<TextBlock
Grid.Column="10" Grid.Row="0"
VerticalAlignment="Center"
Text="{x:Bind Source.ToString()}" FontSize="13" FontFamily="Segoe UI Variable Text"
ToolTipService.ToolTip="{x:Bind Source.ToString()}"
/>
</Grid>
</Grid>
</widgets:PackageItemContainer>
</DataTemplate>
</Page.Resources>

Expand Down Expand Up @@ -654,6 +662,8 @@
<CommandBar Name="ToolBar" x:FieldModifier="protected" Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="3" DefaultLabelPosition="Right" HorizontalAlignment="Stretch">
</CommandBar>
</Grid>


<!-- NON-HEADER CONTENT -->
<Grid Grid.Row="2" Grid.Column="1" RowSpacing="4" ColumnSpacing="12" Name="BodyGrid">
<Grid.ColumnDefinitions>
Expand Down Expand Up @@ -842,10 +852,14 @@
<Button Name="SourceHeader" Grid.Column="10" Grid.ColumnSpan="3" HorizontalAlignment="Stretch" CornerRadius="0,4,4,0" BorderThickness="0"/>
</Grid>

<ListView x:Name="PackageList" x:FieldModifier="public" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="1"
<ItemsView x:Name="PackageList" x:FieldModifier="protected" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="1"
ItemsSource="{x:Bind FilteredPackages, Mode=TwoWay}"
ItemTemplate="{StaticResource PackageTemplate}"
CanBeScrollAnchor="False"/>
ItemTemplate="{StaticResource PackageTemplate}" Padding="4,0,4,0"
CanBeScrollAnchor="False">
<ItemsView.Layout>
<StackLayout Spacing="3"/>
</ItemsView.Layout>
</ItemsView>

<Grid Grid.Row="1">
<Grid.RowDefinitions>
Expand Down
Loading

0 comments on commit 42d315d

Please sign in to comment.