Added tab view (not working)

This commit is contained in:
watsonb8 2019-12-21 22:21:07 -05:00
parent 881d339ffd
commit 7560e122f8
10 changed files with 849 additions and 27 deletions

View File

@ -158,6 +158,12 @@
<Reference Include="OpenTK.GLControl">
<HintPath>..\packages\OpenTK.GLControl.3.0.1\lib\net20\OpenTK.GLControl.dll</HintPath>
</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>
<EmbeddedResource Include="gtk-gui\gui.stetic">

View File

@ -1,7 +1,6 @@
using System;
using LibVLCSharp.Forms.Shared;
using Xamarin.Forms.Platform.GTK;
using Xamarin.Forms.Platform.GTK.Helpers;
namespace Aurora.gtk
{

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<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="Grpc" version="2.25.0" targetFramework="net47" />
<package id="Grpc.Core" version="2.25.0" targetFramework="net47" />

View File

@ -21,6 +21,8 @@
<PackageReference Include="Google.Protobuf" Version="3.10.1" />
<PackageReference Include="Xam.Plugins.Settings" Version="3.1.1" />
<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>
<Folder Include="Design\" />
@ -37,7 +39,6 @@
<Folder Include="Models\" />
<Folder Include="Services\" />
<Folder Include="Design\Views\Party\" />
<Folder Include="Design\Components\HostSelector\" />
<Folder Include="Design\Components\MemberList\" />
<Folder Include="Design\Components\Library\" />
<Folder Include="Design\Views\Profile\" />
@ -47,6 +48,7 @@
<Folder Include="Design\Components\ImageButton\" />
<Folder Include="Design\Components\Dialogs\" />
<Folder Include="Design\Views\Party\NewPartyDialog\" />
<Folder Include="Design\Components\TabView\" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Design\Behaviors\DeselectItemBehaviorBase.cs" />

View 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); }
}
}
}

View File

@ -0,0 +1,630 @@
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, PositionChangingEventArgs e);
public delegate void PositionChangedEventHandler(object sender, PositionChangedEventArgs e);
public class PositionChangingEventArgs : EventArgs
{
public bool Canceled { get; set; }
public int NewPosition { get; set; }
public int OldPosition { get; set; }
}
public class PositionChangedEventArgs : 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 CarouselViewControl _carouselView;
private ScrollView _tabHeadersContainerSv;
public event PositionChangingEventHandler PositionChanging;
public event PositionChangedEventHandler PositionChanged;
protected virtual void OnPositionChanging(ref PositionChangingEventArgs e)
{
PositionChangingEventHandler handler = PositionChanging;
handler?.Invoke(this, e);
}
protected virtual void OnPositionChanged(PositionChangedEventArgs 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 bool _supressCarouselViewPositionChangedEvent;
private void _carouselView_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(_carouselView.Position) && !_supressCarouselViewPositionChangedEvent)
{
var positionChangingArgs = new PositionChangingEventArgs()
{
Canceled = false,
NewPosition = _carouselView.Position,
OldPosition = SelectedTabIndex
};
OnPositionChanging(ref positionChangingArgs);
if (positionChangingArgs != null && positionChangingArgs.Canceled)
{
_supressCarouselViewPositionChangedEvent = true;
_carouselView.PositionSelected -= _carouselView_PositionSelected;
_carouselView.PropertyChanged -= _carouselView_PropertyChanged;
_carouselView.Position = SelectedTabIndex;
_carouselView.PositionSelected += _carouselView_PositionSelected;
_carouselView.PropertyChanged += _carouselView_PropertyChanged;
_supressCarouselViewPositionChangedEvent = false;
}
SetPosition(positionChangingArgs.NewPosition);
}
}
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
};
_carouselView = new CarouselViewControl
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
HeightRequest = ContentHeight,
ShowArrows = false,
ShowIndicators = false,
BindingContext = this
};
_carouselView.PropertyChanged += _carouselView_PropertyChanged;
_carouselView.PositionSelected += _carouselView_PositionSelected;
_mainContainerSL = new StackLayout
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
Children = { _tabHeadersContainerSv, _carouselView },
Spacing = 0
};
Content = _mainContainerSL;
ItemSource.CollectionChanged += ItemSource_CollectionChanged;
SetPosition(SelectedTabIndex, true);
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
if (BindingContext != null)
{
foreach (var tab in ItemSource)
{
if (tab is TabItem view)
{
view.Content.BindingContext = BindingContext;
}
}
}
}
private void _carouselView_PositionSelected(object sender, PositionSelectedEventArgs e)
{
if (_carouselView.Position != e.NewValue || SelectedTabIndex != e.NewValue)
{
SetPosition(e.NewValue);
}
}
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
};
//selectionBarBoxView.SetBinding(IsVisibleProperty, nameof(TabItem.IsCurrent));
var underlineColorBinding = new Binding(nameof(TabItem.IsCurrent), BindingMode.OneWay, new SelectedTabHeaderToTabBackgroundColorConverter(), this);
//selectionBarBoxView.SetBinding(BoxView.ColorProperty, nameof(TabItem.HeaderSelectionUnderlineColor), BindingMode.OneWay, new SelectedTabHeaderToTabBackgroundColorConverter(), );
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))
{
SetPosition(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) =>
{
_supressCarouselViewPositionChangedEvent = true;
var capturedIndex = _headerContainerGrid.Children.IndexOf((View)s);
SetPosition(capturedIndex);
_supressCarouselViewPositionChangedEvent = false;
};
headerItemSL.GestureRecognizers.Add(tapRecognizer);
_headerContainerGrid.Children.Add(headerItemSL, _headerContainerGrid.ColumnDefinitions.Count - 1, 0);
_carouselView.ItemsSource = ItemSource.Select(t => t.Content);
}
#region IsSwipingEnabled
public bool IsSwipingEnabled
{
get { return (bool)GetValue(IsSwipingEnabledProperty); }
set { SetValue(IsSwipingEnabledProperty, value); }
}
private static void IsSwipingEnabledChanged(BindableObject bindable, object oldValue, object newValue)
{
if (bindable is TabViewControl tabViewControl)
{
tabViewControl._carouselView.IsSwipeEnabled = (bool)newValue;
}
}
public static readonly BindableProperty IsSwipingEnabledProperty = BindableProperty.Create(nameof(IsSwipingEnabled), typeof(bool), typeof(TabViewControl), true, BindingMode.Default, null, IsSwipingEnabledChanged);
#endregion
#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)
{
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._carouselView.Position != (int)newValue)
{
tabViewControl.SetPosition((int)newValue);
}
}
public int SelectedTabIndex
{
get => (int)GetValue(SelectedTabIndexProperty);
set { SetValue(SelectedTabIndexProperty, value); }
}
#endregion
public void SetPosition(int position, bool initialRun = false)
{
if (SelectedTabIndex == position && !initialRun)
{
return;
}
int oldPosition = SelectedTabIndex;
var positionChangingArgs = new PositionChangingEventArgs()
{
Canceled = false,
NewPosition = position,
OldPosition = oldPosition
};
OnPositionChanging(ref positionChangingArgs);
if (positionChangingArgs != null && positionChangingArgs.Canceled)
{
return;
}
if ((position >= 0 && position < ItemSource.Count) || initialRun)
{
if (_carouselView.Position != position || initialRun)
{
_carouselView.PositionSelected -= _carouselView_PositionSelected;
_carouselView.Position = position;
_carouselView.PositionSelected += _carouselView_PositionSelected;
}
if (oldPosition != position)
{
if (oldPosition < ItemSource.Count)
{
ItemSource[oldPosition].IsCurrent = false;
}
ItemSource[position].IsCurrent = true;
SelectedTabIndex = position;
Device.BeginInvokeOnMainThread(async () => await _tabHeadersContainerSv.ScrollToAsync(_headerContainerGrid.Children[position], ScrollToPosition.MakeVisible, false));
}
}
var positionChangedArgs = new PositionChangedEventArgs()
{
NewPosition = SelectedTabIndex,
OldPosition = oldPosition
};
OnPositionChanged(positionChangedArgs);
}
public void SelectNext()
{
SetPosition(SelectedTabIndex + 1);
}
public void SelectPrevious()
{
SetPosition(SelectedTabIndex - 1);
}
public void SelectFirst()
{
SetPosition(0);
}
public void SelectLast()
{
SetPosition(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());
}
_carouselView.ItemsSource = ItemSource.Select(t => t.Content);
SelectedTabIndex = position >= 0 && position < ItemSource.Count ? position : ItemSource.Count - 1;
}
}
}

View 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;
}
}
}

View 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;
}
}
}

View File

@ -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();
}
}
}

View File

@ -2,7 +2,7 @@
<ContentView
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ml="clr-namespace:Aurora.Design.Components.MemberList"
xmlns:tabView="clr-namespace:Aurora.Design.Components.TabView"
xmlns:library="clr-namespace:Aurora.Design.Components.Library"
xmlns:flv="clr-namespace:DLToolkit.Forms.Controls;assembly=DLToolkit.Forms.Controls.FlowListView"
x:Class="Aurora.Design.Views.Party.PartyView">
@ -11,29 +11,27 @@
Source="./PartyView.css"/>
</ContentView.Resources>
<ContentView.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition
Height="100"/>
<RowDefinition
Height="*"/>
</Grid.RowDefinitions>
<StackLayout
x:Name="TabHeader"
Grid.Row="0">
<Label
x:Name="PartyMembersLabel"
Text="Party Members"/>
<ml:MemberList
x:Name="MembersList"
VerticalOptions="FillAndExpand"
Members="{Binding Members}"/>
</StackLayout>
<library:Library
Grid.Row="1"
ItemsSource="{Binding Queue}"
SelectedItem="{Binding SelectedSong}"
ItemDoubleClicked="{Binding PlayCommand}"/>
</Grid>
<StackLayout
x:Name="TabHeader">
<tabView:TabViewControl
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
x:Name="TabView">
<tabView:TabViewControl.ItemSource>
<tabView:TabItem
HeaderText="Queue">
<library:Library
ItemsSource="{Binding Queue}"
SelectedItem="{Binding SelectedSong}"
ItemDoubleClicked="{Binding PlayCommand}"/>
</tabView:TabItem>
<tabView:TabItem
HeaderText="Members">
<Label
Text="Members"/>
</tabView:TabItem>
</tabView:TabViewControl.ItemSource>
</tabView:TabViewControl>
</StackLayout>
</ContentView.Content>
</ContentView>