189 lines
7.1 KiB
C#
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
|
|
//-------------------------------------------------------------------
|
|
|
|
//-------------------------------------------------------------------
|
|
}
|
|
//=======================================================================
|
|
}
|