194 lines
6.2 KiB
C#
194 lines
6.2 KiB
C#
using Microsoft.Maui;
|
|
using Microsoft.Maui.Layouts;
|
|
using Sarand.Net.Mobile.Maui.App;
|
|
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, ISamView
|
|
{
|
|
// --- 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 ---
|
|
|
|
VerticalOptions = LayoutOptions.FillAndExpand;
|
|
mainLayout.VerticalOptions = LayoutOptions.FillAndExpand;
|
|
mainLayout.Spacing = 2.0;
|
|
Content = mainLayout;
|
|
|
|
// --- Header panel ---
|
|
|
|
headerPanel.BackgroundColor = Sam.Visuals.Form.TabControl.HeaderBackgroundColor;
|
|
mainLayout.Children.Add(headerPanel);
|
|
|
|
// --- Default font size ---
|
|
|
|
DefaultHeaderFontSize = new Label().FontSize;
|
|
HeaderFontSize = DefaultHeaderFontSize;
|
|
|
|
// --- Body panel ---
|
|
|
|
bodyPanel.HorizontalOptions = LayoutOptions.Fill;
|
|
bodyPanel.VerticalOptions = LayoutOptions.FillAndExpand;
|
|
bodyPanel.BackgroundColor = Sam.Visuals.Form.TabControl.BodyBackgroundColor;
|
|
mainLayout.Children.Add(bodyPanel);
|
|
}
|
|
|
|
// --- Properties ---
|
|
|
|
// Header.
|
|
public Color HeaderBackgroundColor { get { return headerPanel.BackgroundColor; } set { headerPanel.BackgroundColor = value; } }
|
|
public Color CaptionBackgroundColor { get; set; } = Sam.Visuals.Form.TabControl.CaptionBackgroundColor;
|
|
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); }
|
|
}
|
|
|
|
// --- Tab panels ---
|
|
|
|
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();
|
|
}
|
|
|
|
// --- Refresh layout ---
|
|
|
|
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);
|
|
}
|
|
|
|
// --- Change tab panel ---
|
|
|
|
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;
|
|
}
|
|
|
|
// --- Component state ---
|
|
|
|
public void ConfigureComponents() { }
|
|
public void SetControlActivity(bool enabled)
|
|
{
|
|
if (IsEnabled != enabled) IsEnabled = enabled;
|
|
SetControlsReadOnly();
|
|
}
|
|
public void SetControlsReadOnly() { }
|
|
|
|
// --- The End ---
|
|
}
|
|
}
|