Merge branch 'feature/party_list'
This commit is contained in:
commit
fa82c4fa30
@ -158,6 +158,12 @@
|
|||||||
<Reference Include="OpenTK.GLControl">
|
<Reference Include="OpenTK.GLControl">
|
||||||
<HintPath>..\packages\OpenTK.GLControl.3.0.1\lib\net20\OpenTK.GLControl.dll</HintPath>
|
<HintPath>..\packages\OpenTK.GLControl.3.0.1\lib\net20\OpenTK.GLControl.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="DLToolkit.Forms.Controls.FlowListView">
|
||||||
|
<HintPath>..\packages\DLToolkit.Forms.Controls.FlowListView.2.0.11\lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10+netstandard1.0\DLToolkit.Forms.Controls.FlowListView.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="CarouselView.FormsPlugin.Abstractions">
|
||||||
|
<HintPath>..\packages\CarouselView.FormsPlugin.5.2.0\lib\netstandard2.0\CarouselView.FormsPlugin.Abstractions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="gtk-gui\gui.stetic">
|
<EmbeddedResource Include="gtk-gui\gui.stetic">
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using LibVLCSharp.Forms.Shared;
|
using LibVLCSharp.Forms.Shared;
|
||||||
using Xamarin.Forms.Platform.GTK;
|
using Xamarin.Forms.Platform.GTK;
|
||||||
using Xamarin.Forms.Platform.GTK.Helpers;
|
|
||||||
|
|
||||||
namespace Aurora.gtk
|
namespace Aurora.gtk
|
||||||
{
|
{
|
||||||
@ -12,6 +11,8 @@ namespace Aurora.gtk
|
|||||||
{
|
{
|
||||||
Gtk.Application.Init();
|
Gtk.Application.Init();
|
||||||
LibVLCSharpFormsRenderer.Init();
|
LibVLCSharpFormsRenderer.Init();
|
||||||
|
DLToolkit.Forms.Controls.FlowListView.Init();
|
||||||
|
|
||||||
// For some reason, Xamarin does not pick the LibVLCSharp.Form.Platforms.Gtk assembly as a renderer assembly.
|
// For some reason, Xamarin does not pick the LibVLCSharp.Form.Platforms.Gtk assembly as a renderer assembly.
|
||||||
// Add it manually.
|
// Add it manually.
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
|
<package id="CarouselView.FormsPlugin" version="5.2.0" targetFramework="net47" />
|
||||||
|
<package id="DLToolkit.Forms.Controls.FlowListView" version="2.0.11" targetFramework="net47" />
|
||||||
<package id="Google.Protobuf" version="3.10.1" targetFramework="net47" />
|
<package id="Google.Protobuf" version="3.10.1" targetFramework="net47" />
|
||||||
<package id="Grpc" version="2.25.0" targetFramework="net47" />
|
<package id="Grpc" version="2.25.0" targetFramework="net47" />
|
||||||
<package id="Grpc.Core" version="2.25.0" targetFramework="net47" />
|
<package id="Grpc.Core" version="2.25.0" targetFramework="net47" />
|
||||||
|
7
Aurora/App.css
Normal file
7
Aurora/App.css
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.primaryColor {
|
||||||
|
background-color: #232323;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accentColor {
|
||||||
|
background-color: #3a3a3a;
|
||||||
|
}
|
@ -24,6 +24,8 @@
|
|||||||
x:Key="InverseBoolConverter"/>
|
x:Key="InverseBoolConverter"/>
|
||||||
<converters:ToUpperConverter
|
<converters:ToUpperConverter
|
||||||
x:Key="ToUpperConverter"/>
|
x:Key="ToUpperConverter"/>
|
||||||
|
<StyleSheet
|
||||||
|
Source="App.css"/>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</Application.Resources>
|
</Application.Resources>
|
||||||
</Application>
|
</Application>
|
@ -21,6 +21,8 @@
|
|||||||
<PackageReference Include="Google.Protobuf" Version="3.10.1" />
|
<PackageReference Include="Google.Protobuf" Version="3.10.1" />
|
||||||
<PackageReference Include="Xam.Plugins.Settings" Version="3.1.1" />
|
<PackageReference Include="Xam.Plugins.Settings" Version="3.1.1" />
|
||||||
<PackageReference Include="Sharpnado.Forms.HorizontalListView" Version="1.3.0" />
|
<PackageReference Include="Sharpnado.Forms.HorizontalListView" Version="1.3.0" />
|
||||||
|
<PackageReference Include="DLToolkit.Forms.Controls.FlowListView" Version="2.0.11" />
|
||||||
|
<PackageReference Include="CarouselView.FormsPlugin" Version="5.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Design\" />
|
<Folder Include="Design\" />
|
||||||
@ -37,7 +39,6 @@
|
|||||||
<Folder Include="Models\" />
|
<Folder Include="Models\" />
|
||||||
<Folder Include="Services\" />
|
<Folder Include="Services\" />
|
||||||
<Folder Include="Design\Views\Party\" />
|
<Folder Include="Design\Views\Party\" />
|
||||||
<Folder Include="Design\Components\HostSelector\" />
|
|
||||||
<Folder Include="Design\Components\MemberList\" />
|
<Folder Include="Design\Components\MemberList\" />
|
||||||
<Folder Include="Design\Components\Library\" />
|
<Folder Include="Design\Components\Library\" />
|
||||||
<Folder Include="Design\Views\Profile\" />
|
<Folder Include="Design\Views\Profile\" />
|
||||||
@ -47,6 +48,7 @@
|
|||||||
<Folder Include="Design\Components\ImageButton\" />
|
<Folder Include="Design\Components\ImageButton\" />
|
||||||
<Folder Include="Design\Components\Dialogs\" />
|
<Folder Include="Design\Components\Dialogs\" />
|
||||||
<Folder Include="Design\Views\Party\NewPartyDialog\" />
|
<Folder Include="Design\Views\Party\NewPartyDialog\" />
|
||||||
|
<Folder Include="Design\Components\TabView\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="Design\Behaviors\DeselectItemBehaviorBase.cs" />
|
<Compile Remove="Design\Behaviors\DeselectItemBehaviorBase.cs" />
|
||||||
|
12
Aurora/Design/Components/MemberList/MemberList.css
Normal file
12
Aurora/Design/Components/MemberList/MemberList.css
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
Frame {
|
||||||
|
margin-left: 20;
|
||||||
|
margin-right: 20;
|
||||||
|
margin-top: 20;
|
||||||
|
margin-bottom: 20;
|
||||||
|
width: 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
Frame Label {
|
||||||
|
color: black;
|
||||||
|
background-color: white;
|
||||||
|
}
|
@ -3,23 +3,30 @@
|
|||||||
xmlns="http://xamarin.com/schemas/2014/forms"
|
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
xmlns:hl="clr-namespace:Aurora.Design.Components.HorizontalList"
|
xmlns:hl="clr-namespace:Aurora.Design.Components.HorizontalList"
|
||||||
|
xmlns:flv="clr-namespace:DLToolkit.Forms.Controls;assembly=DLToolkit.Forms.Controls.FlowListView"
|
||||||
x:Class="Aurora.Design.Components.MemberList.MemberList">
|
x:Class="Aurora.Design.Components.MemberList.MemberList">
|
||||||
|
<ContentView.Resources>
|
||||||
|
<StyleSheet
|
||||||
|
Source="./MemberList.css"/>
|
||||||
|
</ContentView.Resources>
|
||||||
<ContentView.Content>
|
<ContentView.Content>
|
||||||
<StackLayout>
|
<flv:FlowListView
|
||||||
<hl:HorizontalList
|
x:Name="MembersList"
|
||||||
BackgroundColor="Red"
|
FlowColumnCount="8"
|
||||||
x:Name="MembersHorizontalList"
|
RowHeight="150"
|
||||||
ListOrientation="Horizontal"
|
VerticalOptions="FillAndExpand"
|
||||||
VerticalOptions="Start">
|
SeparatorVisibility="None"
|
||||||
<hl:HorizontalList.ItemTemplate>
|
HasUnevenRows="false"
|
||||||
|
StyleClass="accentColor">
|
||||||
|
<flv:FlowListView.FlowColumnTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Frame>
|
<Frame>
|
||||||
<Label
|
<Label
|
||||||
Text="{Binding UserName}"/>
|
Text="{Binding UserName}"
|
||||||
|
TextColor="White"/>
|
||||||
</Frame>
|
</Frame>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</hl:HorizontalList.ItemTemplate>
|
</flv:FlowListView.FlowColumnTemplate>
|
||||||
</hl:HorizontalList>
|
</flv:FlowListView>
|
||||||
</StackLayout>
|
|
||||||
</ContentView.Content>
|
</ContentView.Content>
|
||||||
</ContentView>
|
</ContentView>
|
@ -1,16 +1,16 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
|
using System.Collections;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Aurora.Proto.Party;
|
using Aurora.Proto.Party;
|
||||||
|
using DLToolkit.Forms.Controls;
|
||||||
|
|
||||||
namespace Aurora.Design.Components.MemberList
|
namespace Aurora.Design.Components.MemberList
|
||||||
{
|
{
|
||||||
public partial class MemberList : ContentView
|
public partial class MemberList : ContentView
|
||||||
{
|
{
|
||||||
private static ObservableCollection<PartyMember> _newSource;
|
|
||||||
// private static NotifyCollectionChangedEventHandler _collectionChangedHandler;
|
|
||||||
public MemberList()
|
public MemberList()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@ -55,60 +55,11 @@ namespace Aurora.Design.Components.MemberList
|
|||||||
private static void OnMembersChanged(BindableObject bindable, object oldValue, object newValue)
|
private static void OnMembersChanged(BindableObject bindable, object oldValue, object newValue)
|
||||||
{
|
{
|
||||||
var control = (MemberList)bindable;
|
var control = (MemberList)bindable;
|
||||||
var membersList = control.FindByName("MembersHorizontalList") as HorizontalList.HorizontalList;
|
var membersList = control.FindByName("MembersList") as FlowListView;
|
||||||
if (membersList != null)
|
|
||||||
{
|
|
||||||
_newSource = newValue as ObservableCollection<PartyMember>;
|
|
||||||
membersList.ItemsSource = new ObservableCollection<object>(_newSource);
|
|
||||||
|
|
||||||
//Setup collection changed listeners
|
if (newValue is ICollection source)
|
||||||
//TODO evaluate for memory leak
|
|
||||||
_newSource.CollectionChanged += (sender, e) => HandleCollectionChanged(sender, e, bindable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e, BindableObject bindable)
|
|
||||||
{
|
{
|
||||||
MemberList self = bindable as MemberList;
|
membersList.FlowItemsSource = source;
|
||||||
var membersList = self.FindByName("MembersHorizontalList") as HorizontalList.HorizontalList;
|
|
||||||
|
|
||||||
switch (e.Action)
|
|
||||||
{
|
|
||||||
case NotifyCollectionChangedAction.Add:
|
|
||||||
{
|
|
||||||
foreach (PartyMember member in e.NewItems)
|
|
||||||
{
|
|
||||||
membersList.ItemsSource.Add(member);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NotifyCollectionChangedAction.Remove:
|
|
||||||
{
|
|
||||||
foreach (PartyMember member in e.NewItems)
|
|
||||||
{
|
|
||||||
//Find all matches
|
|
||||||
var sourceMembers = membersList.ItemsSource.Where((object obj) =>
|
|
||||||
{
|
|
||||||
bool match = false;
|
|
||||||
if (obj is PartyMember)
|
|
||||||
{
|
|
||||||
PartyMember tmp = obj as PartyMember;
|
|
||||||
match = tmp.Id == member.Id;
|
|
||||||
}
|
|
||||||
|
|
||||||
return match;
|
|
||||||
});
|
|
||||||
|
|
||||||
//Remove found matches
|
|
||||||
foreach (object obj in sourceMembers)
|
|
||||||
{
|
|
||||||
membersList.ItemsSource.Remove(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
111
Aurora/Design/Components/TabView/TabItem.cs
Normal file
111
Aurora/Design/Components/TabView/TabItem.cs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Aurora.Design.Components.TabView
|
||||||
|
{
|
||||||
|
[ContentProperty(nameof(Content))]
|
||||||
|
public class TabItem : BindableObject
|
||||||
|
{
|
||||||
|
public TabItem()
|
||||||
|
{
|
||||||
|
//Parameterless constructor required for xaml instantiation.
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TriggerPropertyChange(string propertyName = null)
|
||||||
|
{
|
||||||
|
base.OnPropertyChanged(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TabItem(string headerText, View content, ImageSource headerIcon = null)
|
||||||
|
{
|
||||||
|
HeaderText = headerText;
|
||||||
|
Content = content;
|
||||||
|
if (headerIcon != null)
|
||||||
|
HeaderIcon = headerIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly BindableProperty HeaderIconProperty = BindableProperty.Create(nameof(HeaderIcon), typeof(ImageSource), typeof(TabItem));
|
||||||
|
public ImageSource HeaderIcon
|
||||||
|
{
|
||||||
|
get => (ImageSource)GetValue(HeaderIconProperty);
|
||||||
|
set { SetValue(HeaderIconProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly BindableProperty HeaderIconSizeProperty = BindableProperty.Create(nameof(HeaderIconSize), typeof(double), typeof(TabItem), 32.0);
|
||||||
|
public double HeaderIconSize
|
||||||
|
{
|
||||||
|
get => (double)GetValue(HeaderIconSizeProperty);
|
||||||
|
set { SetValue(HeaderIconSizeProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly BindableProperty HeaderTextProperty = BindableProperty.Create(nameof(HeaderText), typeof(string), typeof(TabItem), string.Empty);
|
||||||
|
public string HeaderText
|
||||||
|
{
|
||||||
|
get => (string)GetValue(HeaderTextProperty);
|
||||||
|
set { SetValue(HeaderTextProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly BindableProperty ContentProperty = BindableProperty.Create(nameof(Content), typeof(View), typeof(TabItem));
|
||||||
|
public View Content
|
||||||
|
{
|
||||||
|
get => (View)GetValue(ContentProperty);
|
||||||
|
set { SetValue(ContentProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly BindableProperty IsCurrentProperty = BindableProperty.Create(nameof(IsCurrent), typeof(bool), typeof(TabItem), false);
|
||||||
|
public bool IsCurrent
|
||||||
|
{
|
||||||
|
get => (bool)GetValue(IsCurrentProperty);
|
||||||
|
set { SetValue(IsCurrentProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly BindableProperty HeaderTextColorProperty = BindableProperty.Create(nameof(HeaderTextColor), typeof(Color), typeof(TabItem), Color.White);
|
||||||
|
public Color HeaderTextColor
|
||||||
|
{
|
||||||
|
get => (Color)GetValue(HeaderTextColorProperty);
|
||||||
|
set { SetValue(HeaderTextColorProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly BindableProperty HeaderSelectionUnderlineColorProperty = BindableProperty.Create(nameof(HeaderSelectionUnderlineColor), typeof(Color), typeof(TabItem), Color.Transparent);
|
||||||
|
public Color HeaderSelectionUnderlineColor
|
||||||
|
{
|
||||||
|
get => (Color)GetValue(HeaderSelectionUnderlineColorProperty);
|
||||||
|
set { SetValue(HeaderSelectionUnderlineColorProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly BindableProperty HeaderSelectionUnderlineThicknessProperty = BindableProperty.Create(nameof(HeaderSelectionUnderlineThickness), typeof(double), typeof(TabItem), (double)5);
|
||||||
|
public double HeaderSelectionUnderlineThickness
|
||||||
|
{
|
||||||
|
get => (double)GetValue(HeaderSelectionUnderlineThicknessProperty);
|
||||||
|
set { SetValue(HeaderSelectionUnderlineThicknessProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly BindableProperty HeaderSelectionUnderlineWidthProperty = BindableProperty.Create(nameof(HeaderSelectionUnderlineWidth), typeof(double), typeof(TabItem), (double)40);
|
||||||
|
public double HeaderSelectionUnderlineWidth
|
||||||
|
{
|
||||||
|
get => (double)GetValue(HeaderSelectionUnderlineWidthProperty);
|
||||||
|
set { SetValue(HeaderSelectionUnderlineWidthProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly BindableProperty HeaderTabTextFontSizeProperty = BindableProperty.Create(nameof(HeaderTabTextFontSize), typeof(double), typeof(TabItem), TabDefaults.DefaultTextSize);
|
||||||
|
[TypeConverter(typeof(FontSizeConverter))]
|
||||||
|
public double HeaderTabTextFontSize
|
||||||
|
{
|
||||||
|
get => (double)GetValue(HeaderTabTextFontSizeProperty);
|
||||||
|
set { SetValue(HeaderTabTextFontSizeProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly BindableProperty HeaderTabTextFontFamilyProperty = BindableProperty.Create(nameof(HeaderTabTextFontFamily), typeof(string), typeof(TabItem));
|
||||||
|
public string HeaderTabTextFontFamily
|
||||||
|
{
|
||||||
|
get => (string)GetValue(HeaderTabTextFontFamilyProperty);
|
||||||
|
set { SetValue(HeaderTabTextFontFamilyProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly BindableProperty HeaderTabTextFontAttributesProperty = BindableProperty.Create(nameof(HeaderTabTextFontAttributes), typeof(FontAttributes), typeof(TabItem), FontAttributes.None);
|
||||||
|
public FontAttributes HeaderTabTextFontAttributes
|
||||||
|
{
|
||||||
|
get => (FontAttributes)GetValue(HeaderTabTextFontAttributesProperty);
|
||||||
|
set { SetValue(HeaderTabTextFontAttributesProperty, value); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
554
Aurora/Design/Components/TabView/TabView.cs
Normal file
554
Aurora/Design/Components/TabView/TabView.cs
Normal file
@ -0,0 +1,554 @@
|
|||||||
|
// using CarouselView.FormsPlugin.Abstractions;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Aurora.Design.Converters;
|
||||||
|
|
||||||
|
namespace Aurora.Design.Components.TabView
|
||||||
|
{
|
||||||
|
public delegate void PositionChangingEventHandler(object sender, TabChangingEventArgs e);
|
||||||
|
public delegate void PositionChangedEventHandler(object sender, TabChangedEventArgs e);
|
||||||
|
|
||||||
|
public class TabChangingEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public bool Canceled { get; set; }
|
||||||
|
public int NewPosition { get; set; }
|
||||||
|
public int OldPosition { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TabChangedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public int NewPosition { get; set; }
|
||||||
|
public int OldPosition { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TabDefaults
|
||||||
|
{
|
||||||
|
public static readonly Color DefaultColor = Color.White;
|
||||||
|
public const double DefaultThickness = 5;
|
||||||
|
public const double DefaultTextSize = 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TabViewControl : ContentView
|
||||||
|
{
|
||||||
|
private StackLayout _mainContainerSL;
|
||||||
|
private Grid _headerContainerGrid;
|
||||||
|
private ScrollView _tabHeadersContainerSv;
|
||||||
|
|
||||||
|
public event PositionChangingEventHandler PositionChanging;
|
||||||
|
public event PositionChangedEventHandler PositionChanged;
|
||||||
|
|
||||||
|
protected virtual void OnTabChanging(ref TabChangingEventArgs e)
|
||||||
|
{
|
||||||
|
PositionChangingEventHandler handler = PositionChanging;
|
||||||
|
handler?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnTabChanged(TabChangedEventArgs e)
|
||||||
|
{
|
||||||
|
PositionChangedEventHandler handler = PositionChanged;
|
||||||
|
handler?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TabViewControl()
|
||||||
|
{
|
||||||
|
//Parameterless constructor required for xaml instantiation.
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TabViewControl(IList<TabItem> tabItems, int selectedTabIndex = 0)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
foreach (var tab in tabItems)
|
||||||
|
{
|
||||||
|
ItemSource.Add(tab);
|
||||||
|
}
|
||||||
|
if (selectedTabIndex > 0)
|
||||||
|
{
|
||||||
|
SelectedTabIndex = selectedTabIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemSource_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.NewItems != null)
|
||||||
|
{
|
||||||
|
foreach (var tab in e.NewItems)
|
||||||
|
{
|
||||||
|
if (tab is TabItem newTab)
|
||||||
|
{
|
||||||
|
SetTabProps(newTab);
|
||||||
|
AddTabToView(newTab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetTabProps(TabItem tab)
|
||||||
|
{
|
||||||
|
//Set the tab properties from the main control only if not set in xaml at the individual tab level.
|
||||||
|
if (tab.HeaderTextColor == TabDefaults.DefaultColor && HeaderTabTextColor != TabDefaults.DefaultColor)
|
||||||
|
tab.HeaderTextColor = HeaderTabTextColor;
|
||||||
|
if (tab.HeaderSelectionUnderlineColor == TabDefaults.DefaultColor && HeaderSelectionUnderlineColor != TabDefaults.DefaultColor)
|
||||||
|
tab.HeaderSelectionUnderlineColor = HeaderSelectionUnderlineColor;
|
||||||
|
if (tab.HeaderSelectionUnderlineThickness.Equals(TabDefaults.DefaultThickness) && !HeaderSelectionUnderlineThickness.Equals(TabDefaults.DefaultThickness))
|
||||||
|
tab.HeaderSelectionUnderlineThickness = HeaderSelectionUnderlineThickness;
|
||||||
|
if (tab.HeaderSelectionUnderlineWidth > 0)
|
||||||
|
tab.HeaderSelectionUnderlineWidth = HeaderSelectionUnderlineWidth;
|
||||||
|
if (tab.HeaderTabTextFontSize.Equals(TabDefaults.DefaultTextSize) && !HeaderTabTextFontSize.Equals(TabDefaults.DefaultTextSize))
|
||||||
|
tab.HeaderTabTextFontSize = HeaderTabTextFontSize;
|
||||||
|
if (tab.HeaderTabTextFontFamily is null && !string.IsNullOrWhiteSpace(HeaderTabTextFontFamily))
|
||||||
|
tab.HeaderTabTextFontFamily = HeaderTabTextFontFamily;
|
||||||
|
if (tab.HeaderTabTextFontAttributes == FontAttributes.None && HeaderTabTextFontAttributes != FontAttributes.None)
|
||||||
|
tab.HeaderTabTextFontAttributes = HeaderTabTextFontAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Init()
|
||||||
|
{
|
||||||
|
ItemSource = new ObservableCollection<TabItem>();
|
||||||
|
|
||||||
|
_headerContainerGrid = new Grid
|
||||||
|
{
|
||||||
|
HorizontalOptions = LayoutOptions.FillAndExpand,
|
||||||
|
VerticalOptions = LayoutOptions.Start,
|
||||||
|
// BackgroundColor = Color.White, // tab sepeartor color
|
||||||
|
MinimumHeightRequest = 50,
|
||||||
|
ColumnSpacing = 0, // seperator thickness
|
||||||
|
};
|
||||||
|
|
||||||
|
_tabHeadersContainerSv = new ScrollView()
|
||||||
|
{
|
||||||
|
HorizontalScrollBarVisibility = ScrollBarVisibility.Never,
|
||||||
|
Orientation = ScrollOrientation.Horizontal,
|
||||||
|
Content = _headerContainerGrid,
|
||||||
|
BackgroundColor = HeaderBackgroundColor,
|
||||||
|
HorizontalOptions = LayoutOptions.FillAndExpand
|
||||||
|
};
|
||||||
|
|
||||||
|
_mainContainerSL = new StackLayout
|
||||||
|
{
|
||||||
|
HorizontalOptions = LayoutOptions.FillAndExpand,
|
||||||
|
VerticalOptions = LayoutOptions.FillAndExpand,
|
||||||
|
Children = { _tabHeadersContainerSv },
|
||||||
|
Spacing = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
Content = _mainContainerSL;
|
||||||
|
ItemSource.CollectionChanged += ItemSource_CollectionChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnBindingContextChanged()
|
||||||
|
{
|
||||||
|
base.OnBindingContextChanged();
|
||||||
|
if (BindingContext != null)
|
||||||
|
{
|
||||||
|
foreach (var tab in ItemSource)
|
||||||
|
{
|
||||||
|
if (tab is TabItem view)
|
||||||
|
{
|
||||||
|
view.Content.BindingContext = BindingContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetCurrentTab(0, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddTabToView(TabItem tab)
|
||||||
|
{
|
||||||
|
var tabSize = (TabSizeOption.IsAbsolute && TabSizeOption.Value.Equals(0)) ? new GridLength(1, GridUnitType.Star) : TabSizeOption;
|
||||||
|
|
||||||
|
_headerContainerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = tabSize });
|
||||||
|
|
||||||
|
tab.IsCurrent = _headerContainerGrid.ColumnDefinitions.Count - 1 == SelectedTabIndex;
|
||||||
|
|
||||||
|
var headerIcon = new Image
|
||||||
|
{
|
||||||
|
Margin = new Thickness(0, 8, 0, 0),
|
||||||
|
BindingContext = tab,
|
||||||
|
HorizontalOptions = LayoutOptions.CenterAndExpand,
|
||||||
|
VerticalOptions = LayoutOptions.Center,
|
||||||
|
WidthRequest = tab.HeaderIconSize,
|
||||||
|
HeightRequest = tab.HeaderIconSize
|
||||||
|
};
|
||||||
|
headerIcon.SetBinding(Image.SourceProperty, nameof(TabItem.HeaderIcon));
|
||||||
|
headerIcon.SetBinding(IsVisibleProperty, nameof(TabItem.HeaderIcon), converter: new NullToBoolConverter());
|
||||||
|
|
||||||
|
var headerLabel = new Label
|
||||||
|
{
|
||||||
|
BindingContext = tab,
|
||||||
|
VerticalTextAlignment = TextAlignment.Center,
|
||||||
|
HorizontalTextAlignment = TextAlignment.Center,
|
||||||
|
HorizontalOptions = LayoutOptions.Center,
|
||||||
|
VerticalOptions = LayoutOptions.CenterAndExpand,
|
||||||
|
Margin = new Thickness(5, 8, 5, 5)
|
||||||
|
};
|
||||||
|
|
||||||
|
headerLabel.SetBinding(Label.TextProperty, nameof(TabItem.HeaderText));
|
||||||
|
headerLabel.SetBinding(Label.TextColorProperty, nameof(TabItem.HeaderTextColor));
|
||||||
|
headerLabel.SetBinding(Label.FontSizeProperty, nameof(TabItem.HeaderTabTextFontSize));
|
||||||
|
headerLabel.SetBinding(Label.FontFamilyProperty, nameof(TabItem.HeaderTabTextFontFamily));
|
||||||
|
headerLabel.SetBinding(Label.FontAttributesProperty, nameof(TabItem.HeaderTabTextFontAttributes));
|
||||||
|
headerLabel.SetBinding(IsVisibleProperty, nameof(TabItem.HeaderText), converter: new NullToBoolConverter());
|
||||||
|
|
||||||
|
var selectionBarBoxView = new BoxView
|
||||||
|
{
|
||||||
|
VerticalOptions = LayoutOptions.End,
|
||||||
|
BindingContext = tab,
|
||||||
|
HeightRequest = HeaderSelectionUnderlineThickness,
|
||||||
|
WidthRequest = HeaderSelectionUnderlineWidth
|
||||||
|
};
|
||||||
|
var underlineColorBinding = new Binding(nameof(TabItem.IsCurrent), BindingMode.OneWay, new SelectedTabHeaderToTabBackgroundColorConverter(), this);
|
||||||
|
selectionBarBoxView.SetBinding(BoxView.BackgroundColorProperty, underlineColorBinding);
|
||||||
|
|
||||||
|
selectionBarBoxView.SetBinding(WidthRequestProperty, nameof(TabItem.HeaderSelectionUnderlineWidth));
|
||||||
|
selectionBarBoxView.SetBinding(HeightRequestProperty, nameof(TabItem.HeaderSelectionUnderlineThickness));
|
||||||
|
selectionBarBoxView.SetBinding(HorizontalOptionsProperty,
|
||||||
|
nameof(TabItem.HeaderSelectionUnderlineWidthProperty),
|
||||||
|
converter: new DoubleToLayoutOptionsConverter());
|
||||||
|
|
||||||
|
selectionBarBoxView.PropertyChanged += (object sender, PropertyChangedEventArgs e) =>
|
||||||
|
{
|
||||||
|
if (e.PropertyName == nameof(TabItem.IsCurrent))
|
||||||
|
{
|
||||||
|
SetCurrentTab(ItemSource.IndexOf((TabItem)((BoxView)sender).BindingContext));
|
||||||
|
}
|
||||||
|
if (e.PropertyName == nameof(WidthRequest))
|
||||||
|
{
|
||||||
|
selectionBarBoxView.HorizontalOptions = tab.HeaderSelectionUnderlineWidth > 0 ? LayoutOptions.CenterAndExpand : LayoutOptions.FillAndExpand;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var headerItemSL = new StackLayout
|
||||||
|
{
|
||||||
|
VerticalOptions = LayoutOptions.FillAndExpand,
|
||||||
|
Children = { headerIcon, headerLabel, selectionBarBoxView },
|
||||||
|
BackgroundColor = HeaderBackgroundColor,
|
||||||
|
Spacing = 0
|
||||||
|
};
|
||||||
|
var tapRecognizer = new TapGestureRecognizer();
|
||||||
|
|
||||||
|
tapRecognizer.Tapped += (object s, EventArgs e) =>
|
||||||
|
{
|
||||||
|
var capturedIndex = _headerContainerGrid.Children.IndexOf((View)s);
|
||||||
|
SetCurrentTab(capturedIndex);
|
||||||
|
};
|
||||||
|
|
||||||
|
headerItemSL.GestureRecognizers.Add(tapRecognizer);
|
||||||
|
_headerContainerGrid.Children.Add(headerItemSL, _headerContainerGrid.ColumnDefinitions.Count - 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region HeaderBackgroundColor
|
||||||
|
public Color HeaderBackgroundColor
|
||||||
|
{
|
||||||
|
get { return (Color)GetValue(HeaderBackgroundColorProperty); }
|
||||||
|
set { SetValue(HeaderBackgroundColorProperty, value); }
|
||||||
|
}
|
||||||
|
private static void HeaderBackgroundColorChanged(BindableObject bindable, object oldValue, object newValue)
|
||||||
|
{
|
||||||
|
if (bindable is TabViewControl tabViewControl)
|
||||||
|
{
|
||||||
|
tabViewControl._tabHeadersContainerSv.BackgroundColor = (Color)newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static readonly BindableProperty HeaderBackgroundColorProperty = BindableProperty.Create(nameof(HeaderBackgroundColor), typeof(Color), typeof(TabViewControl), Color.SkyBlue, BindingMode.Default, null, HeaderBackgroundColorChanged);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region HeaderTabTextColor
|
||||||
|
public Color HeaderTabTextColor
|
||||||
|
{
|
||||||
|
get { return (Color)GetValue(HeaderTabTextColorProperty); }
|
||||||
|
set { SetValue(HeaderTabTextColorProperty, value); }
|
||||||
|
}
|
||||||
|
private static void HeaderTabTextColorChanged(BindableObject bindable, object oldValue, object newValue)
|
||||||
|
{
|
||||||
|
if (bindable is TabViewControl tabViewControl && tabViewControl.ItemSource != null)
|
||||||
|
{
|
||||||
|
foreach (var tab in tabViewControl.ItemSource)
|
||||||
|
{
|
||||||
|
tab.HeaderTextColor = (Color)newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static readonly BindableProperty HeaderTabTextColorProperty =
|
||||||
|
BindableProperty.Create(nameof(HeaderTabTextColor), typeof(Color), typeof(TabViewControl), TabDefaults.DefaultColor, BindingMode.OneWay, null, HeaderTabTextColorChanged);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ContentHeight
|
||||||
|
public double ContentHeight
|
||||||
|
{
|
||||||
|
get { return (double)GetValue(ContentHeightProperty); }
|
||||||
|
set { SetValue(ContentHeightProperty, value); }
|
||||||
|
}
|
||||||
|
private static void ContentHeightChanged(BindableObject bindable, object oldValue, object newValue)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
// if (bindable is TabViewControl tabViewControl && tabViewControl._carouselView != null)
|
||||||
|
// {
|
||||||
|
// tabViewControl._carouselView.HeightRequest = (double)newValue;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
public static readonly BindableProperty ContentHeightProperty = BindableProperty.Create(nameof(ContentHeight), typeof(double), typeof(TabViewControl), (double)200, BindingMode.Default, null, ContentHeightChanged);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region HeaderSelectionUnderlineColor
|
||||||
|
public Color HeaderSelectionUnderlineColor
|
||||||
|
{
|
||||||
|
get { return (Color)GetValue(HeaderSelectionUnderlineColorProperty); }
|
||||||
|
set { SetValue(HeaderSelectionUnderlineColorProperty, value); }
|
||||||
|
}
|
||||||
|
private static void HeaderSelectionUnderlineColorChanged(BindableObject bindable, object oldValue, object newValue)
|
||||||
|
{
|
||||||
|
if (bindable is TabViewControl tabViewControl && tabViewControl.ItemSource != null)
|
||||||
|
{
|
||||||
|
foreach (var tab in tabViewControl.ItemSource)
|
||||||
|
{
|
||||||
|
tab.HeaderSelectionUnderlineColor = (Color)newValue;
|
||||||
|
tab.TriggerPropertyChange(nameof(tab.IsCurrent));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static readonly BindableProperty HeaderSelectionUnderlineColorProperty = BindableProperty.Create(nameof(HeaderSelectionUnderlineColor), typeof(Color), typeof(TabViewControl), Color.White, BindingMode.Default, null, HeaderSelectionUnderlineColorChanged);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region HeaderSelectionUnderlineThickness
|
||||||
|
public double HeaderSelectionUnderlineThickness
|
||||||
|
{
|
||||||
|
get { return (double)GetValue(HeaderSelectionUnderlineThicknessProperty); }
|
||||||
|
set { SetValue(HeaderSelectionUnderlineThicknessProperty, value); }
|
||||||
|
}
|
||||||
|
private static void HeaderSelectionUnderlineThicknessChanged(BindableObject bindable, object oldValue, object newValue)
|
||||||
|
{
|
||||||
|
if (bindable is TabViewControl tabViewControl && tabViewControl.ItemSource != null)
|
||||||
|
{
|
||||||
|
foreach (var tab in tabViewControl.ItemSource)
|
||||||
|
{
|
||||||
|
tab.HeaderSelectionUnderlineThickness = (double)newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static readonly BindableProperty HeaderSelectionUnderlineThicknessProperty = BindableProperty.Create(nameof(HeaderSelectionUnderlineThickness), typeof(double), typeof(TabViewControl), TabDefaults.DefaultThickness, BindingMode.Default, null, HeaderSelectionUnderlineThicknessChanged);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region HeaderSelectionUnderlineWidth
|
||||||
|
public double HeaderSelectionUnderlineWidth
|
||||||
|
{
|
||||||
|
get { return (double)GetValue(HeaderSelectionUnderlineWidthProperty); }
|
||||||
|
set { SetValue(HeaderSelectionUnderlineWidthProperty, value); }
|
||||||
|
}
|
||||||
|
private static void HeaderSelectionUnderlineWidthChanged(BindableObject bindable, object oldValue, object newValue)
|
||||||
|
{
|
||||||
|
if (bindable is TabViewControl tabViewControl && tabViewControl.ItemSource != null)
|
||||||
|
{
|
||||||
|
foreach (var tab in tabViewControl.ItemSource)
|
||||||
|
{
|
||||||
|
tab.HeaderSelectionUnderlineWidth = (double)newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static readonly BindableProperty HeaderSelectionUnderlineWidthProperty = BindableProperty.Create(nameof(HeaderSelectionUnderlineWidth), typeof(double), typeof(TabViewControl), (double)0, BindingMode.Default, null, HeaderSelectionUnderlineWidthChanged);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region HeaderTabTextFontSize
|
||||||
|
[Xamarin.Forms.TypeConverter(typeof(FontSizeConverter))]
|
||||||
|
public double HeaderTabTextFontSize
|
||||||
|
{
|
||||||
|
get { return (double)GetValue(HeaderTabTextFontSizeProperty); }
|
||||||
|
set { SetValue(HeaderTabTextFontSizeProperty, value); }
|
||||||
|
}
|
||||||
|
private static void HeaderTabTextFontSizeChanged(BindableObject bindable, object oldValue, object newValue)
|
||||||
|
{
|
||||||
|
if (bindable is TabViewControl tabViewControl && tabViewControl.ItemSource != null)
|
||||||
|
{
|
||||||
|
foreach (var tab in tabViewControl.ItemSource)
|
||||||
|
{
|
||||||
|
tab.HeaderTabTextFontSize = (double)newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static readonly BindableProperty HeaderTabTextFontSizeProperty = BindableProperty.Create(nameof(HeaderTabTextFontSize), typeof(double), typeof(TabViewControl), (double)14, BindingMode.Default, null, HeaderTabTextFontSizeChanged);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region HeaderTabTextFontFamily
|
||||||
|
public string HeaderTabTextFontFamily
|
||||||
|
{
|
||||||
|
get { return (string)GetValue(HeaderTabTextFontFamilyProperty); }
|
||||||
|
set { SetValue(HeaderTabTextFontFamilyProperty, value); }
|
||||||
|
}
|
||||||
|
private static void HeaderTabTextFontFamilyChanged(BindableObject bindable, object oldValue, object newValue)
|
||||||
|
{
|
||||||
|
if (bindable is TabViewControl tabViewControl && tabViewControl.ItemSource != null)
|
||||||
|
{
|
||||||
|
foreach (var tab in tabViewControl.ItemSource)
|
||||||
|
{
|
||||||
|
tab.HeaderTabTextFontFamily = (string)newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static readonly BindableProperty HeaderTabTextFontFamilyProperty = BindableProperty.Create(nameof(HeaderTabTextFontFamily), typeof(string), typeof(TabViewControl), null, BindingMode.Default, null, HeaderTabTextFontFamilyChanged);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region HeaderTabTextFontAttributes
|
||||||
|
public FontAttributes HeaderTabTextFontAttributes
|
||||||
|
{
|
||||||
|
get { return (FontAttributes)GetValue(HeaderTabTextFontAttributesProperty); }
|
||||||
|
set { SetValue(HeaderTabTextFontAttributesProperty, value); }
|
||||||
|
}
|
||||||
|
private static void HeaderTabTextFontAttributesChanged(BindableObject bindable, object oldValue, object newValue)
|
||||||
|
{
|
||||||
|
if (bindable is TabViewControl tabViewControl && tabViewControl.ItemSource != null)
|
||||||
|
{
|
||||||
|
foreach (var tab in tabViewControl.ItemSource)
|
||||||
|
{
|
||||||
|
tab.HeaderTabTextFontAttributes = (FontAttributes)newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static readonly BindableProperty HeaderTabTextFontAttributesProperty = BindableProperty.Create(nameof(HeaderTabTextFontAttributes), typeof(FontAttributes), typeof(TabViewControl), FontAttributes.None, BindingMode.Default, null, HeaderTabTextFontAttributesChanged);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ItemSource
|
||||||
|
public static readonly BindableProperty ItemSourceProperty = BindableProperty.Create(nameof(ItemSource), typeof(ObservableCollection<TabItem>), typeof(TabViewControl));
|
||||||
|
public ObservableCollection<TabItem> ItemSource
|
||||||
|
{
|
||||||
|
get => (ObservableCollection<TabItem>)GetValue(ItemSourceProperty);
|
||||||
|
set { SetValue(ItemSourceProperty, value); }
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region TabSizeOption
|
||||||
|
public static readonly BindableProperty TabSizeOptionProperty = BindableProperty.Create(nameof(TabSizeOption), typeof(GridLength), typeof(TabViewControl), default(GridLength), propertyChanged: OnTabSizeOptionChanged);
|
||||||
|
private static void OnTabSizeOptionChanged(BindableObject bindable, object oldValue, object newValue)
|
||||||
|
{
|
||||||
|
if (bindable is TabViewControl tabViewControl && tabViewControl._headerContainerGrid != null && tabViewControl.ItemSource != null)
|
||||||
|
{
|
||||||
|
foreach (var tabContainer in tabViewControl._headerContainerGrid.ColumnDefinitions)
|
||||||
|
{
|
||||||
|
tabContainer.Width = (GridLength)newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public GridLength TabSizeOption
|
||||||
|
{
|
||||||
|
get => (GridLength)GetValue(TabSizeOptionProperty);
|
||||||
|
set { SetValue(TabSizeOptionProperty, value); }
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region SelectedTabIndex
|
||||||
|
public static readonly BindableProperty SelectedTabIndexProperty = BindableProperty.Create(nameof(SelectedTabIndex), typeof(int), typeof(TabViewControl), 0, propertyChanged: OnSelectedTabIndexChanged);
|
||||||
|
private static void OnSelectedTabIndexChanged(BindableObject bindable, object oldValue, object newValue)
|
||||||
|
{
|
||||||
|
if (bindable is TabViewControl tabViewControl && tabViewControl.ItemSource != null)
|
||||||
|
{
|
||||||
|
tabViewControl.SetCurrentTab((int)newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int SelectedTabIndex
|
||||||
|
{
|
||||||
|
get => (int)GetValue(SelectedTabIndexProperty);
|
||||||
|
set { SetValue(SelectedTabIndexProperty, value); }
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public void SetCurrentTab(int position, bool initialRun = false)
|
||||||
|
{
|
||||||
|
if (SelectedTabIndex == position && !initialRun)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int oldPosition = SelectedTabIndex;
|
||||||
|
|
||||||
|
var tabChangingArgs = new TabChangingEventArgs()
|
||||||
|
{
|
||||||
|
Canceled = false,
|
||||||
|
NewPosition = position,
|
||||||
|
OldPosition = oldPosition
|
||||||
|
};
|
||||||
|
OnTabChanging(ref tabChangingArgs);
|
||||||
|
|
||||||
|
if (tabChangingArgs != null && tabChangingArgs.Canceled)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((position >= 0 && position < ItemSource.Count) || initialRun))
|
||||||
|
{
|
||||||
|
if (oldPosition < ItemSource.Count && _mainContainerSL.Children.Count == 2)
|
||||||
|
{
|
||||||
|
ItemSource[oldPosition].IsCurrent = false;
|
||||||
|
//Remove second child
|
||||||
|
_mainContainerSL.Children.RemoveAt(1);
|
||||||
|
}
|
||||||
|
_mainContainerSL.Children.Add(ItemSource[position].Content);
|
||||||
|
ItemSource[position].IsCurrent = true;
|
||||||
|
SelectedTabIndex = position;
|
||||||
|
Device.BeginInvokeOnMainThread(async () => await _tabHeadersContainerSv.ScrollToAsync(_headerContainerGrid.Children[position], ScrollToPosition.MakeVisible, false));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var tabChangedArgs = new TabChangedEventArgs()
|
||||||
|
{
|
||||||
|
NewPosition = SelectedTabIndex,
|
||||||
|
OldPosition = oldPosition
|
||||||
|
};
|
||||||
|
OnTabChanged(tabChangedArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectNext()
|
||||||
|
{
|
||||||
|
SetCurrentTab(SelectedTabIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectPrevious()
|
||||||
|
{
|
||||||
|
SetCurrentTab(SelectedTabIndex - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectFirst()
|
||||||
|
{
|
||||||
|
SetCurrentTab(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectLast()
|
||||||
|
{
|
||||||
|
SetCurrentTab(ItemSource.Count - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddTab(TabItem tab, int position = -1, bool selectNewPosition = false)
|
||||||
|
{
|
||||||
|
if (position > -1)
|
||||||
|
{
|
||||||
|
ItemSource.Insert(position, tab);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ItemSource.Add(tab);
|
||||||
|
}
|
||||||
|
if (selectNewPosition)
|
||||||
|
{
|
||||||
|
SelectedTabIndex = position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveTab(int position = -1)
|
||||||
|
{
|
||||||
|
if (position > -1)
|
||||||
|
{
|
||||||
|
ItemSource.RemoveAt(position);
|
||||||
|
_headerContainerGrid.Children.RemoveAt(position);
|
||||||
|
_headerContainerGrid.ColumnDefinitions.RemoveAt(position);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ItemSource.Remove(ItemSource.Last());
|
||||||
|
_headerContainerGrid.Children.RemoveAt(_headerContainerGrid.Children.Count - 1);
|
||||||
|
_headerContainerGrid.ColumnDefinitions.Remove(_headerContainerGrid.ColumnDefinitions.Last());
|
||||||
|
}
|
||||||
|
SelectedTabIndex = position >= 0 && position < ItemSource.Count ? position : ItemSource.Count - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
Aurora/Design/Converters/DoubleToLayoutOptions.cs
Normal file
24
Aurora/Design/Converters/DoubleToLayoutOptions.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Aurora.Design.Converters
|
||||||
|
{
|
||||||
|
public class DoubleToLayoutOptionsConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
var result = double.TryParse(value.ToString(), out double val);
|
||||||
|
if (result && val > 0)
|
||||||
|
{
|
||||||
|
return LayoutOptions.CenterAndExpand;
|
||||||
|
}
|
||||||
|
return LayoutOptions.FillAndExpand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
Aurora/Design/Converters/NullToBullConverter.cs
Normal file
19
Aurora/Design/Converters/NullToBullConverter.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Aurora.Design.Converters
|
||||||
|
{
|
||||||
|
public class NullToBoolConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return value != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using Aurora.Design.Components.TabView;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Aurora.Design.Converters
|
||||||
|
{
|
||||||
|
class SelectedTabHeaderToTabBackgroundColorConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
bool isCurrentTabSelected = false;
|
||||||
|
if (!string.IsNullOrWhiteSpace(value?.ToString()))
|
||||||
|
bool.TryParse(value.ToString(), out isCurrentTabSelected);
|
||||||
|
|
||||||
|
if (parameter is TabViewControl tvc && isCurrentTabSelected)
|
||||||
|
{
|
||||||
|
return tvc.HeaderSelectionUnderlineColor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Color.Transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,4 @@
|
|||||||
^ContentPage {
|
#Header {
|
||||||
background-color: #232323;
|
|
||||||
}
|
|
||||||
|
|
||||||
#Header {
|
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
margin-top: 10;
|
margin-top: 10;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
xmlns:navigation="clr-namespace:Aurora.Design.Components.NavigationMenu"
|
xmlns:navigation="clr-namespace:Aurora.Design.Components.NavigationMenu"
|
||||||
xmlns:mp="clr-namespace:Aurora.Design.Components.MediaPlayer"
|
xmlns:mp="clr-namespace:Aurora.Design.Components.MediaPlayer"
|
||||||
xmlns:dialog="clr-namespace:Aurora.Design.Components.Dialogs"
|
xmlns:dialog="clr-namespace:Aurora.Design.Components.Dialogs"
|
||||||
x:Class="Aurora.Design.Views.Main.MainView">
|
x:Class="Aurora.Design.Views.Main.MainView"
|
||||||
|
StyleClass="primaryColor">
|
||||||
<ContentPage.Resources>
|
<ContentPage.Resources>
|
||||||
<StyleSheet
|
<StyleSheet
|
||||||
Source="MainView.css"/>
|
Source="MainView.css"/>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
<ContentView
|
<ContentView
|
||||||
xmlns="http://xamarin.com/schemas/2014/forms"
|
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
xmlns:tabView="clr-namespace:Aurora.Design.Components.TabView"
|
||||||
xmlns:ml="clr-namespace:Aurora.Design.Components.MemberList"
|
xmlns:ml="clr-namespace:Aurora.Design.Components.MemberList"
|
||||||
xmlns:library="clr-namespace:Aurora.Design.Components.Library"
|
xmlns:library="clr-namespace:Aurora.Design.Components.Library"
|
||||||
xmlns:flv="clr-namespace:DLToolkit.Forms.Controls;assembly=DLToolkit.Forms.Controls.FlowListView"
|
xmlns:flv="clr-namespace:DLToolkit.Forms.Controls;assembly=DLToolkit.Forms.Controls.FlowListView"
|
||||||
@ -11,29 +12,29 @@
|
|||||||
Source="./PartyView.css"/>
|
Source="./PartyView.css"/>
|
||||||
</ContentView.Resources>
|
</ContentView.Resources>
|
||||||
<ContentView.Content>
|
<ContentView.Content>
|
||||||
<Grid>
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition
|
|
||||||
Height="100"/>
|
|
||||||
<RowDefinition
|
|
||||||
Height="*"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<StackLayout
|
<StackLayout
|
||||||
x:Name="TabHeader"
|
x:Name="TabHeader">
|
||||||
Grid.Row="0">
|
<tabView:TabViewControl
|
||||||
<Label
|
HorizontalOptions="FillAndExpand"
|
||||||
x:Name="PartyMembersLabel"
|
VerticalOptions="FillAndExpand"
|
||||||
Text="Party Members"/>
|
x:Name="TabView">
|
||||||
|
<tabView:TabViewControl.ItemSource>
|
||||||
|
<tabView:TabItem
|
||||||
|
HeaderText="Members">
|
||||||
<ml:MemberList
|
<ml:MemberList
|
||||||
x:Name="MembersList"
|
x:Name="MembersList"
|
||||||
VerticalOptions="FillAndExpand"
|
VerticalOptions="FillAndExpand"
|
||||||
Members="{Binding Members}"/>
|
Members="{Binding Members}"/>
|
||||||
</StackLayout>
|
</tabView:TabItem>
|
||||||
|
<tabView:TabItem
|
||||||
|
HeaderText="Queue">
|
||||||
<library:Library
|
<library:Library
|
||||||
Grid.Row="1"
|
|
||||||
ItemsSource="{Binding Queue}"
|
ItemsSource="{Binding Queue}"
|
||||||
SelectedItem="{Binding SelectedSong}"
|
SelectedItem="{Binding SelectedSong}"
|
||||||
ItemDoubleClicked="{Binding PlayCommand}"/>
|
ItemDoubleClicked="{Binding PlayCommand}"/>
|
||||||
</Grid>
|
</tabView:TabItem>
|
||||||
|
</tabView:TabViewControl.ItemSource>
|
||||||
|
</tabView:TabViewControl>
|
||||||
|
</StackLayout>
|
||||||
</ContentView.Content>
|
</ContentView.Content>
|
||||||
</ContentView>
|
</ContentView>
|
Reference in New Issue
Block a user