10 Commits

90 changed files with 134 additions and 1390 deletions

22
.gitea/bug_template.md Normal file
View File

@ -0,0 +1,22 @@
---
name: "Bug"
about: "Add a bug to the backlog"
title: "[Bug] "
labels:
- bug
---
## Description
## Steps to Reproduce
## Expected Behavior
## Actual Behavior
## Resources
## Notes

21
.gitea/issue_template.md Normal file
View File

@ -0,0 +1,21 @@
---
name: "New Story"
about: "Add a new story to the backlog"
title: "[Feature] "
labels:
- feature
---
## Story
**As a**:
**I want**:
**So that**:
## Description
## Resources
## Notes

23
README.md Normal file
View File

@ -0,0 +1,23 @@
# Aurora
A collaborative media player
![Aurora](./aurora-sharp-desktop/Docs/Aurora.png)
## The Problem Statement
Music is a medium that should be consumed together. Aurora aims to creat a music listening experience that can be shared with any number of people no matter where the listeners are. With music perfectly in sync between all listeners, remote listening is as easy as loading the app and connecting to your friends.
## The Tech
- GTK: Aurora takes advantage of Xamarin and GTK under the hood in order to render a sleek, modern, cross platform desktop application.
- gRPC: gRPC is a modern open source high performance RPC framework that can run in any environment. This app is inherently a peer to peer application and as such, gRPC is utilized to efficiently and effectively communicate between aurora nodes by implementing simple service definitions.
## The Future
We are always looking for ways to improve the exerience of the application.
- Aurora Turn Server: The next big step for the application is integrating a custom Aurora turn server so that listeners can connect to one another from different networks while maintaining perfectly synchronized output
- 3rd Party Source Integration: Not everybody has a vast local collection of media that they have been collecting for years. We plan to integrate with 3rd Party music sources such as _Spotify_ and _Apple Music_

View File

@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<Protobuf Include="Src\Protos\signal.proto" GrpcServices="Server" />
<Protobuf Include="..\..\aurora-proto\Proto\signal.proto" GrpcServices="Server" />
</ItemGroup>
<ItemGroup>

View File

@ -2,7 +2,7 @@ syntax = "proto3";
package Aurora.Proto.Party;
import "Proto/general.proto";
import "general.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/field_mask.proto";

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Xamarin.Forms.4.3.0.991211\build\Xamarin.Forms.props" Condition="Exists('..\packages\Xamarin.Forms.4.3.0.991211\build\Xamarin.Forms.props')" />
<Import Project="..\packages\Xamarin.Forms.5.0.0.2012\build\Xamarin.Forms.props" Condition="Exists('..\packages\Xamarin.Forms.5.0.0.2012\build\Xamarin.Forms.props')" />
<Import Project="..\packages\Grpc.Tools.2.25.0\build\Grpc.Tools.props" Condition="Exists('..\packages\Grpc.Tools.2.25.0\build\Grpc.Tools.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -28,42 +28,24 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="gtk-sharp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
</Reference>
<Reference Include="gdk-sharp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
</Reference>
<Reference Include="glib-sharp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
</Reference>
<Reference Include="glade-sharp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
</Reference>
<Reference Include="pango-sharp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
</Reference>
<Reference Include="atk-sharp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
</Reference>
<Reference Include="Mono.Posix" />
<Reference Include="Xamarin.Forms.Core">
<HintPath>..\packages\Xamarin.Forms.4.3.0.991211\lib\netstandard2.0\Xamarin.Forms.Core.dll</HintPath>
<HintPath>..\packages\Xamarin.Forms.5.0.0.2012\lib\netstandard2.0\Xamarin.Forms.Core.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Platform">
<HintPath>..\packages\Xamarin.Forms.4.3.0.991211\lib\netstandard2.0\Xamarin.Forms.Platform.dll</HintPath>
<HintPath>..\packages\Xamarin.Forms.5.0.0.2012\lib\netstandard2.0\Xamarin.Forms.Platform.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Xaml">
<HintPath>..\packages\Xamarin.Forms.4.3.0.991211\lib\netstandard2.0\Xamarin.Forms.Xaml.dll</HintPath>
<HintPath>..\packages\Xamarin.Forms.5.0.0.2012\lib\netstandard2.0\Xamarin.Forms.Xaml.dll</HintPath>
</Reference>
<Reference Include="OpenTK">
<HintPath>..\packages\OpenTK.3.1.0\lib\net20\OpenTK.dll</HintPath>
</Reference>
<Reference Include="webkit-sharp">
<HintPath>..\packages\Xamarin.Forms.Platform.GTK.4.3.0.991211\lib\net45\webkit-sharp.dll</HintPath>
<HintPath>..\packages\Xamarin.Forms.Platform.GTK.5.0.0.2012\lib\net45\webkit-sharp.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Platform.GTK">
<HintPath>..\packages\Xamarin.Forms.Platform.GTK.4.3.0.991211\lib\net45\Xamarin.Forms.Platform.GTK.dll</HintPath>
<HintPath>..\packages\Xamarin.Forms.Platform.GTK.5.0.0.2012\lib\net45\Xamarin.Forms.Platform.GTK.dll</HintPath>
</Reference>
<Reference Include="System.Reflection">
<HintPath>..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll</HintPath>
@ -168,6 +150,15 @@
<HintPath>..\packages\Autofac.5.0.0\lib\net461\Autofac.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
<Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
<Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
<Reference Include="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
<Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
<Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
<Reference Include="Xamarin.Forms.DataGrid">
<HintPath>..\packages\Xamarin.Forms.DataGrid.4.8.0\lib\netstandard2.0\Xamarin.Forms.DataGrid.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="gtk-gui\gui.stetic">
@ -545,5 +536,5 @@
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Import Project="..\packages\Grpc.Core.2.25.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.2.25.0\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\VideoLAN.LibVLC.Mac.3.1.3.1\build\VideoLAN.LibVLC.Mac.targets" Condition="Exists('..\packages\VideoLAN.LibVLC.Mac.3.1.3.1\build\VideoLAN.LibVLC.Mac.targets')" />
<Import Project="..\packages\Xamarin.Forms.4.3.0.991211\build\Xamarin.Forms.targets" Condition="Exists('..\packages\Xamarin.Forms.4.3.0.991211\build\Xamarin.Forms.targets')" />
<Import Project="..\packages\Xamarin.Forms.5.0.0.2012\build\Xamarin.Forms.targets" Condition="Exists('..\packages\Xamarin.Forms.5.0.0.2012\build\Xamarin.Forms.targets')" />
</Project>

View File

@ -2,6 +2,7 @@
<stetic-interface>
<configuration>
<images-root-path>..</images-root-path>
<target-gtk-version>2.12</target-gtk-version>
</configuration>
<import>
<widget-library name="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />

View File

@ -8,7 +8,7 @@
<package id="Grpc.Core" version="2.25.0" targetFramework="net47" />
<package id="Grpc.Core.Api" version="2.25.0" targetFramework="net47" />
<package id="Grpc.Tools" version="2.25.0" targetFramework="net47" developmentDependency="true" />
<package id="LibVLCSharp" version="3.3.1" targetFramework="net47" />
<package id="LibVLCSharp" version="3.3.1" targetFramework="net47" requireReinstallation="true" />
<package id="LibVLCSharp.Forms" version="3.3.1" targetFramework="net47" />
<package id="LibVLCSharp.Forms.GTK" version="3.3.1" targetFramework="net47" />
<package id="LibVLCSharp.GTK" version="3.3.1" targetFramework="net47" />
@ -25,7 +25,7 @@
<package id="System.Memory" version="4.5.3" targetFramework="net47" />
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net47" />
<package id="System.Reflection" version="4.3.0" targetFramework="net47" />
<package id="System.Reflection.TypeExtensions" version="4.6.0" targetFramework="net47" />
<package id="System.Reflection.TypeExtensions" version="4.6.0" targetFramework="net47" requireReinstallation="true" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net47" />
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net47" />
<package id="System.Runtime.Serialization.Primitives" version="4.3.0" targetFramework="net47" />
@ -34,6 +34,7 @@
<package id="taglib-sharp-netstandard2.0" version="2.1.0" targetFramework="net47" />
<package id="VideoLAN.LibVLC.Mac" version="3.1.3.1" targetFramework="net47" />
<package id="Xam.Plugins.Settings" version="3.1.1" targetFramework="net47" />
<package id="Xamarin.Forms" version="4.3.0.991211" targetFramework="net47" />
<package id="Xamarin.Forms.Platform.GTK" version="4.3.0.991211" targetFramework="net47" />
<package id="Xamarin.Forms" version="5.0.0.2012" targetFramework="net47" />
<package id="Xamarin.Forms.DataGrid" version="4.8.0" targetFramework="net47" />
<package id="Xamarin.Forms.Platform.GTK" version="5.0.0.2012" targetFramework="net47" />
</packages>

View File

@ -5,8 +5,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aurora", "Aurora\Aurora.csp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aurora.gtk", "Aurora.gtk\Aurora.gtk.csproj", "{E8C8C24A-5C51-47CB-B241-F5A9F0E808B1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aurora.test", "Aurora.test\Aurora.test.csproj", "{45680D8A-1AF1-4D93-AAC0-59CDB01CED5D}"
EndProject
#Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aurora.test", "Aurora.test\Aurora.test.csproj", "{45680D8A-1AF1-4D93-AAC0-59CDB01CED5D}"
#EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|iPhoneSimulator = Debug|iPhoneSimulator

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
@ -23,9 +23,6 @@
<ProjectReference Include="..\Aurora\Aurora.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="Resources\Jidenna\The Chief\01 A Bull%27s Tale.mp3">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Jidenna\The Chief\04 Bambi.mp3">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
@ -56,62 +53,11 @@
<None Update="Resources\Jidenna\The Chief\06 Long Live The Chief.mp3">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Jidenna\The Chief\02 Chief Don%27t Run.mp3">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Jidenna\The Chief\11 Little Bit More.mp3">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Jidenna\The Chief\13 White Niggas.mp3">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\16 BDE Bonus %28Prod. By_ ID Labs%29.mp3">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\11 Play Ya Cards %28Prod By_ Chuck Inglish%29.m4a">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\08 All Around The World %28Prod. By_ Just Blaze%29.m4a">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\10 In The Air %28Prod By_ Ritz Reynolds%29.m4a">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\05 I%27ll Be There %28feat. Phonte%29 %28Prod. By_ Beanz %27n%27 Kornbread%29.mp3">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\03 Donald Trump %28Prod. By_ Sap%29.m4a">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\13 Life Ain%27t Easy %28Prod. By_ ID Labs%29.m4a">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\09 Down The Rabbit Hole %28Prod. By_ Blue of The Sore Losers%29.m4a">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\07 Wake Up %28Prod By_ Sap &amp; ID Labs%29.m4a">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\04 Oy Vey %28Prod By_ ID Labs%29.mp3">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\01 Best Day Ever %28Prod. By_ ID Labs%29.m4a">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\02 Get Up %28Prod. By_ Teddy Roxpin%29.m4a">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\14 Snooze %28Prod By_ ID Labs%29.m4a">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\12 She Said %28Prod By_ Khrysis%29.m4a">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\15 Keep Floatin%27 %28feat. Wiz Khalifa%29 %28Prod. By_ ID Labs%29.mp3">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Mac Miller\Best Day Ever\06 Wear My Hat %28Prod. By_ Chuck Inglish%29.m4a">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -5,11 +5,12 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>pdbonly</DebugType>
<OutputPath></OutputPath>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Forms" Version="4.3.0.991211" />
<PackageReference Include="Xamarin.Essentials" Version="1.3.1" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2012" />
<PackageReference Include="Xamarin.Essentials" Version="1.6.1" />
<PackageReference Include="taglib-sharp-netstandard2.0" Version="2.1.0" />
<PackageReference Include="LibVLCSharp.Forms" Version="3.3.1" />
<PackageReference Include="VideoLAN.LibVLC.Mac" Version="3.1.3.1" />
@ -24,6 +25,7 @@
<PackageReference Include="DLToolkit.Forms.Controls.FlowListView" Version="2.0.11" />
<PackageReference Include="CarouselView.FormsPlugin" Version="5.2.0" />
<PackageReference Include="Autofac" Version="5.0.0" />
<PackageReference Include="Xamarin.Forms.DataGrid" Version="4.8.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Design\" />
@ -43,7 +45,6 @@
<Folder Include="Design\Components\MemberList\" />
<Folder Include="Design\Components\Library\" />
<Folder Include="Design\Views\Profile\" />
<Folder Include="Design\Components\DataGrid\" />
<Folder Include="Resources\" />
<Folder Include="Design\Extensions\" />
<Folder Include="Design\Components\ImageButton\" />
@ -60,8 +61,8 @@
</Compile>
</ItemGroup>
<ItemGroup>
<Protobuf Include="Proto\general.proto" />
<Protobuf Include="Proto\party.proto" />
<Protobuf Include="..\..\aurora-proto\Proto\general.proto" />
<Protobuf Include="..\..\aurora-proto\Proto\party.proto" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\backward.png" />

View File

@ -1,8 +0,0 @@
using System.Collections.Generic;
namespace Aurora.Design.Components.DataGrid
{
public sealed class ColumnCollection : List<DataGridColumn>
{
}
}

View File

@ -1,95 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Grid
x:Name="self"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Aurora.Design.Components.DataGrid.DataGrid"
Padding="0"
RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition
Height="Auto"/>
<RowDefinition
Height="*"/>
</Grid.RowDefinitions>
<Grid
x:Name="_headerView"
RowSpacing="0">
<Grid.Resources>
<ResourceDictionary>
<!--Default Header Style-->
<Style
x:Key="HeaderDefaultStyle"
TargetType="Label">
<Setter
Property="FontSize"
Value="{Binding HeaderFontSize, Source={x:Reference self}}"/>
<Setter
Property="FontAttributes"
Value="Bold"/>
<Setter
Property="HorizontalOptions"
Value="Center"/>
<Setter
Property="VerticalOptions"
Value="Center"/>
<Setter
Property="TextColor"
Value="{Binding HeaderTextColor,Source={x:Reference self}}"/>
<Setter
Property="LineBreakMode"
Value="WordWrap"/>
</Style>
<Style
TargetType="Grid">
<Setter
Property="BackgroundColor"
Value="{Binding HeaderBackground,Source={x:Reference self}}"/>
</Style>
<Style
x:Key="ImageStyleBase"
TargetType="Image">
<Setter
Property="Aspect"
Value="AspectFill"/>
<Setter
Property="VerticalOptions"
Value="Center"/>
<Setter
Property="HorizontalOptions"
Value="Center"/>
<Setter
Property="HeightRequest"
Value="5"/>
<Setter
Property="WidthRequest"
Value="9"/>
<Setter
Property="Margin"
Value="0,0,4,0"/>
</Style>
<Style
x:Key="AscendingIconStyle"
TargetType="Image"
BasedOn="{StaticResource ImageStyleBase}">
<Setter
Property="Source"
Value="{Binding AscendingIcon, Source={x:Reference self}}"/>
</Style>
<Style
x:Key="DescendingIconStyle"
TargetType="Image"
BasedOn="{StaticResource ImageStyleBase}">
<Setter
Property="Source"
Value="{Binding DescendingIcon, Source={x:Reference self}}"/>
</Style>
</ResourceDictionary>
</Grid.Resources>
</Grid>
<ListView x:Name="DataList" Grid.Row="1" BackgroundColor="#222222" />
<ContentView
x:Name="_noDataView"
Grid.RowSpan="2"
IsVisible="False"/>
</Grid>

View File

@ -1,756 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Windows.Input;
using Xamarin.Forms;
using Aurora.Utils;
namespace Aurora.Design.Components.DataGrid
{
public partial class DataGrid : Grid
{
#region Private Fields
private ObservableCollection<object> _internalItems;
private Dictionary<int, SortingOrder> _sortingOrders;
#endregion Fields
#region Constructor
public DataGrid() : this(ListViewCachingStrategy.RetainElement)
{
}
public DataGrid(ListViewCachingStrategy cachingStrategy)
{
InitializeComponent();
BackgroundColor = Color.Transparent;
_sortingOrders = new Dictionary<int, SortingOrder>();
DataList.ItemTemplate = new DataGridRowTemplateSelector();
DataList.ItemSelected += (s, e) =>
{
if (SelectionEnabled)
{
SelectedItem = DataList.SelectedItem;
}
else
{
DataList.SelectedItem = null;
}
ItemSelected?.Invoke(this, e);
};
DataList.Refreshing += (s, e) =>
{
Refreshing?.Invoke(this, e);
};
DataList.SetBinding(ListView.RowHeightProperty, new Binding("RowHeight", source: this));
}
#endregion Constructor
#region Public Fields
public event EventHandler Refreshing;
public event EventHandler<SelectedItemChangedEventArgs> ItemSelected;
#endregion Public Fields
#region Bindable properties
public static readonly BindableProperty ActiveRowColorProperty =
BindableProperty.Create(
nameof(ActiveRowColor),
typeof(Color),
typeof(DataGrid),
Color.FromRgb(128, 144, 160),
coerceValue: (bindable, value) =>
{
if (!(bindable as DataGrid).SelectionEnabled)
throw new InvalidOperationException("Datagrid must be SelectionEnabled=true to set ActiveRowColor");
return value;
});
public static readonly BindableProperty HeaderBackgroundProperty =
BindableProperty.Create(
nameof(HeaderBackground),
typeof(Color),
typeof(DataGrid),
Color.White,
propertyChanged: (bindable, oldValue, newValue) =>
{
var self = bindable as DataGrid;
if (self._headerView != null && !self.HeaderBordersVisible)
self._headerView.BackgroundColor = (Color)newValue;
});
public static readonly BindableProperty BorderColorProperty =
BindableProperty.Create(
nameof(BorderColor),
typeof(Color),
typeof(DataGrid),
Color.Black,
propertyChanged: (bindable, oldValue, newValue) =>
{
var self = bindable as DataGrid;
if (self.HeaderBordersVisible)
self._headerView.BackgroundColor = (Color)newValue;
if (self.Columns != null && self.ItemsSource != null)
self.Reload();
});
public static readonly BindableProperty RowsBackgroundColorPaletteProperty =
BindableProperty.Create(nameof(RowsBackgroundColorPalette),
typeof(IColorProvider),
typeof(DataGrid),
new PaletteCollection { default(Color) },
propertyChanged: (bindable, oldValue, newValue) =>
{
var self = bindable as DataGrid;
if (self.Columns != null && self.ItemsSource != null)
self.Reload();
});
public static readonly BindableProperty RowsTextColorPaletteProperty =
BindableProperty.Create(
nameof(RowsTextColorPalette),
typeof(IColorProvider),
typeof(DataGrid),
new PaletteCollection { Color.Black },
propertyChanged: (bindable, oldValue, newValue) =>
{
var self = bindable as DataGrid;
if (self.Columns != null && self.ItemsSource != null)
self.Reload();
});
public static readonly BindableProperty ColumnsProperty =
BindableProperty.Create(
nameof(Columns),
typeof(ColumnCollection),
typeof(DataGrid),
propertyChanged: (bindable, oldValue, newValue) =>
{
(bindable as DataGrid).InitHeaderView();
},
defaultValueCreator: bindable => { return new ColumnCollection(); }
);
public static BindableProperty ItemsSourceProperty =
BindableProperty.Create(
propertyName: nameof(ItemsSource),
returnType: typeof(IEnumerable),
declaringType: typeof(DataGrid),
defaultBindingMode: BindingMode.TwoWay,
propertyChanged: (bindable, oldValue, newValue) =>
{
DataGrid self = bindable as DataGrid;
//ObservableCollection Tracking
if (oldValue != null && oldValue is INotifyCollectionChanged)
{
(oldValue as INotifyCollectionChanged).CollectionChanged -= self.HandleItemsSourceCollectionChanged;
}
if (newValue != null && newValue is INotifyCollectionChanged)
{
(newValue as INotifyCollectionChanged).CollectionChanged += self.HandleItemsSourceCollectionChanged;
self.InternalItems = new ObservableCollection<object>(((IEnumerable<object>)newValue));
//Assign listview item source
self.DataList.ItemsSource = self.InternalItems;
self.DataList.SetBinding(ListView.ItemsSourceProperty, new Binding("ItemsSource", source: self));
}
if (self.SelectedItem != null && !self.InternalItems.Contains(self.SelectedItem))
{
self.SelectedItem = null;
}
if (self.NoDataView != null)
{
if (self.ItemsSource == null || self.InternalItems.Count() == 0)
{
self._noDataView.IsVisible = true;
}
else if (self._noDataView.IsVisible)
{
self._noDataView.IsVisible = false;
}
}
});
private void HandleItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (object item in e.NewItems)
{
InternalItems.Add(item);
}
}
if (e.OldItems != null)
{
foreach (object item in e.OldItems)
{
InternalItems.Remove(item);
}
}
if (SelectedItem != null && !InternalItems.Contains(SelectedItem))
{
SelectedItem = null;
}
}
public static readonly BindableProperty RowHeightProperty =
BindableProperty.Create(nameof(RowHeight), typeof(int), typeof(DataGrid), 40,
propertyChanged: (bindable, oldValue, newValue) =>
{
var self = bindable as DataGrid;
self.DataList.RowHeight = (int)newValue;
});
public static readonly BindableProperty HeaderHeightProperty =
BindableProperty.Create(nameof(HeaderHeight), typeof(int), typeof(DataGrid), 40,
propertyChanged: (bindable, oldValue, newValue) =>
{
var self = bindable as DataGrid;
self._headerView.HeightRequest = (int)newValue;
});
public static readonly BindableProperty IsSortableProperty =
BindableProperty.Create(nameof(IsSortable), typeof(bool), typeof(DataGrid), true);
public static readonly BindableProperty FontSizeProperty =
BindableProperty.Create(nameof(FontSize), typeof(double), typeof(DataGrid), 13.0);
public static readonly BindableProperty FontFamilyProperty =
BindableProperty.Create(
nameof(FontFamily),
typeof(string),
typeof(DataGrid),
Font.Default.FontFamily);
public static readonly BindableProperty SelectedItemProperty =
BindableProperty.Create(
nameof(SelectedItem),
typeof(object),
typeof(DataGrid),
null,
BindingMode.TwoWay,
coerceValue: (bindable, value) =>
{
var self = bindable as DataGrid;
if (!self.SelectionEnabled && value != null)
{
throw new InvalidOperationException("Datagrid must be SelectionEnabled=true to set SelectedItem");
}
if (self.InternalItems != null && self.InternalItems.Contains(value))
{
return value;
}
else
{
return null;
}
},
propertyChanged: (bindable, oldValue, newValue) =>
{
var self = bindable as DataGrid;
if (self.DataList.SelectedItem != newValue)
{
self.DataList.SelectedItem = newValue;
}
}
);
public static readonly BindableProperty SelectionEnabledProperty =
BindableProperty.Create(nameof(SelectionEnabled), typeof(bool), typeof(DataGrid), true,
propertyChanged: (bindable, oldValue, newValue) =>
{
var self = bindable as DataGrid;
if (!self.SelectionEnabled && self.SelectedItem != null)
{
self.SelectedItem = null;
}
});
public static readonly BindableProperty PullToRefreshCommandProperty =
BindableProperty.Create(nameof(PullToRefreshCommand), typeof(ICommand), typeof(DataGrid), null,
propertyChanged: (bindable, oldValue, newValue) =>
{
var self = bindable as DataGrid;
if (newValue == null)
{
self.DataList.IsPullToRefreshEnabled = false;
self.DataList.RefreshCommand = null;
}
else
{
self.DataList.IsPullToRefreshEnabled = true;
self.DataList.RefreshCommand = newValue as ICommand;
}
});
public static readonly BindableProperty IsRefreshingProperty =
BindableProperty.Create(
nameof(IsRefreshing),
typeof(bool),
typeof(DataGrid),
false,
BindingMode.TwoWay,
propertyChanged: (bindable, oldValue, newValue) =>
{
(bindable as DataGrid).DataList.IsRefreshing = (bool)newValue;
});
public static readonly BindableProperty BorderThicknessProperty =
BindableProperty.Create(
nameof(BorderThickness),
typeof(Thickness),
typeof(DataGrid),
new Thickness(1),
propertyChanged: (bindable, oldValue, newValue) =>
{
(bindable as DataGrid)._headerView.ColumnSpacing = ((Thickness)newValue).HorizontalThickness / 2;
(bindable as DataGrid)._headerView.Padding = ((Thickness)newValue).HorizontalThickness / 2;
});
public static readonly BindableProperty HeaderBordersVisibleProperty =
BindableProperty.Create(
nameof(HeaderBordersVisible),
typeof(bool),
typeof(DataGrid),
true,
propertyChanged: (bindable, oldValue, newValue) => (bindable as DataGrid)._headerView.BackgroundColor = (bool)newValue ? (bindable as DataGrid).BorderColor : (bindable as DataGrid).HeaderBackground);
public static readonly BindableProperty SortedColumnIndexProperty =
BindableProperty.Create(
nameof(SortedColumnIndex),
typeof(SortData),
typeof(DataGrid),
null,
BindingMode.TwoWay,
validateValue: (bindable, v) =>
{
var self = bindable as DataGrid;
var sData = (SortData)v;
return
sData == null || //setted to null
self.Columns == null || // Columns binded but not setted
self.Columns.Count == 0 || //columns not setted yet
(sData.Index < self.Columns.Count && self.Columns.ElementAt(sData.Index).SortingEnabled);
},
propertyChanged: (bindable, oldValue, newValue) =>
{
var self = bindable as DataGrid;
if (oldValue != newValue)
self.SortItems((SortData)newValue);
});
public static readonly BindableProperty HeaderLabelStyleProperty =
BindableProperty.Create(nameof(HeaderLabelStyle), typeof(Style), typeof(DataGrid));
public static readonly BindableProperty AscendingIconProperty =
BindableProperty.Create(
nameof(AscendingIcon),
typeof(ImageSource),
typeof(DataGrid),
ImageSource.FromResource("Xamarin.Forms.DataGrid.up.png",
typeof(DataGrid).GetTypeInfo().Assembly));
public static readonly BindableProperty DescendingIconProperty =
BindableProperty.Create(
nameof(DescendingIcon),
typeof(ImageSource),
typeof(DataGrid),
ImageSource.FromResource("Xamarin.Forms.DataGrid.down.png",
typeof(DataGrid).GetTypeInfo().Assembly));
public static readonly BindableProperty DescendingIconStyleProperty =
BindableProperty.Create(nameof(DescendingIconStyle), typeof(Style), typeof(DataGrid), null,
propertyChanged: (bindable, oldValue, newValue) =>
{
var self = bindable as DataGrid;
var style = (newValue as Style).Setters.FirstOrDefault(x => x.Property == Image.SourceProperty);
if (style != null)
{
if (style.Value is string vs)
self.DescendingIcon = ImageSource.FromFile(vs);
else
self.DescendingIcon = (ImageSource)style.Value;
}
});
public static readonly BindableProperty AscendingIconStyleProperty =
BindableProperty.Create(nameof(AscendingIconStyle), typeof(Style), typeof(DataGrid), null,
coerceValue: (bindable, v) =>
{
var self = bindable as DataGrid;
return v;
},
propertyChanged: (bindable, oldValue, newValue) =>
{
var self = bindable as DataGrid;
if ((newValue as Style).Setters.Any(x => x.Property == Image.SourceProperty))
{
var style = (newValue as Style).Setters.FirstOrDefault(x => x.Property == Image.SourceProperty);
if (style != null)
{
if (style.Value is string vs)
self.AscendingIcon = ImageSource.FromFile(vs);
else
self.AscendingIcon = (ImageSource)style.Value;
}
}
});
public static readonly BindableProperty NoDataViewProperty =
BindableProperty.Create(nameof(NoDataView), typeof(View), typeof(DataGrid),
propertyChanged: (bindable, oldValue, newValue) =>
{
if (oldValue != newValue)
(bindable as DataGrid)._noDataView.Content = newValue as View;
});
#endregion
#region Properties
public Color ActiveRowColor
{
get { return (Color)GetValue(ActiveRowColorProperty); }
set { SetValue(ActiveRowColorProperty, value); }
}
public Color HeaderBackground
{
get { return (Color)GetValue(HeaderBackgroundProperty); }
set { SetValue(HeaderBackgroundProperty, value); }
}
[Obsolete("Please use HeaderLabelStyle", true)]
public Color HeaderTextColor
{
get; set;
}
public Color BorderColor
{
get { return (Color)GetValue(BorderColorProperty); }
set { SetValue(BorderColorProperty, value); }
}
public IColorProvider RowsBackgroundColorPalette
{
get { return (IColorProvider)GetValue(RowsBackgroundColorPaletteProperty); }
set { SetValue(RowsBackgroundColorPaletteProperty, value); }
}
public IColorProvider RowsTextColorPalette
{
get { return (IColorProvider)GetValue(RowsTextColorPaletteProperty); }
set { SetValue(RowsTextColorPaletteProperty, value); }
}
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
internal ObservableCollection<object> InternalItems
{
get { return _internalItems; }
set
{
if (value != _internalItems)
{
_internalItems = value;
if (IsSortable && SortedColumnIndex != null)
{
SortItems(SortedColumnIndex);
}
}
DataList.ItemsSource = _internalItems;
}
}
public ColumnCollection Columns
{
get { return (ColumnCollection)GetValue(ColumnsProperty); }
set { SetValue(ColumnsProperty, value); }
}
public double FontSize
{
get { return (double)GetValue(FontSizeProperty); }
set { SetValue(FontSizeProperty, value); }
}
[Obsolete("Please use HeaderLabelStyle", true)]
public double HeaderFontSize
{
get; set;
}
public string FontFamily
{
get { return (string)GetValue(FontFamilyProperty); }
set { SetValue(FontFamilyProperty, value); }
}
public int RowHeight
{
get { return (int)GetValue(RowHeightProperty); }
set { SetValue(RowHeightProperty, value); }
}
public int HeaderHeight
{
get { return (int)GetValue(HeaderHeightProperty); }
set { SetValue(HeaderHeightProperty, value); }
}
public bool IsSortable
{
get { return (bool)GetValue(IsSortableProperty); }
set { SetValue(IsSortableProperty, value); }
}
public bool SelectionEnabled
{
get { return (bool)GetValue(SelectionEnabledProperty); }
set { SetValue(SelectionEnabledProperty, value); }
}
public object SelectedItem
{
get { return GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
public ICommand PullToRefreshCommand
{
get { return (ICommand)GetValue(PullToRefreshCommandProperty); }
set { SetValue(PullToRefreshCommandProperty, value); }
}
public bool IsRefreshing
{
get { return (bool)GetValue(IsRefreshingProperty); }
set { SetValue(IsRefreshingProperty, value); }
}
public Thickness BorderThickness
{
get { return (Thickness)GetValue(BorderThicknessProperty); }
set { SetValue(BorderThicknessProperty, value); }
}
public bool HeaderBordersVisible
{
get { return (bool)GetValue(HeaderBordersVisibleProperty); }
set { SetValue(HeaderBordersVisibleProperty, value); }
}
public SortData SortedColumnIndex
{
get { return (SortData)GetValue(SortedColumnIndexProperty); }
set { SetValue(SortedColumnIndexProperty, value); }
}
public Style HeaderLabelStyle
{
get { return (Style)GetValue(HeaderLabelStyleProperty); }
set { SetValue(HeaderLabelStyleProperty, value); }
}
public ImageSource AscendingIcon
{
get { return (ImageSource)GetValue(AscendingIconProperty); }
set { SetValue(AscendingIconProperty, value); }
}
public ImageSource DescendingIcon
{
get { return (ImageSource)GetValue(DescendingIconProperty); }
set { SetValue(DescendingIconProperty, value); }
}
public Style AscendingIconStyle
{
get { return (Style)GetValue(AscendingIconStyleProperty); }
set { SetValue(AscendingIconStyleProperty, value); }
}
public Style DescendingIconStyle
{
get { return (Style)GetValue(DescendingIconStyleProperty); }
set { SetValue(DescendingIconStyleProperty, value); }
}
public View NoDataView
{
get { return (View)GetValue(NoDataViewProperty); }
set { SetValue(NoDataViewProperty, value); }
}
#endregion
#region UI Methods
protected override void OnParentSet()
{
base.OnParentSet();
InitHeaderView();
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
SetColumnsBindingContext();
}
#endregion
#region Private Methods
private void Reload()
{
InternalItems = new ObservableCollection<object>(_internalItems);
}
private void SortItems(SortData sData)
{
if (InternalItems == null || sData.Index >= Columns.Count || !Columns[sData.Index].SortingEnabled)
return;
var items = InternalItems;
var column = Columns[sData.Index];
SortingOrder order = sData.Order;
if (!IsSortable)
throw new InvalidOperationException("This DataGrid is not sortable");
else if (column.PropertyName == null)
throw new InvalidOperationException("Please set the PropertyName property of Column");
//Sort
// if (order == SortingOrder.Descendant)
// items = items.OrderByDescending(x => ReflectionUtils.GetValueByPath(x, column.PropertyName)).ToList();
// else
// items = items.OrderBy(x => ReflectionUtils.GetValueByPath(x, column.PropertyName)).ToList();
column.SortingIcon.Style = (order == SortingOrder.Descendant) ?
AscendingIconStyle ?? (Style)_headerView.Resources["DescendingIconStyle"] :
DescendingIconStyle ?? (Style)_headerView.Resources["AscendingIconStyle"];
//Support DescendingIcon property (if setted)
if (!column.SortingIcon.Style.Setters.Any(x => x.Property == Image.SourceProperty))
{
if (order == SortingOrder.Descendant && DescendingIconProperty.DefaultValue != DescendingIcon)
column.SortingIcon.Source = DescendingIcon;
if (order == SortingOrder.Ascendant && AscendingIconProperty.DefaultValue != AscendingIcon)
column.SortingIcon.Source = AscendingIcon;
}
for (int i = 0; i < Columns.Count; i++)
{
if (i != sData.Index)
{
if (Columns[i].SortingIcon.Style != null)
Columns[i].SortingIcon.Style = null;
if (Columns[i].SortingIcon.Source != null)
Columns[i].SortingIcon.Source = null;
_sortingOrders[i] = SortingOrder.None;
}
}
_internalItems = items;
_sortingOrders[sData.Index] = order;
SortedColumnIndex = sData;
}
private View GetHeaderViewForColumn(DataGridColumn column)
{
column.HeaderLabel.Style = column.HeaderLabelStyle ?? this.HeaderLabelStyle ?? (Style)_headerView.Resources["HeaderDefaultStyle"];
Grid grid = new Grid
{
ColumnSpacing = 0,
};
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
if (IsSortable)
{
column.SortingIcon.Style = (Style)_headerView.Resources["ImageStyleBase"];
grid.Children.Add(column.SortingIcon);
Grid.SetColumn(column.SortingIcon, 1);
TapGestureRecognizer tgr = new TapGestureRecognizer();
tgr.Tapped += (s, e) =>
{
int index = Columns.IndexOf(column);
SortingOrder order = _sortingOrders[index] == SortingOrder.Ascendant ? SortingOrder.Descendant : SortingOrder.Ascendant;
if (Columns.ElementAt(index).SortingEnabled)
SortedColumnIndex = new SortData(index, order);
};
grid.GestureRecognizers.Add(tgr);
}
grid.Children.Add(column.HeaderLabel);
return grid;
}
private void InitHeaderView()
{
SetColumnsBindingContext();
_headerView.Children.Clear();
_headerView.ColumnDefinitions.Clear();
_sortingOrders.Clear();
_headerView.Padding = new Thickness(BorderThickness.Left, BorderThickness.Top, BorderThickness.Right, 0);
_headerView.ColumnSpacing = BorderThickness.HorizontalThickness / 2;
if (Columns != null)
{
foreach (var col in Columns)
{
_headerView.ColumnDefinitions.Add(new ColumnDefinition { Width = col.Width });
var cell = GetHeaderViewForColumn(col);
_headerView.Children.Add(cell);
Grid.SetColumn(cell, Columns.IndexOf(col));
_sortingOrders.Add(Columns.IndexOf(col), SortingOrder.None);
}
}
}
private void SetColumnsBindingContext()
{
if (Columns != null)
foreach (var c in Columns)
c.BindingContext = BindingContext;
}
#endregion Private Methods
}
}

View File

@ -1,135 +0,0 @@
using System;
using Xamarin.Forms;
namespace Aurora.Design.Components.DataGrid
{
public class DataGridColumn : BindableObject, IDefinition
{
#region bindable properties
public static readonly BindableProperty WidthProperty =
BindableProperty.Create(nameof(Width), typeof(GridLength), typeof(DataGridColumn), new GridLength(1, GridUnitType.Star),
propertyChanged: (bindable, oldValue, newValue) =>
{
if (oldValue != newValue)
{
(bindable as DataGridColumn).OnSizeChanged();
};
});
public static readonly BindableProperty TitleProperty =
BindableProperty.Create(nameof(Title), typeof(string), typeof(DataGridColumn), string.Empty,
propertyChanged: (b, o, n) => (b as DataGridColumn).HeaderLabel.Text = (string)n);
public static readonly BindableProperty FormattedTitleProperty =
BindableProperty.Create(nameof(FormattedTitle), typeof(FormattedString), typeof(DataGridColumn),
propertyChanged: (b, o, n) => (b as DataGridColumn).HeaderLabel.FormattedText = (FormattedString)n);
public static readonly BindableProperty PropertyNameProperty =
BindableProperty.Create(nameof(PropertyName), typeof(string), typeof(DataGridColumn), null);
public static readonly BindableProperty StringFormatProperty =
BindableProperty.Create(nameof(StringFormat), typeof(string), typeof(DataGridColumn), null);
public static readonly BindableProperty CellTemplateProperty =
BindableProperty.Create(nameof(CellTemplate), typeof(DataTemplate), typeof(DataGridColumn), null);
public static readonly BindableProperty HorizontalContentAlignmentProperty =
BindableProperty.Create(nameof(HorizontalContentAlignment), typeof(LayoutOptions), typeof(DataGridColumn), LayoutOptions.Center);
public static readonly BindableProperty VerticalContentAlignmentProperty =
BindableProperty.Create(nameof(VerticalContentAlignment), typeof(LayoutOptions), typeof(DataGridColumn), LayoutOptions.Center);
public static readonly BindableProperty SortingEnabledProperty =
BindableProperty.Create(nameof(SortingEnabled), typeof(bool), typeof(DataGridColumn), true);
public static readonly BindableProperty HeaderLabelStyleProperty =
BindableProperty.Create(nameof(HeaderLabelStyle), typeof(Style), typeof(DataGridColumn),
propertyChanged: (b, o, n) =>
{
if ((b as DataGridColumn).HeaderLabel != null && (o != n))
(b as DataGridColumn).HeaderLabel.Style = n as Style;
});
#endregion
#region properties
public GridLength Width
{
get { return (GridLength)GetValue(WidthProperty); }
set { SetValue(WidthProperty, value); }
}
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public FormattedString FormattedTitle
{
get { return (string)GetValue(FormattedTitleProperty); }
set { SetValue(FormattedTitleProperty, value); }
}
public string PropertyName
{
get { return (string)GetValue(PropertyNameProperty); }
set { SetValue(PropertyNameProperty, value); }
}
public string StringFormat
{
get { return (string)GetValue(StringFormatProperty); }
set { SetValue(StringFormatProperty, value); }
}
public DataTemplate CellTemplate
{
get { return (DataTemplate)GetValue(CellTemplateProperty); }
set { SetValue(CellTemplateProperty, value); }
}
internal Image SortingIcon { get; set; }
internal Label HeaderLabel { get; set; }
public LayoutOptions HorizontalContentAlignment
{
get { return (LayoutOptions)GetValue(HorizontalContentAlignmentProperty); }
set { SetValue(HorizontalContentAlignmentProperty, value); }
}
public LayoutOptions VerticalContentAlignment
{
get { return (LayoutOptions)GetValue(VerticalContentAlignmentProperty); }
set { SetValue(VerticalContentAlignmentProperty, value); }
}
public bool SortingEnabled
{
get { return (bool)GetValue(SortingEnabledProperty); }
set { SetValue(SortingEnabledProperty, value); }
}
public Style HeaderLabelStyle
{
get { return (Style)GetValue(HeaderLabelStyleProperty); }
set { SetValue(HeaderLabelStyleProperty, value); }
}
#endregion
public event EventHandler SizeChanged;
public DataGridColumn()
{
HeaderLabel = new Label();
SortingIcon = new Image();
}
void OnSizeChanged()
{
SizeChanged?.Invoke(this, EventArgs.Empty);
}
}
}

View File

@ -1,30 +0,0 @@
using Xamarin.Forms;
namespace Aurora.Design.Components.DataGrid
{
internal class DataGridRowTemplateSelector : DataTemplateSelector
{
private static DataTemplate _dataGridRowTemplate;
public DataGridRowTemplateSelector()
{
_dataGridRowTemplate = new DataTemplate(typeof(DataGridViewCell));
}
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
ListView listView = container as ListView;
DataGrid dataGrid = listView.Parent as DataGrid;
var items = dataGrid.InternalItems;
_dataGridRowTemplate.SetValue(DataGridViewCell.DataGridProperty, dataGrid);
_dataGridRowTemplate.SetValue(DataGridViewCell.RowContextProperty, item);
if (items != null)
{
_dataGridRowTemplate.SetValue(DataGridViewCell.IndexProperty, items.IndexOf(item));
}
return _dataGridRowTemplate;
}
}
}

View File

@ -1,163 +0,0 @@
using Xamarin.Forms;
namespace Aurora.Design.Components.DataGrid
{
internal sealed class DataGridViewCell : ViewCell
{
#region Fields
Grid _mainLayout;
Color _bgColor;
Color _textColor;
bool _hasSelected;
#endregion
#region properties
public DataGrid DataGrid
{
get { return (DataGrid)GetValue(DataGridProperty); }
set { SetValue(DataGridProperty, value); }
}
public int Index
{
get { return (int)GetValue(IndexProperty); }
set { SetValue(IndexProperty, value); }
}
public object RowContext
{
get { return GetValue(RowContextProperty); }
set { SetValue(RowContextProperty, value); }
}
#endregion
#region Bindable Properties
public static readonly BindableProperty DataGridProperty =
BindableProperty.Create(
nameof(DataGrid),
typeof(DataGrid),
typeof(DataGridViewCell),
null,
propertyChanged: (b, o, n) => (b as DataGridViewCell).CreateView());
public static readonly BindableProperty IndexProperty =
BindableProperty.Create(
nameof(Index),
typeof(int),
typeof(DataGridViewCell),
0,
propertyChanged: (b, o, n) => (b as DataGridViewCell).UpdateBackgroundColor());
public static readonly BindableProperty RowContextProperty =
BindableProperty.Create(
nameof(RowContext),
typeof(object),
typeof(DataGridViewCell),
propertyChanged: (b, o, n) => (b as DataGridViewCell).UpdateBackgroundColor());
#endregion
#region Methods
private void CreateView()
{
UpdateBackgroundColor();
_mainLayout = new Grid()
{
BackgroundColor = DataGrid.BorderColor,
RowSpacing = 0,
ColumnSpacing = DataGrid.BorderThickness.HorizontalThickness / 2,
Padding = new Thickness(DataGrid.BorderThickness.HorizontalThickness / 2,
DataGrid.BorderThickness.VerticalThickness / 2),
};
foreach (var col in DataGrid.Columns)
{
_mainLayout.ColumnDefinitions.Add(new ColumnDefinition() { Width = col.Width });
View cell;
if (col.CellTemplate != null)
{
cell = new ContentView() { Content = col.CellTemplate.CreateContent() as View };
if (col.PropertyName != null)
{
cell.SetBinding(BindingContextProperty,
new Binding(col.PropertyName, source: RowContext));
}
}
else
{
var text = new Label
{
TextColor = _textColor,
HorizontalOptions = col.HorizontalContentAlignment,
VerticalOptions = col.VerticalContentAlignment,
LineBreakMode = LineBreakMode.WordWrap,
};
text.SetBinding(Label.TextProperty, new Binding(col.PropertyName, BindingMode.Default, stringFormat: col.StringFormat));
text.SetBinding(Label.FontSizeProperty, new Binding(DataGrid.FontSizeProperty.PropertyName, BindingMode.Default, source: DataGrid));
text.SetBinding(Label.FontFamilyProperty, new Binding(DataGrid.FontFamilyProperty.PropertyName, BindingMode.Default, source: DataGrid));
cell = new ContentView
{
Padding = 0,
BackgroundColor = _bgColor,
Content = text,
};
}
_mainLayout.Children.Add(cell);
Grid.SetColumn(cell, DataGrid.Columns.IndexOf(col));
}
View = _mainLayout;
}
private void UpdateBackgroundColor()
{
_hasSelected = DataGrid.SelectedItem == RowContext;
int actualIndex = DataGrid?.InternalItems?.IndexOf(BindingContext) ?? -1;
if (actualIndex > -1)
{
_bgColor = (DataGrid.SelectionEnabled && DataGrid.SelectedItem != null && DataGrid.SelectedItem == RowContext) ?
DataGrid.ActiveRowColor : DataGrid.RowsBackgroundColorPalette.GetColor(Index, BindingContext);
_textColor = DataGrid.RowsTextColorPalette.GetColor(actualIndex, BindingContext);
ChangeColor(_bgColor);
}
}
private void ChangeColor(Color color)
{
foreach (var v in _mainLayout.Children)
{
v.BackgroundColor = color;
var contentView = v as ContentView;
if (contentView?.Content is Label)
((Label)contentView.Content).TextColor = _textColor;
}
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
UpdateBackgroundColor();
}
protected override void OnParentSet()
{
base.OnParentSet();
if (Parent != null)
DataGrid.ItemSelected += DataGrid_ItemSelected;
else
DataGrid.ItemSelected -= DataGrid_ItemSelected;
}
private void DataGrid_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
if (DataGrid.SelectionEnabled && (e.SelectedItem == RowContext || _hasSelected))
{
UpdateBackgroundColor();
}
}
#endregion
}
}

View File

@ -1,8 +0,0 @@
using Xamarin.Forms;
namespace Aurora.Design.Components.DataGrid
{
public interface IColorProvider
{
Color GetColor(int rowIndex, object item);
}
}

View File

@ -1,17 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using Xamarin.Forms;
namespace Aurora.Design.Components.DataGrid
{
public sealed class PaletteCollection : List<Color>, IColorProvider
{
public Color GetColor(int rowIndex, object item)
{
if (Count > 0)
return this.ElementAt(rowIndex % Count);
else
return default(Color);
}
}
}

View File

@ -1,51 +0,0 @@
using System;
using Xamarin.Forms;
namespace Aurora.Design.Components.DataGrid
{
[TypeConverter(typeof(SortDataTypeConverter))]
public class SortData
{
#region ctor
public SortData()
{
}
public SortData(int index, SortingOrder order)
{
Index = index;
Order = order;
}
#endregion
#region Properties
public SortingOrder Order { get; set; }
public int Index { get; set; }
#endregion
public static implicit operator SortData(int index)
{
return new SortData
{
Index = Math.Abs(index),
Order = index < 0 ? SortingOrder.Descendant : SortingOrder.Ascendant
};
}
public override bool Equals(object obj)
{
if (obj is SortData)
{
SortData other = obj as SortData;
return other.Index == Index && other.Order == Order;
}
else
return false;
}
}
}

View File

@ -1,24 +0,0 @@
using System;
using Xamarin.Forms;
namespace Aurora.Design.Components.DataGrid
{
public class SortDataTypeConverter : TypeConverter
{
public override bool CanConvertFrom(Type sourceType)
{
return base.CanConvertFrom(sourceType);
}
public override object ConvertFromInvariantString(string value)
{
int index = 0;
if (int.TryParse(value, out index))
return (SortData)index;
else
return null;
}
}
}

View File

@ -1,9 +0,0 @@
namespace Aurora.Design.Components.DataGrid
{
public enum SortingOrder
{
None = 0,
Ascendant = 1,
Descendant = 2,
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

View File

@ -2,7 +2,7 @@
<ContentView
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:dg="clr-namespace:Aurora.Design.Components.DataGrid"
xmlns:dg="clr-namespace:Xamarin.Forms.DataGrid;assembly=Xamarin.Forms.DataGrid"
x:Class="Aurora.Design.Components.Library.Library">
<ContentView.Resources>
<StyleSheet

View File

@ -21,3 +21,16 @@ We are always looking for ways to improve the exerience of the application.
- Aurora Turn Server: The next big step for the application is integrating a custom Aurora turn server so that listeners can connect to one another from different networks while maintaining perfectly synchronized output
- 3rd Party Source Integration: Not everybody has a vast local collection of media that they have been collecting for years. We plan to integrate with 3rd Party music sources such as _Spotify_ and _Apple Music_
## Developers Start Here
### Installation
1. Install dotnet versions 3.1 and 5.0
1. Install mono complete
1. If linux, install gtk-sharp via apt
1. If linux, install libvlc-dev via apt

21
aurora.code-workspace Normal file
View File

@ -0,0 +1,21 @@
{
"folders": [
{
"path": "aurora-sharp-desktop"
},
{
"path": "aurora-cradle-sharp"
},
{
"path": "aurora-proto"
},
{
"path": ".gitea"
}
],
"settings": {
"files.exclude": {
"**/obj": true
}
}
}