Files
Common-VS2019/SacsStandardMob/Mobile/Forms/Controls/SaxTabControl.cs
T
2021-05-05 15:36:28 +01:00

189 lines
7.1 KiB
C#

using Sarand.Net.Standard.Mobile.Forms.Layouts;
using Sarand.Net.Standard.Mobile.Forms.Panels;
using Sarand.Net.Standard.Mobile.Forms.Views;
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;
namespace Sarand.Net.Standard.Mobile.Forms.Controls
{
//=======================================================================
public class SaxTabControl : ContentView
{
//-------------------------------------------------------------------
// Definitions.
//-------------------------------------------------------------------
// Data members.
private readonly List<SaxTabPanel> tabPanels = new List<SaxTabPanel>();
private short currentTabIdx = -1;
// Main layout to host header and body.
private SaxStackLayout mainLayout = new SaxStackLayout() { Orientation = StackOrientation.Vertical };
// Header layout - horizontal row.
private SaxFlexLayout headerPanel = new SaxFlexLayout() { Direction = FlexDirection.Row, AlignItems = FlexAlignItems.Center, JustifyContent = FlexJustify.Start, HorizontalOptions = LayoutOptions.Start };
// Body - Content view to host tab panel.
private SaxContentView bodyPanel = new SaxContentView();
//-------------------------------------------------------------------
// Construction.
public SaxTabControl ()
{
// Main layout - vertical stack with two rows.
// 1. Header - tab panel captions.
// 2. Body - current tab panel.
VerticalOptions = LayoutOptions.FillAndExpand;
//BackgroundColor = Color.LightSkyBlue;
mainLayout.VerticalOptions = LayoutOptions.FillAndExpand;
mainLayout.Spacing = 2.0;
Content = mainLayout;
// Header panel - tab captions.
//headerPanel.HorizontalOptions = LayoutOptions.Fill;
mainLayout.Children.Add(headerPanel);
// Default label font size.
DefaultHeaderFontSize = new Label().FontSize;
HeaderFontSize = DefaultHeaderFontSize;
// Body panel.
bodyPanel.HorizontalOptions = LayoutOptions.Fill;
bodyPanel.VerticalOptions = LayoutOptions.FillAndExpand;
bodyPanel.BackgroundColor = Color.LightYellow;
mainLayout.Children.Add(bodyPanel);
}
//-------------------------------------------------------------------
// Properties.
// Header.
public Color HeaderBackgroundColor { get { return headerPanel.BackgroundColor; } set { headerPanel.BackgroundColor = value; } }
public Color CaptionBackgroundColor { get; set; } = Color.Transparent;
public double DefaultHeaderFontSize { get; }
public double HeaderFontSize { get; set; }
public double HeaderMarginBottom
{
get { return mainLayout.Spacing; }
set { if (mainLayout.Spacing == value) return; mainLayout.Spacing = value; }
}
public Thickness HeaderPadding
{
get { return mainLayout.Padding; }
set { if (mainLayout.Padding == value) return; mainLayout.Padding = value; }
}
public Thickness HeaderCaptionPadding { get; set; } = new Thickness(12.0, 4.0);
public double HeaderCaptionSpacing { get; set; } = 4.0;
// Tab panels.
public Color BodyBackgroundColor { get { return bodyPanel.BackgroundColor; } set { bodyPanel.BackgroundColor = value; } }
public int PanelCount { get { return tabPanels.Count; } }
public short TabPanelIndex
{
get { return currentTabIdx; }
set { ChangeTabPanel(value); }
}
//-------------------------------------------------------------------
// T a b P a n e l s
//-------------------------------------------------------------------
public void ClearPanels ()
{
tabPanels.Clear();
RefreshLayout();
}
public void AddPanel (String caption, SaxContentView panel)
{
AddPanel(new SaxTabPanel(caption, panel));
}
public void AddPanel (SaxTabPanel tabPanel)
{
AddPanels(new List<SaxTabPanel>() { tabPanel });
}
public void AddPanels (IEnumerable<SaxTabPanel> tabPanels)
{
this.tabPanels.AddRange(tabPanels);
RefreshLayout();
}
//-------------------------------------------------------------------
// R e f r e s h L a y o u t
//-------------------------------------------------------------------
private void RefreshLayout ()
{
// Clear existing components.
headerPanel.Children.Clear();
bodyPanel.Content = null;
// Add each Tab panel in turn.
for (short tabPanelIdx = 0; tabPanelIdx < tabPanels.Count; tabPanelIdx++)
{
short tabPanelIdx_Local = tabPanelIdx; // Loop closure.
SaxTabPanel tabPanel = tabPanels[tabPanelIdx];
// Header caption.
SaxContentView captionPanel = new SaxContentView()
{
Padding = HeaderCaptionPadding,
BackgroundColor = CaptionBackgroundColor,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand
};
if (tabPanelIdx > 0)
captionPanel.Margin = new Thickness(HeaderCaptionSpacing, 0, 0, 0);
SaxLabel captionLabel = new SaxLabel()
{
Text = tabPanel.Caption,
FontSize = HeaderFontSize
};
captionPanel.Content = captionLabel;
headerPanel.Children.Add(captionPanel);
// Tap Gesture.
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += (s, e) => { ChangeTabPanel(tabPanelIdx_Local); };
captionPanel.GestureRecognizers.Add(tapGestureRecognizer);
}
// Current tab retains previous value if still valid (in panel range),
// is restricted to the range 0 to number of panels - 1 if there are panels,
// or -1 if no panels.
currentTabIdx = (short)(tabPanels.Count > 0 ? Math.Max(0, Math.Min(tabPanels.Count - 1, currentTabIdx)) : -1);
if (tabPanels.Count > 0)
ChangeTabPanel(currentTabIdx);
}
//-------------------------------------------------------------------
// C h a n g e T a b P a n e l
//-------------------------------------------------------------------
private void ChangeTabPanel (short tabPanelIdx)
{
// Validate requested panel index.
if (tabPanelIdx < 0 || tabPanelIdx >= tabPanels.Count)
throw new IndexOutOfRangeException("Tab panel index must be between 0 & " + (tabPanels.Count - 1) + ". Supplied value: " + tabPanelIdx);
// Highlight selected tab panel header caption.
for (short headerPanelIdx = 0; headerPanelIdx < headerPanel.Children.Count; headerPanelIdx++)
{
View headerPanelView = headerPanel.Children[headerPanelIdx];
Label headerPanelLabel = (headerPanelView as Label);
if (headerPanelLabel == null && headerPanelView is ContentView)
headerPanelLabel = ((headerPanelView as ContentView).Content as Label);
if (headerPanelLabel != null)
{
if (headerPanelIdx == tabPanelIdx)
headerPanelLabel.FontAttributes = FontAttributes.Bold;
else headerPanelLabel.FontAttributes = FontAttributes.None;
}
}
// Display selected tab panel.
bodyPanel.Content = tabPanels[tabPanelIdx];
currentTabIdx = tabPanelIdx;
}
//-------------------------------------------------------------------
// C o n t r o l E v e n t s
//-------------------------------------------------------------------
//-------------------------------------------------------------------
}
//=======================================================================
}