Files
Common-VS2019/SacsMobileMaui/Maui/Controls/SamTabControl.cs
T

194 lines
7.1 KiB
C#

using Microsoft.Maui;
using Microsoft.Maui.Layouts;
using Sarand.Net.Mobile.Maui.Layouts;
using Sarand.Net.Mobile.Maui.Panels;
using Sarand.Net.Mobile.Maui.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sarand.Net.Mobile.Maui.Controls
{
//=======================================================================
public class SamTabControl : ContentView
{
//-------------------------------------------------------------------
// Definitions.
//-------------------------------------------------------------------
// Data members.
private readonly List<SamTabPanel> tabPanels = new List<SamTabPanel>();
private short currentTabIdx = -1;
// Main layout to host header and body.
private SamStackLayout mainLayout = new SamStackLayout() { Orientation = StackOrientation.Vertical };
// Header layout - horizontal row.
private SamFlexLayout headerPanel = new SamFlexLayout() { Direction = FlexDirection.Row, AlignItems = FlexAlignItems.Center, JustifyContent = FlexJustify.Start, HorizontalOptions = LayoutOptions.Start };
// Body - Content view to host tab panel.
private SamContentView bodyPanel = new SamContentView();
//-------------------------------------------------------------------
// Construction.
public SamTabControl()
{
// 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 = Colors.LightYellow;
mainLayout.Children.Add(bodyPanel);
}
//-------------------------------------------------------------------
// Properties.
// Header.
public Color HeaderBackgroundColor { get { return headerPanel.BackgroundColor; } set { headerPanel.BackgroundColor = value; } }
public Color CaptionBackgroundColor { get; set; } = Colors.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, SamContentView panel)
{
AddPanel(new SamTabPanel(caption, panel));
}
public void AddPanel(SamTabPanel tabPanel)
{
AddPanels(new List<SamTabPanel>() { tabPanel });
}
public void AddPanels(IEnumerable<SamTabPanel> 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.
SamTabPanel tabPanel = tabPanels[tabPanelIdx];
// Header caption.
SamContentView captionPanel = new SamContentView()
{
Padding = HeaderCaptionPadding,
BackgroundColor = CaptionBackgroundColor,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand
};
if (tabPanelIdx > 0)
captionPanel.Margin = new Thickness(HeaderCaptionSpacing, 0, 0, 0);
SamLabel captionLabel = new SamLabel()
{
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.
View? headerPanelView = headerPanel.Children[headerPanelIdx] as View;
// Label.
Label? headerPanelLabel = (headerPanelView as Label);
if (headerPanelLabel == null && headerPanelView is ContentView)
headerPanelLabel = ((ContentView)headerPanelView).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
//-------------------------------------------------------------------
//-------------------------------------------------------------------
}
//=======================================================================
}