Saxonite 1.2.11.3. Sandtrap.
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.App
|
||||
{
|
||||
//=======================================================================
|
||||
// Colour references:
|
||||
// http://www.html-color-names.com/skyblue.php
|
||||
// http://www.html-color-names.com/lightsteelblue.php
|
||||
//=======================================================================
|
||||
public static class Sam
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public enum Platform
|
||||
{
|
||||
Unknown = 0,
|
||||
Android,
|
||||
IOS,
|
||||
MacCatalyst,
|
||||
Windows
|
||||
}
|
||||
// Utilities.
|
||||
public static Random Random { get; set; } = new Random();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Localisation.
|
||||
public static class Locale
|
||||
{
|
||||
public static CultureInfo CultureInfo { get; set; } = CultureInfo.CurrentCulture;
|
||||
public static TextInfo TextInfo { get; set; } = CultureInfo.TextInfo;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Visuals.
|
||||
public enum DisplayPosition { None, Left, Middle, Right }
|
||||
public static class Visuals
|
||||
{
|
||||
// Application styling.
|
||||
public static class Application
|
||||
{
|
||||
// Application bar.
|
||||
public static class Bar
|
||||
{
|
||||
public static double Height { get; set; } = 28;
|
||||
public static Color BackgroundColor { get; set; } = Color.FromArgb("#558395");
|
||||
public static Color TextColor { get; set; } = Color.FromArgb("#f8f8f8");
|
||||
public static double TextSizeRatio { get; set; } = 1.5;
|
||||
public static Color BorderColor { get; set; } = Colors.DarkSlateBlue;
|
||||
public static double BorderBottom { get; set; } = 1.0;
|
||||
}
|
||||
// Menu.
|
||||
public static class Menu
|
||||
{
|
||||
public static Color BorderColor { get; set; } = Colors.DarkSlateBlue;
|
||||
public static double Border { get; set; } = 1.0;
|
||||
public static Color BackgroundColor { get; set; } = Color.FromArgb("#F0F0F0");
|
||||
public static Color HeaderBackgroundColor { get; set; } = Color.FromArgb("#E0E0E0");
|
||||
}
|
||||
}
|
||||
// Page layout.
|
||||
public static class Page
|
||||
{
|
||||
public static Color BaseColor { get; set; } = Color.FromArgb("#c8e8f5");
|
||||
public static Color BackgroundColor { get; set; } = Color.FromArgb("#e9f6fb");
|
||||
// Header.
|
||||
public static class Header
|
||||
{
|
||||
// Text.
|
||||
public static String TextLeft { get; set; } = "";
|
||||
public static String TextRight { get; set; } = "";
|
||||
// Toolbar.
|
||||
public static DisplayPosition ToolbarDisplay { get; set; } = Sam.DisplayPosition.None;
|
||||
public static bool Display_ToolbarItem_Back { get; set; } = false;
|
||||
// Styling.
|
||||
public static Color BackgroundColor { get; set; } = Colors.Honeydew;
|
||||
public static Color BorderColor { get; set; } = Colors.LightSlateGray;
|
||||
public static double BorderStrokeWidthTop { get; set; } = 2.0;
|
||||
public static double BorderStrokeWidthBottom { get; set; } = 1.0;
|
||||
public static Thickness Padding { get; set; } = new Thickness(8, 4);
|
||||
}
|
||||
// Caption.
|
||||
public static class Caption
|
||||
{
|
||||
public static Color BackgroundColor { get; set; } = Color.FromArgb("#558395");
|
||||
public static double PaddingHorizontal { get; set; } = 4.0;
|
||||
public static double PaddingVertical { get; set; } = 8.0;
|
||||
public static Color TextColor { get; set; } = Color.FromArgb("#f8f8f8");
|
||||
public static double TextSizeRatio { get; set; } = 1.25;
|
||||
}
|
||||
// Navigation.
|
||||
public static class Navigation
|
||||
{
|
||||
public static double BorderTopWidth { get; set; } = 0.75;
|
||||
public static double PaddingVertical { get; set; } = 4.0;
|
||||
public static Color BorderColor { get; set; } = Color.FromArgb("#808080");
|
||||
public static Color BackgroundColor { get; set; } = Color.FromArgb("#e9f6fb");
|
||||
}
|
||||
// Body.
|
||||
public static class Body
|
||||
{
|
||||
public static double PaddingVerticalMin { get; set; } = 4.0;
|
||||
public static double PaddingHorizontalMin { get; set; } = 4.0;
|
||||
}
|
||||
// Footer.
|
||||
public static class Footer
|
||||
{
|
||||
public static String TextLeft { get; set; } = "";
|
||||
public static String TextMiddle { get; set; } = "";
|
||||
public static String TextRight { get; set; } = "";
|
||||
public static String DateTimeFormat { get; set; } = "ddd d-MMM-yyyy HH:mm:ss";
|
||||
public static DisplayPosition DateTimeDisplay { get; set; } = DisplayPosition.None;
|
||||
public static Color BackgroundColor { get; set; } = Colors.Honeydew;
|
||||
public static Color BorderColor { get; set; } = Colors.LightSlateGray;
|
||||
public static double BorderStrokeWidthTop { get; set; } = 1.0;
|
||||
public static double BorderStrokeWidthBottom { get; set; } = 2.0;
|
||||
public static Thickness Padding { get; set; } = new Thickness(8, 4);
|
||||
}
|
||||
}
|
||||
// Fonts.
|
||||
public static class Fonts
|
||||
{
|
||||
// Dynamic font sizing.
|
||||
public static string HtmlFontSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if (SamApplication.MinDeviceDimension > 2000) return "14pt";
|
||||
if (SamApplication.MinDeviceDimension > 1600) return "13pt";
|
||||
if (SamApplication.MinDeviceDimension > 1200) return "12pt";
|
||||
if (SamApplication.MinDeviceDimension > 1000) return "11pt";
|
||||
return "10pt";
|
||||
}
|
||||
}
|
||||
public static double FontSizeRatio
|
||||
{
|
||||
get
|
||||
{
|
||||
if (SamApplication.MinDeviceDimension > 2000) return 1.75;
|
||||
if (SamApplication.MinDeviceDimension > 1600) return 1.50;
|
||||
if (SamApplication.MinDeviceDimension > 1200) return 1.25;
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Data display visuals.
|
||||
public static class Data
|
||||
{
|
||||
// Item list.
|
||||
public static class ItemList
|
||||
{
|
||||
public static double HeaderBorderWidth { get; set; } = 2.0;
|
||||
public static float HeaderBorderRadius = 6.0f;
|
||||
public static Color HeaderBorderColor = Sam.Visuals.Application.Bar.BackgroundColor;
|
||||
public static Color HeaderBackgroundColor = Color.FromArgb("#F0F0F0");
|
||||
}
|
||||
// Associated items panel.
|
||||
public static class AssociatedItems
|
||||
{
|
||||
public static Color CaptionBackgroundColor { get; set; } = Color.FromArgb("#becee4");
|
||||
public static Color CaptionTextColor { get; set; } = Color.FromArgb("#f8f8f8");
|
||||
public static double CaptionTextSizeRatio { get; set; } = 1.2;
|
||||
public static Color BackgroundColor { get; set; } = Color.FromArgb("#dbe4f0");
|
||||
}
|
||||
}
|
||||
// Form.
|
||||
public static class Form
|
||||
{
|
||||
public static Color BackgroundColor { get; set; } = Color.FromArgb("#e9f6fb");
|
||||
public static double GridRowSpacing { get; set; } = 4.0;
|
||||
public static double GridColumnSpacing { get; set; } = 4.0;
|
||||
// Label.
|
||||
public static class Label
|
||||
{
|
||||
public static Thickness Margin { get; set; } = new Thickness(8.0, 4.0, 8.0, 2.0);
|
||||
}
|
||||
// Controls.
|
||||
public static class Controls
|
||||
{
|
||||
public static Thickness Padding { get; set; } = new Thickness(4.0, 2.0, 4.0, 1.0);
|
||||
public static Color BackgroundColor { get; set; } = Color.FromArgb("#F8F8F8");
|
||||
public static Color BorderColor { get; set; } = Color.FromArgb("#E0E0E0");
|
||||
public static double BorderWidth { get; set; } = 0.5;
|
||||
// Native behaviour modified by SamHandler.
|
||||
public static bool NativeNoBorder { get; set; } = false;
|
||||
public static bool NativeNoUnderline { get; set; } = false;
|
||||
public static bool NativeBackgroundClear { get; set; } = false;
|
||||
}
|
||||
// Tab controls.
|
||||
public static class TabControl
|
||||
{
|
||||
public static Color HeaderBackgroundColor { get; set; } = Colors.Transparent;
|
||||
public static Color CaptionBackgroundColor { get; set; } = Color.FromArgb("#E0E0E0");
|
||||
public static Color BodyBackgroundColor { get; set; } = Color.FromArgb("#F8F8F8");
|
||||
public static Thickness BodyPadding { get; set; } = new Thickness(4.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.App
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamApplication : Application
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private Sam.Platform platform;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected SamApplication()
|
||||
{
|
||||
// Determine platform.
|
||||
#if ANDROID
|
||||
platform = Sam.Platform.Android;
|
||||
#elif IOS
|
||||
platform = Sam.Platform.IOS;
|
||||
#elif MACCATALYST
|
||||
platform = Sam.Platform.MacCatalyst;
|
||||
#elif WINDOWS
|
||||
platform = Sam.Platform.Windows;
|
||||
#endif
|
||||
|
||||
// Log environment.
|
||||
SaLogger.Debug("Platform: " + platform.ToString());
|
||||
SaLogger.Debug("AppInfo.AppName: " + AppInfo.Name);
|
||||
SaLogger.Debug("AppInfo.PackageName: " + AppInfo.PackageName);
|
||||
SaLogger.Debug("AppInfo.Version: " + AppInfo.VersionString);
|
||||
SaLogger.Debug("AppInfo.Build: " + AppInfo.BuildString);
|
||||
SaLogger.Debug("DeviceWidth: " + DeviceWidth);
|
||||
SaLogger.Debug("DeviceHeight: " + DeviceHeight);
|
||||
SaLogger.Debug("DeviceDensity: " + DeviceDisplay.MainDisplayInfo.Density);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
public Sam.Platform Platform { get { return platform; } }
|
||||
|
||||
// Device screen size and orientation.
|
||||
public static bool Landscape => DeviceWidth > DeviceHeight;
|
||||
public static double DeviceWidth => DeviceDisplay.MainDisplayInfo.Width;
|
||||
public static double DeviceHeight => DeviceDisplay.MainDisplayInfo.Height;
|
||||
public static double MinDeviceDimension => Math.Min(DeviceWidth, DeviceHeight);
|
||||
public static double MaxDeviceDimension => Math.Max(DeviceWidth, DeviceHeight);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Base
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamComponents
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private bool readOnly = false;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamComponents()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public bool ReadOnly
|
||||
{
|
||||
get { return readOnly; }
|
||||
set { if (readOnly == value) return; readOnly = value; SetControlsReadOnly(); }
|
||||
}
|
||||
public bool Changed { get; protected set; } = false;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n f i g u r e C o m p o n e n t s
|
||||
//-------------------------------------------------------------------
|
||||
protected virtual void ConfigureComponents()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l A c t i v i t y
|
||||
//-------------------------------------------------------------------
|
||||
protected virtual void SetControlActivity()
|
||||
{
|
||||
}
|
||||
protected virtual void SetControlsReadOnly()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Consoles
|
||||
{
|
||||
//======================================================================
|
||||
public class SamWebServiceConsole
|
||||
{
|
||||
//------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Construction.
|
||||
protected SamWebServiceConsole()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//------------------------------------------------------------------
|
||||
}
|
||||
//======================================================================
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
using Sarand.Net.Mobile.Maui.Controls.Views;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Controls.Panels
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamCheckBoxPanel : SamControlPanel
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private readonly SamCheckBox checkbox = new SamCheckBox() { };
|
||||
private readonly TapGestureRecognizer gestureSuffixTap = new TapGestureRecognizer() { };
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamCheckBoxPanel()
|
||||
{
|
||||
// View configuration.
|
||||
HorizontalOptions = LayoutOptions.Start;
|
||||
|
||||
// Control configuration.
|
||||
BorderThickness = 0;
|
||||
BorderColor = Colors.Transparent;
|
||||
BackgroundColor = Colors.Transparent;
|
||||
|
||||
// Checkbox events.
|
||||
checkbox.Focused += Entry_Focused;
|
||||
checkbox.Unfocused += Entry_Unfocused;
|
||||
checkbox.CheckedChanged += Checkbox_CheckedChanged;
|
||||
gestureSuffixTap.Tapped += GestureSuffixTap_Tapped;
|
||||
LabelSuffix.GestureRecognizers.Add(gestureSuffixTap);
|
||||
|
||||
ConfigureComponents();
|
||||
SetControlActivity();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
protected override View ControlView { get { return checkbox; } }
|
||||
public bool IsChecked
|
||||
{
|
||||
get { return checkbox.IsChecked; }
|
||||
set { if (checkbox.IsChecked == value) return; checkbox.IsChecked = value; }
|
||||
}
|
||||
public new LayoutOptions HorizontalOptions
|
||||
{
|
||||
get { return checkbox.HorizontalOptions; }
|
||||
set { checkbox.HorizontalOptions = value; ReadOnlyLabel.HorizontalOptions = checkbox.HorizontalOptions; }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n f i g u r e C o m p o n e n t s
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Control configuration that can be changed dynamically.</summary>
|
||||
public override void ConfigureComponents()
|
||||
{
|
||||
base.ConfigureComponents();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l A c t i v i t y
|
||||
//-------------------------------------------------------------------
|
||||
public override void SetControlActivity()
|
||||
{
|
||||
base.SetControlActivity();
|
||||
SetControlsReadOnly();
|
||||
}
|
||||
public override void SetControlsReadOnly()
|
||||
{
|
||||
base.SetControlsReadOnly();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
private void Entry_Focused(object? sender, FocusEventArgs e)
|
||||
{
|
||||
Control_Focused(sender, e);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
private void Entry_Unfocused(object? sender, FocusEventArgs e)
|
||||
{
|
||||
Control_Unfocused(sender, e);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
// Checked changed.
|
||||
public event EventHandler<CheckedChangedEventArgs>? CheckedChanged;
|
||||
private void Checkbox_CheckedChanged(object? sender, CheckedChangedEventArgs e)
|
||||
{
|
||||
ReadOnlyText = checkbox.IsChecked ? "X" : "";
|
||||
if (ReadOnly) return;
|
||||
if (CheckedChanged != null) CheckedChanged.Invoke(sender, e);
|
||||
}
|
||||
|
||||
private void GestureSuffixTap_Tapped(object? sender, TappedEventArgs e)
|
||||
{
|
||||
checkbox.IsChecked = !checkbox.IsChecked;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// V i e w E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnParentSet()
|
||||
{
|
||||
base.OnParentSet();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnPropertyChanging([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanging(propertyName);
|
||||
}
|
||||
protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
//Logger.Debug(GetType().Name + ".OnPropertyChanged Name=" + propertyName);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnChildAdded(Element child)
|
||||
{
|
||||
base.OnChildAdded(child);
|
||||
}
|
||||
protected override void OnChildRemoved(Element child, int oldLogicalIndex)
|
||||
{
|
||||
base.OnChildRemoved(child, oldLogicalIndex);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnSizeAllocated(double width, double height)
|
||||
{
|
||||
base.OnSizeAllocated(width, height);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
using Sarand.Net.Mobile.Maui.App;
|
||||
using Sarand.Net.Mobile.Maui.Views;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Controls.Views
|
||||
{
|
||||
//=======================================================================
|
||||
public abstract class SamControlPanel : SamContentView
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
// Components.
|
||||
private HorizontalStackLayout controlLayout = new HorizontalStackLayout();
|
||||
private SamContentView controlBorder = new SamContentView();
|
||||
private SamContentView controlPanel = new SamContentView() { Padding = Sam.Visuals.Form.Controls.Padding };
|
||||
// Styling.
|
||||
private Thickness controlBorderThickness = new Thickness(Sam.Visuals.Form.Controls.BorderWidth);
|
||||
private Color controlBorderColor = Sam.Visuals.Form.Controls.BorderColor;
|
||||
private Color controlBackgroundColor = Sam.Visuals.Form.Controls.BackgroundColor;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
protected SamControlPanel()
|
||||
{
|
||||
// Control layout: [Border[Panel]] [Suffix].
|
||||
controlBorder.Content = controlPanel;
|
||||
controlLayout.Add(controlBorder);
|
||||
controlLayout.Add(LabelSuffix);
|
||||
|
||||
// Main layout.
|
||||
Content = controlLayout;
|
||||
|
||||
SetControlActivity();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
// Label.
|
||||
public SamLabel Label { get; } = new SamLabel() { Margin = Sam.Visuals.Form.Label.Margin };
|
||||
public String LabelText { get { return Label.Text; } set { if (Label.Text.Equals(value)) return; Label.Text = value; } }
|
||||
|
||||
// Control.
|
||||
/// <summary>The control itself. NB May be composite</summary>
|
||||
protected abstract View ControlView { get; }
|
||||
/// <summary>Control used for read-only display.</summary>
|
||||
protected SamLabel ReadOnlyLabel { get; } =
|
||||
new SamLabel() { BackgroundColor = Colors.Transparent };
|
||||
|
||||
// Suffix.
|
||||
protected SamLabel LabelSuffix { get; } = new SamLabel() { Margin = Sam.Visuals.Form.Label.Margin };
|
||||
public String SuffixText { get { return LabelSuffix.Text; } set { if (LabelSuffix.Text.Equals(value)) return; LabelSuffix.Text = value; } }
|
||||
public double SuffixPadding { get { return LabelSuffix.Padding.Left; } set { if (LabelSuffix.Padding.Left == value) return; LabelSuffix.Padding = new(value, 0, 0, 0); } }
|
||||
|
||||
// Styling.
|
||||
public new Color BackgroundColor
|
||||
{
|
||||
get { return controlBackgroundColor; }
|
||||
set { controlBackgroundColor = value; ConfigureComponents(); }
|
||||
}
|
||||
public Thickness BorderThickness
|
||||
{
|
||||
get { return controlBorderThickness; }
|
||||
set { controlBorderThickness = value; ConfigureComponents(); }
|
||||
}
|
||||
public double BorderWidth
|
||||
{
|
||||
set { BorderThickness = new Thickness(value); }
|
||||
}
|
||||
public Color BorderColor
|
||||
{
|
||||
get { return controlBorderColor; }
|
||||
set { controlBorderColor = value; }
|
||||
}
|
||||
public new LayoutOptions HorizontalOptions
|
||||
{
|
||||
get { return base.HorizontalOptions; }
|
||||
set { base.HorizontalOptions = value; ControlView.HorizontalOptions = value; }
|
||||
}
|
||||
protected String ReadOnlyText
|
||||
{
|
||||
get { return ReadOnlyLabel.Text; }
|
||||
set { if (ReadOnlyLabel.Text.Equals(value)) return; ReadOnlyLabel.Text = value; }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n f i g u r e C o m p o n e n t s
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Control configuration that can be changed dynamically.</summary>
|
||||
public override void ConfigureComponents()
|
||||
{
|
||||
// Outer view acts as border.
|
||||
controlBorder.BackgroundColor = controlBorderColor;
|
||||
controlBorder.Padding = controlBorderThickness;
|
||||
controlPanel.BackgroundColor = controlBackgroundColor;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l A c t i v i t y
|
||||
//-------------------------------------------------------------------
|
||||
public override void SetControlActivity()
|
||||
{
|
||||
base.SetControlActivity();
|
||||
}
|
||||
public override void SetControlsReadOnly()
|
||||
{
|
||||
base.SetControlsReadOnly();
|
||||
if (ReadOnly) controlPanel.Content = ReadOnlyLabel;
|
||||
else controlPanel.Content = ControlView;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
public new event EventHandler<FocusEventArgs>? Focused;
|
||||
protected void Control_Focused(object? sender, FocusEventArgs e)
|
||||
{
|
||||
if (Focused != null) Focused.Invoke(sender, e);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
public new event EventHandler<FocusEventArgs>? Unfocused;
|
||||
protected void Control_Unfocused(object? sender, FocusEventArgs e)
|
||||
{
|
||||
if (Unfocused != null) Unfocused.Invoke(sender, e);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// V i e w E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
//Logger.Debug(GetType().Name + ".OnPropertyChanged Name=" + propertyName);
|
||||
|
||||
if (propertyName.EqualsCI(PaddingProperty.PropertyName))
|
||||
{
|
||||
if (!controlPanel.Padding.Equals(Padding))
|
||||
{
|
||||
// Apply the padding to the embedded view and clear this view's padding.
|
||||
controlPanel.Padding = Padding;
|
||||
Padding = new Thickness();
|
||||
}
|
||||
}
|
||||
else if (propertyName.EqualsCI(BackgroundColorProperty.PropertyName))
|
||||
{
|
||||
controlPanel.BackgroundColor = BackgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Controls.Views
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamEntryPanel : SamControlPanel
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private readonly SamEntry entry = new SamEntry() { HorizontalOptions = LayoutOptions.Fill };
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamEntryPanel()
|
||||
{
|
||||
// View configuration.
|
||||
HorizontalOptions = LayoutOptions.Start;
|
||||
|
||||
// Control configuration.
|
||||
entry.BackgroundColor = Colors.Transparent;
|
||||
|
||||
// Entry events.
|
||||
entry.Focused += Entry_Focused;
|
||||
entry.Unfocused += Entry_Unfocused;
|
||||
entry.TextChanged += Entry_TextChanged;
|
||||
entry.Completed += Entry_Completed;
|
||||
|
||||
SetControlActivity();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
protected override View ControlView { get { return entry; } }
|
||||
public int MaxLength
|
||||
{
|
||||
get { return entry.MaxLength; }
|
||||
set { entry.MaxLength = value; }
|
||||
}
|
||||
public SamEntry.TextCaseType TextCase
|
||||
{
|
||||
get { return entry.TextCase; }
|
||||
set { entry.TextCase = value; }
|
||||
}
|
||||
public bool NumericOnly
|
||||
{
|
||||
get { return entry.NumericOnly; }
|
||||
set { entry.NumericOnly = value; ReadOnlyLabel.HorizontalTextAlignment = entry.HorizontalTextAlignment; }
|
||||
}
|
||||
public byte Decimals
|
||||
{
|
||||
get { return entry.Decimals; }
|
||||
set { entry.Decimals = value; ReadOnlyLabel.HorizontalTextAlignment = entry.HorizontalTextAlignment; }
|
||||
}
|
||||
public Keyboard Keyboard
|
||||
{
|
||||
get { return entry.Keyboard; }
|
||||
set { entry.Keyboard = value; }
|
||||
}
|
||||
public bool IsPassword
|
||||
{
|
||||
get { return entry.IsPassword; }
|
||||
set { entry.IsPassword = value; }
|
||||
}
|
||||
public String Text
|
||||
{
|
||||
get { return entry.Text; }
|
||||
set { value = StringUtil.EmptyOnNull(value); if (entry.Text != null && entry.Text.Equals(value)) return; entry.Text = value; }
|
||||
}
|
||||
public new double WidthRequest
|
||||
{
|
||||
get { return entry.WidthRequest; }
|
||||
set { entry.WidthRequest = value; ReadOnlyLabel.WidthRequest = value; }
|
||||
}
|
||||
public TextAlignment HorizontalTextAlignment
|
||||
{
|
||||
get { return entry.HorizontalTextAlignment; }
|
||||
set { entry.HorizontalTextAlignment = value; ReadOnlyLabel.HorizontalTextAlignment = entry.HorizontalTextAlignment; }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n f i g u r e C o m p o n e n t s
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Control configuration that can be changed dynamically.</summary>
|
||||
public override void ConfigureComponents()
|
||||
{
|
||||
base.ConfigureComponents();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l A c t i v i t y
|
||||
//-------------------------------------------------------------------
|
||||
public override void SetControlActivity()
|
||||
{
|
||||
base.SetControlActivity();
|
||||
SetControlsReadOnly();
|
||||
}
|
||||
public override void SetControlsReadOnly()
|
||||
{
|
||||
base.SetControlsReadOnly();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
private void Entry_Focused(object? sender, FocusEventArgs e)
|
||||
{
|
||||
Control_Focused(sender, e);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
private void Entry_Unfocused(object? sender, FocusEventArgs e)
|
||||
{
|
||||
Control_Unfocused(sender, e);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
// Text changed.
|
||||
public event EventHandler<TextChangedEventArgs>? TextChanged;
|
||||
private void Entry_TextChanged(object? sender, TextChangedEventArgs e)
|
||||
{
|
||||
ReadOnlyText = entry.Text;
|
||||
if (ReadOnly) return;
|
||||
if (TextChanged != null) TextChanged.Invoke(sender, e);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
// Completed.
|
||||
public event EventHandler? Completed;
|
||||
private void Entry_Completed(object? sender, EventArgs e)
|
||||
{
|
||||
if (ReadOnly) return;
|
||||
if (Completed != null) Completed.Invoke(sender, e);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// V i e w E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnParentSet()
|
||||
{
|
||||
base.OnParentSet();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnPropertyChanging([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanging(propertyName);
|
||||
}
|
||||
protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
//Logger.Debug(GetType().Name + ".OnPropertyChanged Name=" + propertyName);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnChildAdded(Element child)
|
||||
{
|
||||
base.OnChildAdded(child);
|
||||
}
|
||||
protected override void OnChildRemoved(Element child, int oldLogicalIndex)
|
||||
{
|
||||
base.OnChildRemoved(child, oldLogicalIndex);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnSizeAllocated(double width, double height)
|
||||
{
|
||||
base.OnSizeAllocated(width, height);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Controls
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamButton : Button
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamButton()
|
||||
{
|
||||
DefaultFontSize = FontSize;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public double DefaultFontSize { get; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Controls
|
||||
{
|
||||
//======================================================================
|
||||
public class SamCheckBox : CheckBox
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamCheckBox()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Control events.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//======================================================================
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
using Sarand.Net.Mobile.Maui.Layouts;
|
||||
using Sarand.Net.Mobile.Maui.Views;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Controls
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamDatePicker : SamContentView
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private bool allowInvalidDate = false;
|
||||
private bool invalidDate = true;
|
||||
private DateTime previousDate = DateTime.MinValue;
|
||||
private SamStackLayout controlLayout = new SamStackLayout() { Orientation = StackOrientation.Horizontal, HorizontalOptions = LayoutOptions.Fill };
|
||||
private DatePicker pickerDate = new DatePicker() { IsVisible = false };
|
||||
private SamEntry entryDate = new SamEntry() { HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.Fill };
|
||||
private SamLabel labelResetDate = new SamLabel() { Text = "X", FontAttributes = FontAttributes.Bold, TextColor = Colors.Red, HorizontalOptions = LayoutOptions.Center, VerticalTextAlignment = TextAlignment.Center };
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamDatePicker()
|
||||
{
|
||||
// Initialise controls.
|
||||
// Date picker. Hidden but used to display calendar.
|
||||
DefaultFontSize = pickerDate.FontSize;
|
||||
pickerDate.Format = "dd-MMM-yyyy";
|
||||
pickerDate.DateSelected += PickerDate_DateSelected;
|
||||
// Date display entry.
|
||||
entryDate.FontSize = pickerDate.FontSize;
|
||||
entryDate.FontFamily = pickerDate.FontFamily;
|
||||
entryDate.FontAttributes = pickerDate.FontAttributes;
|
||||
entryDate.TextColor = pickerDate.TextColor;
|
||||
entryDate.Focused += EntryDate_Focused;
|
||||
// 'Reset' date label - to invalidate the date value.
|
||||
labelResetDate.FontSize = pickerDate.FontSize;
|
||||
labelResetDate.FontFamily = pickerDate.FontFamily;
|
||||
|
||||
// 'Reset' label tap gesture.
|
||||
var tapGestureRecognizer = new TapGestureRecognizer();
|
||||
tapGestureRecognizer.Tapped += LabelValidDate_Tapped;
|
||||
labelResetDate.GestureRecognizers.Add(tapGestureRecognizer);
|
||||
|
||||
// Initialise layout.
|
||||
Content = controlLayout;
|
||||
controlLayout.Children.Add(pickerDate);
|
||||
controlLayout.Children.Add(entryDate);
|
||||
controlLayout.Children.Add(labelResetDate);
|
||||
|
||||
RefreshDateDisplay();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
// Configuration.
|
||||
public Boolean AllowInvalid
|
||||
{
|
||||
get { return allowInvalidDate; }
|
||||
set
|
||||
{
|
||||
if (allowInvalidDate = value) return;
|
||||
allowInvalidDate = value;
|
||||
if (!allowInvalidDate) invalidDate = false;
|
||||
RefreshDateDisplay();
|
||||
}
|
||||
}
|
||||
public string Format
|
||||
{
|
||||
get { return pickerDate.Format; }
|
||||
set
|
||||
{
|
||||
if (pickerDate.Format.Equals(value)) return;
|
||||
pickerDate.Format = value;
|
||||
}
|
||||
}
|
||||
public DateTime MinimumDate
|
||||
{
|
||||
get { return pickerDate.MinimumDate; }
|
||||
set { pickerDate.MinimumDate = value; }
|
||||
}
|
||||
public DateTime MaximumDate
|
||||
{
|
||||
get { return pickerDate.MaximumDate; }
|
||||
set { pickerDate.MaximumDate = value; }
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
// Date value.
|
||||
public DateTime Date
|
||||
{
|
||||
get
|
||||
{
|
||||
if (invalidDate) return DateTime.MinValue;
|
||||
return pickerDate.Date;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (Date.Equals(value)) return;
|
||||
if (!DateUtil.IsValid(value))
|
||||
{
|
||||
invalidDate = true;
|
||||
pickerDate.Date = DateTime.Today;
|
||||
}
|
||||
else
|
||||
{
|
||||
invalidDate = false;
|
||||
pickerDate.Date = value;
|
||||
}
|
||||
previousDate = value;
|
||||
}
|
||||
}
|
||||
public String FormattedDate { get { return !invalidDate ? DateUtil.Format(Date, pickerDate.Format) : ""; } }
|
||||
//-------------------------------------------------------------------
|
||||
// Font.
|
||||
public double DefaultFontSize { get; }
|
||||
public double FontSize
|
||||
{
|
||||
get { return pickerDate.FontSize; }
|
||||
set
|
||||
{
|
||||
if (pickerDate.FontSize == value) return;
|
||||
pickerDate.FontSize = value;
|
||||
entryDate.FontSize = value;
|
||||
}
|
||||
}
|
||||
public String FontFamily
|
||||
{
|
||||
get { return pickerDate.FontFamily; }
|
||||
set
|
||||
{
|
||||
if (pickerDate.FontFamily == value) return;
|
||||
pickerDate.FontFamily = value;
|
||||
entryDate.FontFamily = value;
|
||||
}
|
||||
}
|
||||
public FontAttributes FontAttributes
|
||||
{
|
||||
get { return pickerDate.FontAttributes; }
|
||||
set
|
||||
{
|
||||
if (pickerDate.FontAttributes == value) return;
|
||||
pickerDate.FontAttributes = value;
|
||||
entryDate.FontAttributes = value;
|
||||
}
|
||||
}
|
||||
public Color TextColor
|
||||
{
|
||||
get { return pickerDate.TextColor; }
|
||||
set
|
||||
{
|
||||
if (pickerDate.TextColor == value) return;
|
||||
pickerDate.TextColor = value;
|
||||
entryDate.TextColor = value;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Utilities.
|
||||
private void RefreshDateDisplay()
|
||||
{
|
||||
if (allowInvalidDate)
|
||||
{
|
||||
pickerDate.IsVisible = false;
|
||||
entryDate.IsVisible = true;
|
||||
labelResetDate.IsVisible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pickerDate.IsVisible = true;
|
||||
entryDate.IsVisible = false;
|
||||
labelResetDate.IsVisible = false;
|
||||
}
|
||||
String dateValue = "";
|
||||
if (!invalidDate)
|
||||
dateValue = DateUtil.Format(Date, pickerDate.Format);
|
||||
entryDate.Text = dateValue;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
private void PickerDate_DateSelected(object? sender, DateChangedEventArgs e)
|
||||
{
|
||||
// Date has changed in control.
|
||||
invalidDate = !DateUtil.IsValid(e.NewDate);
|
||||
RefreshDateDisplay();
|
||||
if (DateSelected != null) DateSelected.Invoke(sender, e);
|
||||
}
|
||||
public event EventHandler<DateChangedEventArgs>? DateSelected;
|
||||
//-------------------------------------------------------------------
|
||||
private void EntryDate_Focused(object? sender, FocusEventArgs e)
|
||||
{
|
||||
// Control has gained focus.
|
||||
entryDate.Unfocus();
|
||||
pickerDate.Focus();
|
||||
invalidDate = false;
|
||||
RefreshDateDisplay();
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
private void LabelValidDate_Tapped(object? sender, EventArgs e)
|
||||
{
|
||||
// 'Valid' label tapped.
|
||||
if (invalidDate) return;
|
||||
invalidDate = true;
|
||||
DateTime oldDate = previousDate;
|
||||
RefreshDateDisplay();
|
||||
if (DateSelected != null) DateSelected.Invoke(sender, new DateChangedEventArgs(oldDate, Date));
|
||||
previousDate = Date;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
using Sarand.Net.Mobile.Maui.Layouts;
|
||||
using Sarand.Net.Mobile.Maui.Views;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Controls
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamDateTimePicker : SamContentView
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
// Control layout.
|
||||
private SamStackLayout layoutControl = new SamStackLayout() { Orientation = StackOrientation.Horizontal };
|
||||
private SamDatePicker pickerDate = new SamDatePicker();
|
||||
private SamLabel labelTimePrefix = new SamLabel();
|
||||
private SamTimePicker pickerTime = new SamTimePicker();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamDateTimePicker()
|
||||
{
|
||||
DefaultFontSize = pickerDate.FontSize;
|
||||
|
||||
// Configure components.
|
||||
Content = layoutControl;
|
||||
layoutControl.Children.Add(pickerDate);
|
||||
layoutControl.Children.Add(pickerTime);
|
||||
|
||||
// Control events.
|
||||
pickerDate.DateSelected += PickerDate_DateSelected;
|
||||
pickerTime.TimeChanged += PickerTime_TimeChanged;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public string DateFormat
|
||||
{
|
||||
get { return pickerDate.Format; }
|
||||
set
|
||||
{
|
||||
if (pickerDate.Format.Equals(value)) return;
|
||||
pickerDate.Format = value;
|
||||
}
|
||||
}
|
||||
public DateTime MinimumDate
|
||||
{
|
||||
get { return pickerDate.MinimumDate; }
|
||||
set { pickerDate.MinimumDate = value; }
|
||||
}
|
||||
public DateTime MaximumDate
|
||||
{
|
||||
get { return pickerDate.MaximumDate; }
|
||||
set { pickerDate.MaximumDate = value; }
|
||||
}
|
||||
public string TimeFormat
|
||||
{
|
||||
get { return pickerTime.Format; }
|
||||
set
|
||||
{
|
||||
if (pickerTime.Format.Equals(value)) return;
|
||||
pickerTime.Format = value;
|
||||
}
|
||||
}
|
||||
// Control value.
|
||||
public DateTime DateTime
|
||||
{
|
||||
get { return pickerDate.Date.Date + pickerTime.Time; }
|
||||
set
|
||||
{
|
||||
if (DateTime.CompareTo(value) == 0) return;
|
||||
pickerDate.Date = value.Date;
|
||||
pickerTime.Time = value - value.Date;
|
||||
}
|
||||
}
|
||||
public String DateTimeDelim { get; set; } = " ";
|
||||
public String FormattedDateTime { get { return pickerDate.FormattedDate + DateTimeDelim + pickerTime.FormattedTime; } }
|
||||
// Styling.
|
||||
public double DefaultFontSize { get; }
|
||||
public double FontSize
|
||||
{
|
||||
get { return pickerDate.FontSize; }
|
||||
set { if (pickerDate.FontSize == value) return; pickerDate.FontSize = value; pickerTime.FontSize = value; labelTimePrefix.FontSize = value; }
|
||||
}
|
||||
/// <summary>Amount of space between date and time pickers.</summary>
|
||||
public double ControlSpacing
|
||||
{
|
||||
get { return layoutControl.Spacing; }
|
||||
set { if (layoutControl.Spacing == value) return; layoutControl.Spacing = value; }
|
||||
}
|
||||
public String TimePickerPrefixText
|
||||
{
|
||||
get { return labelTimePrefix.Text; }
|
||||
set { value = StringUtil.TrimAll(value); if (labelTimePrefix.Text.Equals(value)) return; labelTimePrefix.Text = value; ConfigureComponents(); }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n f i g u r e C o m p o n e n t s
|
||||
//-------------------------------------------------------------------
|
||||
public override void ConfigureComponents()
|
||||
{
|
||||
base.ConfigureComponents();
|
||||
|
||||
// Time Picker prefix label text.
|
||||
if (!StringUtil.IsEmpty(TimePickerPrefixText))
|
||||
{
|
||||
// Label has text - ensure label is in the layout.
|
||||
if (!layoutControl.Children.Contains(labelTimePrefix))
|
||||
{
|
||||
// Label will be inserted before the time picker.
|
||||
int insertIdx = layoutControl.Children.IndexOf(pickerTime);
|
||||
layoutControl.Children.Insert(insertIdx, labelTimePrefix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Blank label text - remove label from layout.
|
||||
if (layoutControl.Children.Contains(labelTimePrefix))
|
||||
layoutControl.Children.Remove(labelTimePrefix);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l A c t i v i t y
|
||||
//-------------------------------------------------------------------
|
||||
public override void SetControlActivity()
|
||||
{
|
||||
base.SetControlActivity();
|
||||
}
|
||||
public override void SetControlsReadOnly()
|
||||
{
|
||||
base.SetControlsReadOnly();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
private void PickerDate_DateSelected(object? sender, DateChangedEventArgs e)
|
||||
{
|
||||
if (DateSelected != null) DateSelected.Invoke(sender, e);
|
||||
}
|
||||
public event EventHandler<DateChangedEventArgs>? DateSelected;
|
||||
//-------------------------------------------------------------------
|
||||
private void PickerTime_TimeChanged(object? sender, SamTimePicker.TimeChangedEventArgs e)
|
||||
{
|
||||
if (TimeChanged != null) TimeChanged.Invoke(sender, e);
|
||||
}
|
||||
public event EventHandler<SamTimePicker.TimeChangedEventArgs>? TimeChanged;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using Sarand.Net.Mobile.Maui.App;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Controls
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamEditor : Editor
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private bool trimTextOnCompletion = true;
|
||||
private int NumberOfLinesPrevious = 0;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamEditor()
|
||||
{
|
||||
DefaultFontSize = FontSize;
|
||||
Text = "";
|
||||
TextChanged += SamEditor_TextChanged;
|
||||
Completed += SamEditor_Completed;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
public double DefaultFontSize { get; }
|
||||
|
||||
public bool TrimText
|
||||
{
|
||||
get { return trimTextOnCompletion; }
|
||||
set
|
||||
{
|
||||
if (trimTextOnCompletion == value) return;
|
||||
trimTextOnCompletion = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Native behaviour modified by SamHandler.
|
||||
public bool NativeNoBorder { get; set; } = Sam.Visuals.Form.Controls.NativeNoBorder;
|
||||
public bool NativeNoUnderline { get; set; } = Sam.Visuals.Form.Controls.NativeNoUnderline;
|
||||
public bool NativeBackgroundClear { get; set; } = Sam.Visuals.Form.Controls.NativeBackgroundClear;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
// Key Press event is not supported directly in Xamarin.
|
||||
// Requires O/S specific implementation.
|
||||
// See: Sarand.LogisticsMgr.Mobile.Droid.Forms.Renderers.SlmEditorRenderer
|
||||
public void OnKeyPress_Enter()
|
||||
{
|
||||
// Resize control based on entered text.
|
||||
InvalidateMeasure();
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
private void SamEditor_TextChanged(object? sender, TextChangedEventArgs e)
|
||||
{
|
||||
// If the number of lines of text has changed, resize the control.
|
||||
int NumberOfLines = StringUtil.EmptyOnNull(Text).Split('\n').Length;
|
||||
if (NumberOfLines != NumberOfLinesPrevious)
|
||||
// Resize control based on entered text.
|
||||
InvalidateMeasure();
|
||||
NumberOfLinesPrevious = NumberOfLines;
|
||||
}
|
||||
private void SamEditor_Completed(object? sender, EventArgs e)
|
||||
{
|
||||
if (trimTextOnCompletion)
|
||||
Text = Text.Trim();
|
||||
// Resize control based on entered text.
|
||||
InvalidateMeasure();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
using Sarand.Net.Mobile.Maui.App;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Controls
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamEntry : Entry
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public enum TextCaseType
|
||||
{
|
||||
Normal,
|
||||
Upper,
|
||||
Lower,
|
||||
Title
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private bool trimTextOnCompletion = true;
|
||||
private TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo;
|
||||
private TextCaseType textCase = TextCaseType.Normal;
|
||||
private bool numericOnly = false;
|
||||
private byte decimals = 0;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamEntry()
|
||||
{
|
||||
DefaultFontSize = FontSize;
|
||||
TextChanged += SamEntry_TextChanged;
|
||||
Completed += SamEntry_Completed;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public bool TrimText
|
||||
{
|
||||
get { return trimTextOnCompletion; }
|
||||
set
|
||||
{
|
||||
if (trimTextOnCompletion == value) return;
|
||||
trimTextOnCompletion = value;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether to format text as it is entered.
|
||||
/// <para>NB This can lead to problems with the cursor position and typing doesn't give expected results.</para>
|
||||
/// <para>Default: False.</para>
|
||||
/// </summary>
|
||||
public bool FormatTextOnChange { get; set; } = false;
|
||||
public double DefaultFontSize { get; }
|
||||
public TextCaseType TextCase
|
||||
{
|
||||
get { return textCase; }
|
||||
set
|
||||
{
|
||||
if (textCase == value) return;
|
||||
textCase = value;
|
||||
FormatText();
|
||||
}
|
||||
}
|
||||
public bool NumericOnly
|
||||
{
|
||||
get { return numericOnly; }
|
||||
set
|
||||
{
|
||||
if (numericOnly == value) return;
|
||||
numericOnly = value;
|
||||
if (numericOnly)
|
||||
HorizontalTextAlignment = TextAlignment.End;
|
||||
Keyboard = Keyboard.Numeric;
|
||||
FormatText();
|
||||
}
|
||||
}
|
||||
public byte Decimals
|
||||
{
|
||||
get { return decimals; }
|
||||
set
|
||||
{
|
||||
if (numericOnly && decimals == value) return;
|
||||
numericOnly = true;
|
||||
HorizontalTextAlignment = TextAlignment.End;
|
||||
decimals = value;
|
||||
Keyboard = Keyboard.Numeric;
|
||||
FormatText();
|
||||
}
|
||||
}
|
||||
|
||||
// Native behaviour modified by SamHandler.
|
||||
public bool NativeNoBorder { get; set; } = Sam.Visuals.Form.Controls.NativeNoBorder;
|
||||
public bool NativeNoUnderline { get; set; } = Sam.Visuals.Form.Controls.NativeNoUnderline;
|
||||
public bool NativeBackgroundClear { get; set; } = Sam.Visuals.Form.Controls.NativeBackgroundClear;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// F o r m a t T e x t
|
||||
//-------------------------------------------------------------------
|
||||
private void FormatText(bool trimText = false)
|
||||
{
|
||||
String fn = GetType().Name + ".FormatText";
|
||||
String originalText = Text;
|
||||
String formattedText = originalText;
|
||||
if (StringUtil.IsEmpty(formattedText)) return;
|
||||
if (trimText)
|
||||
formattedText = StringUtil.TrimAll(formattedText);
|
||||
|
||||
if (numericOnly)
|
||||
{
|
||||
if (decimals > 0)
|
||||
{
|
||||
decimal value = StringUtil.ToDecimal(formattedText);
|
||||
if (value != 0.0m)
|
||||
formattedText = value.ToString("N" + decimals);
|
||||
else if (!formattedText.Equals("0"))
|
||||
formattedText = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
long value = StringUtil.ToLong(formattedText);
|
||||
if (value != 0)
|
||||
formattedText = value.ToString();
|
||||
else if (!formattedText.Equals("0"))
|
||||
formattedText = "";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (textCase == TextCaseType.Upper)
|
||||
formattedText = textInfo.ToUpper(formattedText);
|
||||
else if (textCase == TextCaseType.Lower)
|
||||
formattedText = textInfo.ToLower(formattedText);
|
||||
else if (textCase == TextCaseType.Title)
|
||||
formattedText =
|
||||
StringUtil.ToTitleCase(formattedText, textInfo);
|
||||
}
|
||||
|
||||
if (!originalText.Equals(formattedText))
|
||||
{
|
||||
SaLogger.Debug(fn + " Text: " + originalText + ". Formatted: " + formattedText);
|
||||
Text = formattedText;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
private void SamEntry_TextChanged(object? sender, TextChangedEventArgs e)
|
||||
{
|
||||
if (FormatTextOnChange) FormatText();
|
||||
}
|
||||
private void SamEntry_Completed(object? sender, EventArgs e)
|
||||
{
|
||||
FormatText(trimTextOnCompletion);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Controls
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamImageButton : ImageButton
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamImageButton()
|
||||
{
|
||||
//Clicked += Button_Clicked;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Events.
|
||||
protected virtual void Button_Clicked(object? sender, EventArgs e)
|
||||
{
|
||||
SaLogger.Info(SysUtil.Fn + " Button clicked.");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Controls
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamLabel : Label
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private double fontSize;
|
||||
private double fontSizeProportion = 1.0;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamLabel()
|
||||
{
|
||||
fontSize = base.FontSize;
|
||||
FontSizeDefault = fontSize;
|
||||
Text = "";
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
/// <summary>Default (initial) font size.</summary>
|
||||
public double FontSizeDefault { get; private set; }
|
||||
|
||||
public new double FontSize
|
||||
{
|
||||
get { return fontSize; }
|
||||
set { fontSize = value; base.FontSize = fontSize * fontSizeProportion; }
|
||||
}
|
||||
|
||||
/// <summary>Font size proportion.</summary>
|
||||
public double FontSizeProportion
|
||||
{
|
||||
get { return fontSizeProportion; }
|
||||
set { fontSizeProportion = value; base.FontSize = fontSize * fontSizeProportion; }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Control events.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// View events.
|
||||
|
||||
protected override void OnPropertyChanging([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanging(propertyName);
|
||||
if (propertyName.EqualsCI("FontSize"))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
if (propertyName.EqualsCI("FontSize"))
|
||||
{
|
||||
if (FontSizeDefault <= 0)
|
||||
FontSizeDefault = base.FontSize;
|
||||
fontSize = base.FontSize;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
using Sarand.Net.Mobile.Maui.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Controls
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamPicker : Picker
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public class SamPickerItem
|
||||
{
|
||||
public SysId Id { get; set; } = new SysId();
|
||||
public String Code { get; set; } = "";
|
||||
public String Caption { get; set; } = "";
|
||||
public Object? Object { get; set; }
|
||||
public override string ToString()
|
||||
{
|
||||
return Caption;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private readonly List<SamPickerItem> pickerItems = new List<SamPickerItem>();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamPicker()
|
||||
{
|
||||
DefaultFontSize = FontSize;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
public double DefaultFontSize { get; }
|
||||
public bool BeingPopulated { get; protected set; } = false;
|
||||
|
||||
// Native behaviour modified by SamHandler.
|
||||
public bool NativeNoBorder { get; set; } = Sam.Visuals.Form.Controls.NativeNoBorder;
|
||||
public bool NativeNoUnderline { get; set; } = Sam.Visuals.Form.Controls.NativeNoUnderline;
|
||||
public bool NativeBackgroundClear { get; set; } = Sam.Visuals.Form.Controls.NativeBackgroundClear;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// P o p u l a t e I t e m s
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Does the list contain an item with the same Id.
|
||||
/// <para>NB Invalid Id values are matched.</para>
|
||||
/// </summary>
|
||||
public bool ContainsItemId(SysId id)
|
||||
{
|
||||
return pickerItems.Exists(item => SysId.ToInt(item.Id) == SysId.ToInt(id));
|
||||
}
|
||||
/// <summary>
|
||||
/// Does the list contain an item with the same code.
|
||||
/// <para>NB Codes are case-insensitive.</para>
|
||||
/// </summary>
|
||||
public bool ContainsItemCode(String code)
|
||||
{
|
||||
return pickerItems.Exists(item => item.Code.EqualsCI(code));
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Remove all items from the picker.</summary>
|
||||
public void ClearItems()
|
||||
{
|
||||
Items.Clear();
|
||||
ItemsSource = null;
|
||||
pickerItems.Clear();
|
||||
}
|
||||
/// <summary>Replace existing picker item list.</summary>
|
||||
public void SetItems(List<SamPickerItem> pickerItems)
|
||||
{
|
||||
ClearItems();
|
||||
this.pickerItems.AddRange(pickerItems);
|
||||
RefreshPickerItems();
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Add an item identified by a SysId value.
|
||||
/// <para>NB Fails if an item already exists with the same id.</para>
|
||||
/// </summary>
|
||||
public bool AddItem(SysId id, String caption)
|
||||
{
|
||||
if (ContainsItemId(id)) return false;
|
||||
pickerItems.Add(new SamPickerItem() { Id = id, Caption = caption });
|
||||
RefreshPickerItems();
|
||||
return ContainsItemId(id);
|
||||
}
|
||||
/// <summary>
|
||||
/// Add an item identified by a code value.
|
||||
/// <para>NB Fails if an item already exists with the same case-insensitive code.</para>
|
||||
/// </summary>
|
||||
public bool AddItem(String code, String caption)
|
||||
{
|
||||
if (ContainsItemCode(code)) return false;
|
||||
pickerItems.Add(new SamPickerItem() { Code = code, Caption = caption });
|
||||
RefreshPickerItems();
|
||||
return ContainsItemCode(code);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
private void RefreshPickerItems()
|
||||
{
|
||||
//SetBinding(Picker.ItemsSourceProperty, BindableProperty.Create());
|
||||
//ItemDisplayBinding = new Binding("Caption");
|
||||
// Picker items doesn't automatically keep up to date with teh ItemsSource list.
|
||||
// So clear it and reset to force the refresh.
|
||||
ItemsSource = null;
|
||||
ItemsSource = pickerItems;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// I t e m S e l e c t i o n
|
||||
//-------------------------------------------------------------------
|
||||
public SamPickerItem? SelectedPickerItem
|
||||
{
|
||||
get
|
||||
{
|
||||
object selectedItem = SelectedItem;
|
||||
if (selectedItem == null || !(selectedItem is SamPickerItem)) return null;
|
||||
return (selectedItem as SamPickerItem);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (SelectedPickerItem == value) return;
|
||||
if (ItemsSource == null || !ItemsSource.Contains(value)) return;
|
||||
base.SelectedItem = value;
|
||||
}
|
||||
}
|
||||
public SysId SelectedItemId
|
||||
{
|
||||
get
|
||||
{
|
||||
SamPickerItem? selectedPickerItem = SelectedPickerItem;
|
||||
return selectedPickerItem?.Id ?? new SysId();
|
||||
}
|
||||
set
|
||||
{
|
||||
SelectedPickerItem = pickerItems.Find(item => item.Id.Equals(value));
|
||||
}
|
||||
}
|
||||
public String SelectedItemCode
|
||||
{
|
||||
get
|
||||
{
|
||||
SamPickerItem? selectedPickerItem = SelectedPickerItem;
|
||||
return selectedPickerItem?.Code ?? "";
|
||||
}
|
||||
set
|
||||
{
|
||||
SelectedPickerItem = pickerItems.Find(item => item.Code.EqualsCI(value));
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
// Picker population completed.
|
||||
public class PopulatedEventArgs : EventArgs { }
|
||||
public delegate void PopulatedEventHandler(object? sender, PopulatedEventArgs e);
|
||||
/// <summary>Picker population completed event handler.</summary>
|
||||
public event PopulatedEventHandler? Populated;
|
||||
protected void InvokePopulatedEvent()
|
||||
{
|
||||
if (Populated != null) Populated.Invoke(this, new PopulatedEventArgs() { });
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
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
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Controls
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamTimePicker : TimePicker
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamTimePicker()
|
||||
{
|
||||
DefaultFontSize = FontSize;
|
||||
Format = "HH:mm";
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public String FormattedTime { get { return DateUtil.Format(DateTime.Today + Time, Format); } }
|
||||
// Styling.
|
||||
public double DefaultFontSize { get; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
public class TimeChangedEventArgs : EventArgs { };
|
||||
public event EventHandler<TimeChangedEventArgs>? TimeChanged;
|
||||
protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
if (propertyName.EqualsCI(TimePicker.TimeProperty.PropertyName))
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
if (TimeChanged != null) TimeChanged.Invoke(this, new TimeChangedEventArgs());
|
||||
return;
|
||||
}
|
||||
base.OnPropertyChanged(propertyName);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Controls
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamWebView : WebView
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
public String html = "";
|
||||
private HtmlWebViewSource htmlSource;
|
||||
private UrlWebViewSource aboutBlankSource = new UrlWebViewSource() { Url = "about:blank" };
|
||||
// Managers.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamWebView()
|
||||
{
|
||||
// Events.
|
||||
Navigating += WebView_Navigating;
|
||||
Navigated += WebView_Navigated;
|
||||
|
||||
// HTML source.
|
||||
htmlSource = new HtmlWebViewSource() { Html = html };
|
||||
Source = aboutBlankSource;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
// HTML Panel.
|
||||
public static String AppActionPrefix => "App:";
|
||||
public String Html
|
||||
{
|
||||
get { return html; }
|
||||
set
|
||||
{
|
||||
Source = aboutBlankSource;
|
||||
htmlSource.Html = null;
|
||||
html = value;
|
||||
htmlSource.Html = html;
|
||||
Source = htmlSource;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// N a v i g a t i o n
|
||||
//-------------------------------------------------------------------
|
||||
public class AppNavigatingEventArgs : EventArgs
|
||||
{
|
||||
public AppNavigatingEventArgs(String appAction)
|
||||
{
|
||||
this.AppAction = appAction;
|
||||
}
|
||||
public String AppAction { get; }
|
||||
}
|
||||
public delegate void AppNavigatingEventHandler(object? sender, AppNavigatingEventArgs e);
|
||||
public event AppNavigatingEventHandler? AppNavigating;
|
||||
private void OnAppNavigating(String appAction)
|
||||
{
|
||||
if (AppNavigating != null) AppNavigating.Invoke(this, new AppNavigatingEventArgs(appAction));
|
||||
}
|
||||
private String GetAppAction(String location)
|
||||
{
|
||||
if (!location.StartsWithCI(AppActionPrefix)) return "";
|
||||
return location.Right(location.Length - AppActionPrefix.Length);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
private void WebView_Navigating(object? sender, WebNavigatingEventArgs e)
|
||||
{
|
||||
String appAction = GetAppAction(e.Url);
|
||||
SaLogger.Debug("SamWebView_Navigating URL: " + e.Url + ". App action: " + appAction);
|
||||
if (!StringUtil.IsEmpty(appAction))
|
||||
{
|
||||
e.Cancel = true;
|
||||
OnAppNavigating(appAction);
|
||||
}
|
||||
}
|
||||
private void WebView_Navigated(object? sender, WebNavigatedEventArgs e)
|
||||
{
|
||||
SaLogger.Debug("SamWebView_Navigated URL: " + e.Url);
|
||||
String appAction = GetAppAction(e.Url);
|
||||
if (!StringUtil.IsEmpty(appAction))
|
||||
{
|
||||
Source = htmlSource;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
#if ANDROID
|
||||
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||
#endif
|
||||
using Sarand.Net.Mobile.Maui.Controls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Handlers
|
||||
{
|
||||
//========================================================================
|
||||
// Ref. https://dev.to/vhugogarcia/remove-entry-and-picker-borders-in-net-maui-2pk2
|
||||
// Ref. https://github.com/dotnet/maui/issues/7906
|
||||
public static class SamFormHandler
|
||||
{
|
||||
//--------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Remove borders around entry and picker controls.
|
||||
/// <para>Also make background transparent.</para>
|
||||
/// </summary>
|
||||
public static void AssignControlHandlers()
|
||||
{
|
||||
//---------------------------------------------------------------
|
||||
// Entry handler.
|
||||
Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping("SamEntryHandler", (handler, view) =>
|
||||
{
|
||||
if ((view as SamEntry)?.NativeNoBorder ?? false)
|
||||
{
|
||||
#if ANDROID
|
||||
handler.PlatformView.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Colors.Transparent.ToAndroid());
|
||||
#elif IOS || MACCATALYST
|
||||
handler.PlatformView.Layer.BorderWidth = 0;
|
||||
handler.PlatformView.BorderStyle = UIKit.UITextBorderStyle.None;
|
||||
#elif WINDOWS
|
||||
handler.PlatformView.BorderThickness = new Microsoft.UI.Xaml.Thickness() { Bottom = 0, Top = 0, Left = 0, Right = 0, };
|
||||
#endif
|
||||
}
|
||||
if ((view as SamEntry)?.NativeNoUnderline ?? false)
|
||||
{
|
||||
#if ANDROID
|
||||
handler.PlatformView.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Colors.Transparent.ToAndroid());
|
||||
#elif IOS || MACCATALYST
|
||||
#elif WINDOWS
|
||||
#endif
|
||||
}
|
||||
if ((view as SamEntry)?.NativeBackgroundClear ?? false)
|
||||
{
|
||||
#if ANDROID
|
||||
handler.PlatformView.Background = null;
|
||||
handler.PlatformView.SetBackgroundColor(Android.Graphics.Color.Transparent);
|
||||
#elif IOS || MACCATALYST
|
||||
handler.PlatformView.BackgroundColor = UIKit.UIColor.Clear;
|
||||
#elif WINDOWS
|
||||
#endif
|
||||
}
|
||||
});
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Editor handler.
|
||||
Microsoft.Maui.Handlers.EditorHandler.Mapper.AppendToMapping("SamEditorHandler", (handler, view) =>
|
||||
{
|
||||
if ((view as SamEditor)?.NativeNoBorder ?? false)
|
||||
{
|
||||
#if ANDROID
|
||||
handler.PlatformView.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Colors.Transparent.ToAndroid());
|
||||
#elif IOS || MACCATALYST
|
||||
handler.PlatformView.Layer.BorderWidth = 0;
|
||||
//handler.PlatformView.BorderStyle = UIKit.UITextViewBorderStyle.None;
|
||||
#elif WINDOWS
|
||||
handler.PlatformView.BorderThickness = new Microsoft.UI.Xaml.Thickness() { Bottom = 0, Top = 0, Left = 0, Right = 0, };
|
||||
#endif
|
||||
}
|
||||
if ((view as SamEntry)?.NativeNoUnderline ?? false)
|
||||
{
|
||||
#if ANDROID
|
||||
handler.PlatformView.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Colors.Transparent.ToAndroid());
|
||||
#elif IOS || MACCATALYST
|
||||
#elif WINDOWS
|
||||
#endif
|
||||
}
|
||||
if ((view as SamEntry)?.NativeBackgroundClear ?? false)
|
||||
{
|
||||
#if ANDROID
|
||||
handler.PlatformView.Background = null;
|
||||
handler.PlatformView.SetBackgroundColor(Android.Graphics.Color.Transparent);
|
||||
#elif IOS || MACCATALYST
|
||||
handler.PlatformView.BackgroundColor = UIKit.UIColor.Clear;
|
||||
#elif WINDOWS
|
||||
#endif
|
||||
}
|
||||
});
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Picker handler.
|
||||
Microsoft.Maui.Handlers.PickerHandler.Mapper.AppendToMapping("Borderless", (handler, view) =>
|
||||
{
|
||||
if ((view as SamEditor)?.NativeNoBorder ?? false)
|
||||
{
|
||||
#if ANDROID
|
||||
handler.PlatformView.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Colors.Transparent.ToAndroid());
|
||||
#elif IOS || MACCATALYST
|
||||
handler.PlatformView.Layer.BorderWidth = 0;
|
||||
handler.PlatformView.BorderStyle = UIKit.UITextBorderStyle.None;
|
||||
#elif WINDOWS
|
||||
handler.PlatformView.BorderThickness = new Microsoft.UI.Xaml.Thickness() { Bottom = 0, Top = 0, Left = 0, Right = 0, };
|
||||
#endif
|
||||
}
|
||||
if ((view as SamEntry)?.NativeNoUnderline ?? false)
|
||||
{
|
||||
#if ANDROID
|
||||
handler.PlatformView.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Colors.Transparent.ToAndroid());
|
||||
#elif IOS || MACCATALYST
|
||||
#elif WINDOWS
|
||||
#endif
|
||||
}
|
||||
if ((view as SamEntry)?.NativeBackgroundClear ?? false)
|
||||
{
|
||||
#if ANDROID
|
||||
handler.PlatformView.Background = null;
|
||||
handler.PlatformView.SetBackgroundColor(Android.Graphics.Color.Transparent);
|
||||
#elif IOS || MACCATALYST
|
||||
handler.PlatformView.BackgroundColor = UIKit.UIColor.Clear;
|
||||
#elif WINDOWS
|
||||
#endif
|
||||
}
|
||||
});
|
||||
|
||||
//---------------------------------------------------------------
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
}
|
||||
//========================================================================
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Layouts
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamAbsoluteLayout : AbsoluteLayout
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamAbsoluteLayout()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Layouts
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamFlexLayout : FlexLayout
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamFlexLayout()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Layouts
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamGrid : Grid
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamGrid()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// G r i d E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnParentSet()
|
||||
{
|
||||
base.OnParentSet();
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnPropertyChanging([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanging(propertyName);
|
||||
}
|
||||
protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnAdd(int index, IView view)
|
||||
{
|
||||
base.OnAdd(index, view);
|
||||
}
|
||||
protected override void OnChildAdded(Element child)
|
||||
{
|
||||
base.OnChildAdded(child);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnRemove(int index, IView view)
|
||||
{
|
||||
base.OnRemove(index, view);
|
||||
}
|
||||
protected override void OnChildRemoved(Element child, int oldLogicalIndex)
|
||||
{
|
||||
base.OnChildRemoved(child, oldLogicalIndex);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Layouts
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamStackLayout : StackLayout
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamStackLayout()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
using Microsoft.Maui.Controls.Compatibility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Layouts
|
||||
{
|
||||
//=======================================================================
|
||||
/// <summary>
|
||||
/// Wrapping columnar layout - to achieve resposive behaviour.
|
||||
/// <para>Layout which performs wrapping on the boundaries.</para>
|
||||
/// <para>Base Code -> https://forums.xamarin.com/discussion/comment/57486/#Comment_57486</para>
|
||||
/// <para> http://bit.ly/xf-custompanel</para>
|
||||
/// </summary>
|
||||
//=======================================================================
|
||||
public class SamWrapLayout : Layout<View>
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Horizontal spacing between elements.</summary>
|
||||
public double SpacingX
|
||||
{
|
||||
get { return (double)GetValue(SpacingXProperty); }
|
||||
set { SetValue(SpacingXProperty, value); }
|
||||
}
|
||||
public static BindableProperty SpacingXProperty =
|
||||
BindableProperty.Create(
|
||||
nameof(SpacingX),
|
||||
typeof(double),
|
||||
typeof(SamWrapLayout),
|
||||
default(double),
|
||||
defaultBindingMode: BindingMode.OneWay,
|
||||
propertyChanged: (bindable, oldvalue, newvalue) => ((SamWrapLayout)bindable).InvalidateMeasure()
|
||||
);
|
||||
/// <summary>Vertical spacing between elements.</summary>
|
||||
public double SpacingY
|
||||
{
|
||||
get { return (double)GetValue(SpacingYProperty); }
|
||||
set { SetValue(SpacingYProperty, value); }
|
||||
}
|
||||
public static BindableProperty SpacingYProperty =
|
||||
BindableProperty.Create(
|
||||
nameof(SpacingY),
|
||||
typeof(double),
|
||||
typeof(SamWrapLayout),
|
||||
default(double),
|
||||
defaultBindingMode: BindingMode.OneWay,
|
||||
propertyChanged: (bindable, oldvalue, newvalue) => ((SamWrapLayout)bindable).InvalidateMeasure()
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Number of uniform columns in each row.</summary>
|
||||
public int UniformColumns
|
||||
{
|
||||
get { return (int)GetValue(UniformColumnsProperty); }
|
||||
set { SetValue(UniformColumnsProperty, value); }
|
||||
}
|
||||
public static BindableProperty UniformColumnsProperty =
|
||||
BindableProperty.Create(
|
||||
nameof(UniformColumns),
|
||||
typeof(int),
|
||||
typeof(SamWrapLayout),
|
||||
default(int),
|
||||
defaultBindingMode: BindingMode.OneWay,
|
||||
propertyChanged: (bindable, oldvalue, newvalue) => ((SamWrapLayout)bindable).InvalidateMeasure()
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Item height equals item width when UniformColums > 0</summary>
|
||||
public bool IsSquare
|
||||
{
|
||||
get { return (bool)GetValue(IsSquareProperty); }
|
||||
set { SetValue(IsSquareProperty, value); }
|
||||
}
|
||||
public static BindableProperty IsSquareProperty =
|
||||
BindableProperty.Create(
|
||||
nameof(IsSquare),
|
||||
typeof(bool),
|
||||
typeof(SamWrapLayout),
|
||||
false,
|
||||
propertyChanged: (bindable, oldvalue, newvalue) => ((SamWrapLayout)bindable).InvalidateMeasure()
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
|
||||
{
|
||||
if (WidthRequest > 0)
|
||||
widthConstraint = Math.Min(widthConstraint, WidthRequest);
|
||||
if (HeightRequest > 0)
|
||||
heightConstraint = Math.Min(heightConstraint, HeightRequest);
|
||||
|
||||
double internalWidth = double.IsPositiveInfinity(widthConstraint) ? double.PositiveInfinity : Math.Max(0, widthConstraint);
|
||||
double internalHeight = double.IsPositiveInfinity(heightConstraint) ? double.PositiveInfinity : Math.Max(0, heightConstraint);
|
||||
|
||||
if (double.IsPositiveInfinity(widthConstraint) && double.IsPositiveInfinity(heightConstraint))
|
||||
{
|
||||
return new SizeRequest(Microsoft.Maui.Graphics.Size.Zero, Microsoft.Maui.Graphics.Size.Zero);
|
||||
}
|
||||
|
||||
return UniformColumns > 0 ? UniformMeasureAndLayout(internalWidth, internalHeight) :
|
||||
VariableMeasureAndLayout(internalWidth, internalHeight);
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override void LayoutChildren(double x, double y, double width, double height)
|
||||
{
|
||||
if (UniformColumns > 0)
|
||||
UniformMeasureAndLayout(width, height, true, x, y);
|
||||
else
|
||||
VariableMeasureAndLayout(width, height, true, x, y);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private SizeRequest UniformMeasureAndLayout
|
||||
(double widthConstraint, double heightConstraint, bool doLayout = false, double x = 0, double y = 0)
|
||||
{
|
||||
double totalWidth = 0;
|
||||
double totalHeight = 0;
|
||||
double rowHeight = 0;
|
||||
double minWidth = 0;
|
||||
double minHeight = 0;
|
||||
double xPos = x;
|
||||
double yPos = y;
|
||||
|
||||
totalWidth = widthConstraint;
|
||||
var exceptedWidth = widthConstraint - (UniformColumns - 1) * SpacingX; //excepted spacing width
|
||||
|
||||
var columnsSize = exceptedWidth / UniformColumns;
|
||||
if (columnsSize < 1)
|
||||
{
|
||||
columnsSize = 1;
|
||||
}
|
||||
|
||||
foreach (var child in Children.Where(c => c.IsVisible))
|
||||
{
|
||||
|
||||
var size = child.Measure(widthConstraint, heightConstraint);
|
||||
var itemWidth = (double)columnsSize;
|
||||
var itemHeight = size.Request.Height;
|
||||
|
||||
if (IsSquare)
|
||||
{
|
||||
itemHeight = columnsSize;
|
||||
}
|
||||
|
||||
rowHeight = Math.Max(rowHeight, itemHeight + SpacingY);
|
||||
|
||||
minHeight = Math.Max(minHeight, itemHeight);
|
||||
minWidth = Math.Max(minWidth, itemWidth);
|
||||
|
||||
if (doLayout)
|
||||
{
|
||||
var region = new Rect(xPos, yPos, itemWidth, itemHeight);
|
||||
LayoutChildIntoBoundingRegion(child, region);
|
||||
}
|
||||
|
||||
xPos += itemWidth + SpacingX;
|
||||
|
||||
if (xPos + columnsSize - x > widthConstraint)
|
||||
{
|
||||
xPos = x;
|
||||
yPos += rowHeight;
|
||||
totalHeight += rowHeight;
|
||||
rowHeight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
totalHeight = Math.Max(totalHeight + rowHeight - SpacingY, 0);
|
||||
|
||||
return new SizeRequest(new Microsoft.Maui.Graphics.Size(totalWidth, totalHeight), new Microsoft.Maui.Graphics.Size(minWidth, minHeight));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private SizeRequest VariableMeasureAndLayout
|
||||
(double widthConstraint, double heightConstraint, bool doLayout = false, double x = 0, double y = 0)
|
||||
{
|
||||
double totalWidth = 0;
|
||||
double totalHeight = 0;
|
||||
double rowHeight = 0;
|
||||
double rowWidth = 0;
|
||||
double minWidth = 0;
|
||||
double minHeight = 0;
|
||||
double xPos = x;
|
||||
double yPos = y;
|
||||
|
||||
var visibleChildren = Children.Where(c => c.IsVisible).Select(c => new
|
||||
{
|
||||
child = c,
|
||||
size = c.Measure(widthConstraint, heightConstraint)
|
||||
});
|
||||
|
||||
var nextChildren = visibleChildren.Skip(1).ToList();
|
||||
nextChildren.Add(null); //make element count same
|
||||
|
||||
var zipChildren = visibleChildren.Zip(nextChildren, (c, n) => new { current = c, next = n });
|
||||
|
||||
foreach (var childBlock in zipChildren)
|
||||
{
|
||||
var child = childBlock.current.child;
|
||||
var size = childBlock.current.size;
|
||||
var itemWidth = size.Request.Width;
|
||||
var itemHeight = size.Request.Height;
|
||||
|
||||
rowHeight = Math.Max(rowHeight, itemHeight + SpacingY);
|
||||
rowWidth += itemWidth + SpacingX;
|
||||
|
||||
minHeight = Math.Max(minHeight, itemHeight);
|
||||
minWidth = Math.Max(minWidth, itemWidth);
|
||||
|
||||
if (doLayout)
|
||||
{
|
||||
var region = new Rect(xPos, yPos, itemWidth, itemHeight);
|
||||
LayoutChildIntoBoundingRegion(child, region);
|
||||
}
|
||||
|
||||
if (childBlock.next == null)
|
||||
{
|
||||
totalHeight += rowHeight;
|
||||
totalWidth = Math.Max(totalWidth, rowWidth);
|
||||
break;
|
||||
}
|
||||
|
||||
xPos += itemWidth + SpacingX;
|
||||
var nextWitdh = childBlock.next.size.Request.Width;
|
||||
|
||||
if (xPos + nextWitdh - x > widthConstraint)
|
||||
{
|
||||
xPos = x;
|
||||
yPos += rowHeight;
|
||||
totalHeight += rowHeight;
|
||||
totalWidth = Math.Max(totalWidth, rowWidth);
|
||||
rowHeight = 0;
|
||||
rowWidth = 0;
|
||||
}
|
||||
}
|
||||
|
||||
totalWidth = Math.Max(totalWidth - SpacingX, 0);
|
||||
totalHeight = Math.Max(totalHeight - SpacingY, 0);
|
||||
|
||||
return new SizeRequest(new Microsoft.Maui.Graphics.Size(totalWidth, totalHeight), new Microsoft.Maui.Graphics.Size(minWidth, minHeight));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
using Microsoft.Maui.Controls;
|
||||
using Sarand.Net.Mobile.Maui.Views;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Pages
|
||||
{
|
||||
//=======================================================================
|
||||
public abstract class SamContentPage : ContentPage
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamContentPage()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public abstract String MessageTitleDefault { get; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n f i g u r e C o m p o n e n t s
|
||||
//-------------------------------------------------------------------
|
||||
protected virtual void ConfigureComponents()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void ConfigureChildComponents()
|
||||
{
|
||||
// Configure child components.
|
||||
if (Content != null)
|
||||
{
|
||||
ConfigureChildComponent(Content);
|
||||
foreach (var descendent in Content.GetVisualTreeDescendants())
|
||||
{
|
||||
View? childView = descendent as View;
|
||||
if (childView != null)
|
||||
ConfigureChildComponent(childView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureChildComponent(View view)
|
||||
{
|
||||
if (view is ISamView)
|
||||
{
|
||||
ISamView? samView = view as ISamView;
|
||||
if (samView != null)
|
||||
samView.ConfigureComponents();
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l A c t i v i t y
|
||||
//-------------------------------------------------------------------
|
||||
protected virtual void SetControlActivity()
|
||||
{
|
||||
SetControlsReadOnly();
|
||||
|
||||
// Child component control activity.
|
||||
if (Content != null)
|
||||
{
|
||||
SetChildControlActivity(Content);
|
||||
foreach (var descendent in Content.GetVisualTreeDescendants())
|
||||
{
|
||||
View? childView = descendent as View;
|
||||
if (childView != null)
|
||||
SetChildControlActivity(childView);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void SetChildControlActivity(View view)
|
||||
{
|
||||
if (view is ISamView)
|
||||
{
|
||||
ISamView? samView = view as ISamView;
|
||||
if (samView != null)
|
||||
samView.SetControlActivity();
|
||||
}
|
||||
}
|
||||
protected virtual void SetControlsReadOnly()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// P o p u p M e s s a g e s
|
||||
//-------------------------------------------------------------------
|
||||
public enum AlertMode
|
||||
{
|
||||
OK,
|
||||
Close,
|
||||
}
|
||||
public Task DisplayAlert(String message, AlertMode alertMode = AlertMode.OK)
|
||||
{
|
||||
String title = StringUtil.OnEmpty(Title, MessageTitleDefault);
|
||||
String cancel = "OK";
|
||||
if (alertMode == AlertMode.Close)
|
||||
cancel = "Close";
|
||||
return DisplayAlert(title, message, cancel);
|
||||
}
|
||||
public enum ConfirmMode
|
||||
{
|
||||
YesNo,
|
||||
OkCancel
|
||||
}
|
||||
public async Task<bool> DisplayConfirm(String message, ConfirmMode confirmMode = ConfirmMode.OkCancel)
|
||||
{
|
||||
String title = StringUtil.OnEmpty(Title, MessageTitleDefault);
|
||||
String accept = "Yes";
|
||||
String cancel = "No";
|
||||
if (confirmMode == ConfirmMode.OkCancel)
|
||||
{
|
||||
accept = "OK";
|
||||
cancel = "Cancel";
|
||||
}
|
||||
return await DisplayAlert(title, message, accept, cancel);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// P a g e E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnParentSet()
|
||||
{
|
||||
base.OnParentSet();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
ConfigureComponents();
|
||||
ConfigureChildComponents();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Layout changes.
|
||||
private bool inOnSizeAllocated = false;
|
||||
protected override void OnSizeAllocated(double width, double height)
|
||||
{
|
||||
bool alreadyInOnSizeAllocated = inOnSizeAllocated;
|
||||
inOnSizeAllocated = true;
|
||||
base.OnSizeAllocated(width, height);
|
||||
// Only configure components if this is the first entry to this event
|
||||
// // to avoid iterative layout changes caused by components being configured.
|
||||
if (!alreadyInOnSizeAllocated)
|
||||
{
|
||||
if (Width > 0 && Height > 0)
|
||||
{
|
||||
ConfigureComponents();
|
||||
ConfigureChildComponents();
|
||||
}
|
||||
inOnSizeAllocated = false;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
base.OnDisappearing();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using Sarand.Net.Mobile.Maui.Views;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Panels
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamPanel : SamContentView
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamPanel()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n f i g u r e C o m p o n e n t s
|
||||
//-------------------------------------------------------------------
|
||||
public override void ConfigureComponents()
|
||||
{
|
||||
base.ConfigureComponents();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l A c t i v i t y
|
||||
//-------------------------------------------------------------------
|
||||
public override void SetControlActivity()
|
||||
{
|
||||
}
|
||||
public override void SetControlsReadOnly()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// P a n e l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnParentSet()
|
||||
{
|
||||
base.OnParentSet();
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnPropertyChanging([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanging(propertyName);
|
||||
}
|
||||
protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnChildAdded(Element child)
|
||||
{
|
||||
base.OnChildAdded(child);
|
||||
}
|
||||
protected override void OnChildRemoved(Element child, int oldLogicalIndex)
|
||||
{
|
||||
base.OnChildRemoved(child, oldLogicalIndex);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnSizeAllocated(double width, double height)
|
||||
{
|
||||
base.OnSizeAllocated(width, height);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
using Sarand.Net.Mobile.Maui.Layouts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Panels
|
||||
{
|
||||
//=======================================================================
|
||||
public class SacsFilterPropertyType
|
||||
{
|
||||
public enum FilterMode { Text, DropDownList }
|
||||
public SacsFilterPropertyType(int propertyType, String caption)
|
||||
{
|
||||
PropertyType = propertyType;
|
||||
Caption = caption;
|
||||
}
|
||||
public int PropertyType { get; }
|
||||
public String Caption { get; }
|
||||
public FilterMode Mode { get; set; } = FilterMode.Text;
|
||||
}
|
||||
public class SamPanel_ItemFilter : SamWrapLayout
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public class Config
|
||||
{
|
||||
public List<SacsFilterPropertyType> FilterPropertyTypes { get; } = new List<SacsFilterPropertyType>();
|
||||
public ushort FiltersToDisplay { get; set; } = 2;
|
||||
public int PropertyTypeWidth { get; set; } = 100;
|
||||
public int PropertyValueWidth { get; set; } = 120;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private Config config;
|
||||
private SamPanel_ItemFilterProperty[] itemFilterProperties = new SamPanel_ItemFilterProperty[0];
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamPanel_ItemFilter(Config config)
|
||||
{
|
||||
this.config = config;
|
||||
InitialiseComponents();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public int FilterCount { get { return Math.Min(config.FiltersToDisplay, config.FilterPropertyTypes.Count); } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Configure.
|
||||
public void SetConfig(Config config)
|
||||
{
|
||||
this.config = config;
|
||||
ConfigurePanel();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// P u b l i c I n t e r f a c e
|
||||
//-------------------------------------------------------------------
|
||||
public String GetFilterPropertyValue(int propertyType)
|
||||
{
|
||||
foreach (SamPanel_ItemFilterProperty propertyFilter in itemFilterProperties)
|
||||
{
|
||||
if (propertyFilter.SelectedPropertyType == propertyType)
|
||||
return propertyFilter.PropertyValue;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// I n i t i a l i s e
|
||||
//-------------------------------------------------------------------
|
||||
private void InitialiseComponents()
|
||||
{
|
||||
// Styling.
|
||||
SpacingX = 8.0;
|
||||
SpacingY = 4.0;
|
||||
BackgroundColor = Colors.Transparent;
|
||||
|
||||
ConfigurePanel();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n f i g u r e P a n e l
|
||||
//-------------------------------------------------------------------
|
||||
private void ConfigurePanel()
|
||||
{
|
||||
// Clear filter panels.
|
||||
Children.Clear();
|
||||
|
||||
// Reconfigure fiter properties.
|
||||
if (itemFilterProperties.Length != FilterCount)
|
||||
{
|
||||
// Create new set of filters and copy previous filters across up to required number.
|
||||
SamPanel_ItemFilterProperty[] itemFilterPropertiesNew = new SamPanel_ItemFilterProperty[FilterCount];
|
||||
for (int filterIdx = 0; filterIdx < Math.Min(itemFilterProperties.Length, FilterCount); filterIdx++)
|
||||
itemFilterPropertiesNew[filterIdx] = itemFilterProperties[filterIdx];
|
||||
for (int filterIdx = itemFilterProperties.Length; filterIdx < FilterCount; filterIdx++)
|
||||
{
|
||||
itemFilterPropertiesNew[filterIdx] = new SamPanel_ItemFilterProperty(new SamPanel_ItemFilterProperty.Config());
|
||||
itemFilterPropertiesNew[filterIdx].PropertyFilterChanged += SamPanel_ItemFilter_PropertyFilterChanged;
|
||||
}
|
||||
itemFilterProperties = itemFilterPropertiesNew;
|
||||
}
|
||||
|
||||
// Retrieve currently selected property types.
|
||||
List<int> selectedPropertyTypes = new List<int>();
|
||||
for (int filterIdx = 0; filterIdx < FilterCount; filterIdx++)
|
||||
{
|
||||
int selectedPropertyType = itemFilterProperties[filterIdx].SelectedPropertyType;
|
||||
if (selectedPropertyType >= 0 && !selectedPropertyTypes.Contains(selectedPropertyType))
|
||||
selectedPropertyTypes.Add(selectedPropertyType);
|
||||
}
|
||||
|
||||
// Configure filter panels.
|
||||
for (int filterIdx = 0; filterIdx < FilterCount; filterIdx++)
|
||||
{
|
||||
SamPanel_ItemFilterProperty propertyPanel = itemFilterProperties[filterIdx];
|
||||
|
||||
// Determine the property types to display - remove property types selected in other panels.
|
||||
List<SacsFilterPropertyType> filterPropertyTypes = new List<SacsFilterPropertyType>(config.FilterPropertyTypes);
|
||||
filterPropertyTypes.RemoveAll(item => item.PropertyType != propertyPanel.SelectedPropertyType && selectedPropertyTypes.Contains(item.PropertyType));
|
||||
if (filterPropertyTypes.Count == 0) continue;
|
||||
|
||||
SamPanel_ItemFilterProperty.Config propertyPanelConfig = new SamPanel_ItemFilterProperty.Config();
|
||||
propertyPanelConfig.FilterPropertyTypes.AddRange(filterPropertyTypes);
|
||||
propertyPanelConfig.PropertyTypeWidth = config.PropertyTypeWidth;
|
||||
propertyPanelConfig.PropertyValueWidth = config.PropertyValueWidth;
|
||||
propertyPanel.SetConfig(propertyPanelConfig);
|
||||
|
||||
// Include the selecetd type in the list of not already present.
|
||||
int selectedPropertyType = propertyPanel.SelectedPropertyType;
|
||||
if (selectedPropertyType >= 0 && !selectedPropertyTypes.Contains(selectedPropertyType))
|
||||
selectedPropertyTypes.Add(selectedPropertyType);
|
||||
|
||||
// Add panel to the layout.
|
||||
Children.Add(propertyPanel);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// F i l t e r E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
public class FilterChangedEventArgs : EventArgs
|
||||
{
|
||||
public int PropertyType { get; set; } = -1;
|
||||
}
|
||||
public event EventHandler<FilterChangedEventArgs>? FilterChanged;
|
||||
private void FireFilterChangedEvent(int propertyType)
|
||||
{
|
||||
FilterChangedEventArgs filterChangedEventArgs = new FilterChangedEventArgs()
|
||||
{
|
||||
PropertyType = propertyType,
|
||||
};
|
||||
if (FilterChanged != null) FilterChanged.Invoke(this, filterChangedEventArgs);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
private void SamPanel_ItemFilter_PropertyFilterChanged(object? sender, SamPanel_ItemFilterProperty.PropertyFilterChangedEventArgs e)
|
||||
{
|
||||
FireFilterChangedEvent(e.PropertyType);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
using Sarand.Net.Mobile.Maui.Controls;
|
||||
using Sarand.Net.Mobile.Maui.Layouts;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Panels
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamPanel_ItemFilterProperty : SamPanel
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public class Config
|
||||
{
|
||||
public List<SacsFilterPropertyType> FilterPropertyTypes { get; } = new List<SacsFilterPropertyType>();
|
||||
public GridLength Height { get; set; } = GridLength.Auto;
|
||||
public int PropertyTypeWidth { get; set; } = 0;
|
||||
public int PropertyValueWidth { get; set; } = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private Config config;
|
||||
private SamGrid? grid;
|
||||
private SamPicker pickerPropertyType = new SamPicker();
|
||||
private SamEntry entryPropertyValue = new SamEntry() { Text = "", HorizontalOptions = LayoutOptions.FillAndExpand };
|
||||
private SamPicker pickerPropertyValue = new SamPicker() { HorizontalOptions = LayoutOptions.FillAndExpand, IsVisible = false };
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamPanel_ItemFilterProperty(Config config)
|
||||
{
|
||||
this.config = config;
|
||||
InitialiseComponents();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public bool Initialising { get; set; } = true;
|
||||
private SacsFilterPropertyType? SelectedProperty { get { return config.FilterPropertyTypes.Find(item => item.PropertyType == StringUtil.ToInt(pickerPropertyType.SelectedItemCode)); } }
|
||||
public int SelectedPropertyType { get { return SelectedProperty?.PropertyType ?? -1; } }
|
||||
public String PropertyValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (SelectedProperty?.Mode == SacsFilterPropertyType.FilterMode.DropDownList)
|
||||
return pickerPropertyValue.SelectedItemCode;
|
||||
return entryPropertyValue.Text;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Configure.
|
||||
public void SetConfig(Config config)
|
||||
{
|
||||
this.config = config;
|
||||
ConfigurePanel();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// I n i t i a l i s e
|
||||
//-------------------------------------------------------------------
|
||||
private void InitialiseComponents()
|
||||
{
|
||||
// Grid - property type picker followed by property value control.
|
||||
grid = new SamGrid()
|
||||
{
|
||||
BackgroundColor = Colors.Transparent,
|
||||
RowSpacing = 0,
|
||||
ColumnSpacing = 4,
|
||||
RowDefinitions = new RowDefinitionCollection()
|
||||
{
|
||||
// Single row.
|
||||
new RowDefinition(){ Height = config.Height }
|
||||
},
|
||||
ColumnDefinitions = new ColumnDefinitionCollection()
|
||||
{
|
||||
// Two columns - property type & value.
|
||||
new ColumnDefinition(){ Width = config.PropertyTypeWidth > 0 ? config.PropertyTypeWidth : GridLength.Auto },
|
||||
new ColumnDefinition(){ Width = config.PropertyValueWidth > 0 ? config.PropertyValueWidth : GridLength.Auto }
|
||||
}
|
||||
};
|
||||
Content = grid;
|
||||
|
||||
// Property type.
|
||||
if (config.PropertyTypeWidth > 0)
|
||||
pickerPropertyType.WidthRequest = config.PropertyTypeWidth;
|
||||
grid.Add(pickerPropertyType, 0, 0);
|
||||
pickerPropertyType.SelectedIndexChanged += PickerPropertyType_SelectedIndexChanged;
|
||||
|
||||
// Property value.
|
||||
if (config.PropertyValueWidth > 0)
|
||||
entryPropertyValue.WidthRequest = config.PropertyValueWidth;
|
||||
entryPropertyValue.TextChanged += EntryPropertyValue_TextChanged;
|
||||
grid.Add(entryPropertyValue, 1, 0);
|
||||
if (config.PropertyValueWidth > 0)
|
||||
pickerPropertyValue.WidthRequest = config.PropertyValueWidth;
|
||||
pickerPropertyValue.SelectedIndexChanged += PickerPropertyValue_SelectedIndexChanged;
|
||||
grid.Add(pickerPropertyValue, 1, 0);
|
||||
|
||||
ConfigurePanel();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n f i g u r e P a n e l
|
||||
//-------------------------------------------------------------------
|
||||
private void ConfigurePanel()
|
||||
{
|
||||
Initialising = true;
|
||||
|
||||
// Configure layout.
|
||||
if (grid != null)
|
||||
{
|
||||
grid.ColumnDefinitions.Clear();
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = config.PropertyTypeWidth });
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = config.PropertyValueWidth });
|
||||
}
|
||||
|
||||
// Make a note of the currently selected property type.
|
||||
int selectedPropertyType = SelectedPropertyType;
|
||||
pickerPropertyType.ClearItems();
|
||||
|
||||
// Populate list of property types.
|
||||
foreach (SacsFilterPropertyType propertyType in config.FilterPropertyTypes)
|
||||
{
|
||||
pickerPropertyType.AddItem(propertyType.PropertyType.ToString(), propertyType.Caption);
|
||||
}
|
||||
pickerPropertyType.SelectedItemCode = selectedPropertyType.ToString();
|
||||
if (pickerPropertyType.SelectedIndex < 0 && pickerPropertyType.Items.Count > 0)
|
||||
pickerPropertyType.SelectedIndex = 0;
|
||||
|
||||
Initialising = false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// P r o p e r t y F i l t e r E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
public class PropertyFilterChangedEventArgs : EventArgs
|
||||
{
|
||||
public int PropertyType { get; set; } = -1;
|
||||
}
|
||||
public event EventHandler<PropertyFilterChangedEventArgs>? PropertyFilterChanged;
|
||||
private void FireFilterChangedEvent(int propertyType)
|
||||
{
|
||||
if (Initialising) return;
|
||||
PropertyFilterChangedEventArgs filterChangedEventArgs = new PropertyFilterChangedEventArgs()
|
||||
{
|
||||
PropertyType = propertyType,
|
||||
};
|
||||
if (PropertyFilterChanged != null) PropertyFilterChanged.Invoke(this, filterChangedEventArgs);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private void PickerPropertyType_SelectedIndexChanged(object? sender, EventArgs e)
|
||||
{
|
||||
FireFilterChangedEvent(SelectedPropertyType);
|
||||
}
|
||||
private void EntryPropertyValue_TextChanged(object? sender, TextChangedEventArgs e)
|
||||
{
|
||||
FireFilterChangedEvent(SelectedPropertyType);
|
||||
}
|
||||
private void PickerPropertyValue_SelectedIndexChanged(object? sender, EventArgs e)
|
||||
{
|
||||
FireFilterChangedEvent(SelectedPropertyType);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
using Sarand.Net.Mobile.Maui.Controls;
|
||||
using Sarand.Net.Mobile.Maui.Layouts;
|
||||
using Sarand.Net.Mobile.Maui.Utils;
|
||||
using Sarand.Net.Mobile.Maui.Views;
|
||||
using Sarand.Net.Standard.Base.Dbas;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Panels
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamPanel_ItemListHeader : SamPanel
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public class Config
|
||||
{
|
||||
public Thickness? Margin { get; set; } = new Thickness(0, 0, 0, 8);
|
||||
public String Caption { get; set; } = "";
|
||||
public double HeaderBorderWidth { get; set; } = 4.0;
|
||||
public float HeaderBorderRadius { get; set; } = 8.0f;
|
||||
public Color HeaderBorderColor { get; set; } = Color.FromArgb("#808080");
|
||||
public Color HeaderBackgroundColor { get; set; } = Color.FromArgb("#F0F0F0");
|
||||
// Labels.
|
||||
// Styling.
|
||||
public double CaptionLabelFontSizeRatio { get; set; } = 1.0;
|
||||
public double PagingLabelFontSizeRatio { get; set; } = 1.0;
|
||||
public Thickness? LabelMargin { get; set; } = null;
|
||||
// Paging controls.
|
||||
public static int PagingButtonWidthMin { get; } = 40;
|
||||
public static int PagingButtonWidthMax { get; } = 64;
|
||||
public static int PagingButtonWidthDefault { get; } = PagingButtonWidthMin;
|
||||
public int PagingButtonWidth { get; set; } = PagingButtonWidthDefault;
|
||||
public static int PagingButtonHeightMin { get; } = 40;
|
||||
public static int PagingButtonHeightMax { get; } = 64;
|
||||
public static int PagingButtonHeightDefault { get; } = PagingButtonHeightMin;
|
||||
public int PagingButtonHeight { get; set; } = PagingButtonHeightDefault;
|
||||
// Filters.
|
||||
public List<SacsFilterPropertyType> FilterPropertyTypes { get; } = new List<SacsFilterPropertyType>();
|
||||
public ushort FiltersToDisplay { get; set; } = 2;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private Config config;
|
||||
// Layout.
|
||||
private SamFrame frame = new SamFrame();
|
||||
private SamStackLayout mainLayout = new SamStackLayout() { Orientation = StackOrientation.Vertical };
|
||||
// Header.
|
||||
private SamWrapLayout headerLayout = new SamWrapLayout() { SpacingX = 8.0 };
|
||||
private SamContentView captionLabelView = new SamContentView();
|
||||
private SamLabel labelCaption = new SamLabel() { Text = "" };
|
||||
private double initialLabelFontSize = 0;
|
||||
// Paging.
|
||||
private class PagingData : DbQuery.Paging
|
||||
{
|
||||
public int TotalItems { get; set; }
|
||||
public int TotalPages { get { return PageLength > 0 ? (int)Math.Ceiling((double)TotalItems / PageLength) : 0; } }
|
||||
public override bool Paged { get { return base.Paged && TotalItems > 0; } }
|
||||
}
|
||||
private readonly PagingData paging = new PagingData();
|
||||
private SamStackLayout pagingStack = new SamStackLayout() { Orientation = StackOrientation.Horizontal };
|
||||
private SamLabel labelPaging = new SamLabel() { Text = "[Paging]" };
|
||||
private SamImageButton buttonPagingFirst = new SamImageButton() { WidthRequest = 32, HeightRequest = 32, Aspect = Aspect.AspectFit, Padding = new Thickness(2, 4), BackgroundColor = Colors.Transparent };
|
||||
private SamImageButton buttonPagingPrev = new SamImageButton() { WidthRequest = 32, HeightRequest = 32, Aspect = Aspect.AspectFit, Padding = new Thickness(2, 4), BackgroundColor = Colors.Transparent };
|
||||
private SamImageButton buttonPagingNext = new SamImageButton() { WidthRequest = 32, HeightRequest = 32, Aspect = Aspect.AspectFit, Padding = new Thickness(2, 4), BackgroundColor = Colors.Transparent };
|
||||
private SamImageButton buttonPagingLast = new SamImageButton() { WidthRequest = 32, HeightRequest = 32, Aspect = Aspect.AspectFit, Padding = new Thickness(2, 4), BackgroundColor = Colors.Transparent };
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamPanel_ItemListHeader(Config config)
|
||||
{
|
||||
this.config = config;
|
||||
initialLabelFontSize = labelCaption.FontSize;
|
||||
InitialiseComponents();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
// Filter.
|
||||
public SamPanel_ItemFilter? PanelFilter { get; private set; }
|
||||
// Paging.
|
||||
public uint PageNo { get { return paging.PageNo; } }
|
||||
public ushort PageLength { get { return paging.PageLength; } }
|
||||
public int TotalItems { get { return paging.TotalItems; } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// I n i t i a l i s e
|
||||
//-------------------------------------------------------------------
|
||||
private void InitialiseComponents()
|
||||
{
|
||||
// Frame - to allow rounded corners.
|
||||
Content = frame;
|
||||
frame.Content = mainLayout;
|
||||
|
||||
// Header.
|
||||
mainLayout.Spacing = 0;
|
||||
mainLayout.HorizontalOptions = LayoutOptions.StartAndExpand;
|
||||
mainLayout.BackgroundColor = Colors.Transparent;
|
||||
//headerLayout.BackgroundColor = Color.LightYellow;
|
||||
mainLayout.Children.Add(headerLayout);
|
||||
|
||||
// Header - Caption.
|
||||
captionLabelView.VerticalOptions = LayoutOptions.Center;
|
||||
labelCaption.FontAttributes = FontAttributes.Bold;
|
||||
labelCaption.HorizontalOptions = LayoutOptions.StartAndExpand;
|
||||
labelCaption.VerticalOptions = LayoutOptions.CenterAndExpand;
|
||||
labelCaption.LineBreakMode = LineBreakMode.NoWrap;
|
||||
labelCaption.PropertyChanging += LabelCaption_PropertyChanging;
|
||||
// Label is embedded in view to ensure correct sizing.
|
||||
captionLabelView.Content = labelCaption;
|
||||
headerLayout.Children.Add(captionLabelView);
|
||||
|
||||
// Header - Paging.
|
||||
pagingStack.HorizontalOptions = LayoutOptions.EndAndExpand;
|
||||
pagingStack.VerticalOptions = LayoutOptions.CenterAndExpand;
|
||||
headerLayout.Children.Add(pagingStack);
|
||||
labelPaging.VerticalOptions = LayoutOptions.CenterAndExpand;
|
||||
pagingStack.Children.Add(labelPaging);
|
||||
pagingStack.Children.Add(buttonPagingFirst);
|
||||
pagingStack.Children.Add(buttonPagingPrev);
|
||||
pagingStack.Children.Add(buttonPagingNext);
|
||||
pagingStack.Children.Add(buttonPagingLast);
|
||||
|
||||
// Paging actions.
|
||||
buttonPagingFirst.Clicked += ButtonPagingFirst_Clicked;
|
||||
buttonPagingPrev.Clicked += ButtonPagingPrev_Clicked;
|
||||
buttonPagingNext.Clicked += ButtonPagingNext_Clicked;
|
||||
buttonPagingLast.Clicked += ButtonPagingLast_Clicked;
|
||||
|
||||
// Complete panel configuration.
|
||||
ConfigurePanel();
|
||||
}
|
||||
|
||||
private void LabelCaption_PropertyChanging(object? sender, PropertyChangingEventArgs e)
|
||||
{
|
||||
if (e.PropertyName.EqualsCI("Height"))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n f i g u r e P a n e l
|
||||
//-------------------------------------------------------------------
|
||||
private void ConfigurePanel()
|
||||
{
|
||||
if (config.Margin != null)
|
||||
frame.Margin = (Thickness)config.Margin;
|
||||
|
||||
// Header.
|
||||
labelCaption.Text = StringUtil.EmptyOnNull(config.Caption);
|
||||
frame.Padding = new Thickness(config.HeaderBorderWidth);
|
||||
frame.CornerRadius = config.HeaderBorderRadius;
|
||||
frame.BorderColor = config.HeaderBorderColor;
|
||||
frame.BackgroundColor = config.HeaderBackgroundColor;
|
||||
|
||||
// Labels.
|
||||
labelCaption.FontSize = initialLabelFontSize * config.CaptionLabelFontSizeRatio;
|
||||
labelPaging.FontSize = initialLabelFontSize * config.PagingLabelFontSizeRatio;
|
||||
if (config.LabelMargin != null)
|
||||
{
|
||||
labelCaption.Margin = (Thickness)config.LabelMargin;
|
||||
labelPaging.Margin = (Thickness)config.LabelMargin;
|
||||
}
|
||||
|
||||
// Paging controls.
|
||||
buttonPagingFirst.Source = SamImageUtil.GetImageFromByteArray(SacsResourceHelper.GetResourceImage(SacsResourceHelper.ImageResource.Arrow_Left_Double_Black_24_png));
|
||||
buttonPagingFirst.WidthRequest = Math.Max(Config.PagingButtonWidthMin, Math.Min(Config.PagingButtonWidthMax, config.PagingButtonWidth));
|
||||
buttonPagingFirst.HeightRequest = Math.Max(Config.PagingButtonHeightMin, Math.Min(Config.PagingButtonHeightMax, config.PagingButtonHeight));
|
||||
buttonPagingPrev.Source = SamImageUtil.GetImageFromByteArray(SacsResourceHelper.GetResourceImage(SacsResourceHelper.ImageResource.Arrow_Left_Black_24_png));
|
||||
buttonPagingPrev.WidthRequest = Math.Max(Config.PagingButtonWidthMin, Math.Min(Config.PagingButtonWidthMax, config.PagingButtonWidth));
|
||||
buttonPagingPrev.HeightRequest = Math.Max(Config.PagingButtonHeightMin, Math.Min(Config.PagingButtonHeightMax, config.PagingButtonHeight));
|
||||
buttonPagingNext.Source = SamImageUtil.GetImageFromByteArray(SacsResourceHelper.GetResourceImage(SacsResourceHelper.ImageResource.Arrow_Right_Black_24_png));
|
||||
buttonPagingNext.WidthRequest = Math.Max(Config.PagingButtonWidthMin, Math.Min(Config.PagingButtonWidthMax, config.PagingButtonWidth));
|
||||
buttonPagingNext.HeightRequest = Math.Max(Config.PagingButtonHeightMin, Math.Min(Config.PagingButtonHeightMax, config.PagingButtonHeight));
|
||||
buttonPagingLast.Source = SamImageUtil.GetImageFromByteArray(SacsResourceHelper.GetResourceImage(SacsResourceHelper.ImageResource.Arrow_Right_Double_Black_24_png));
|
||||
buttonPagingLast.WidthRequest = Math.Max(Config.PagingButtonWidthMin, Math.Min(Config.PagingButtonWidthMax, config.PagingButtonWidth));
|
||||
buttonPagingLast.HeightRequest = Math.Max(Config.PagingButtonHeightMin, Math.Min(Config.PagingButtonHeightMax, config.PagingButtonHeight));
|
||||
RefreshPaging();
|
||||
|
||||
// Property type filters.
|
||||
SamPanel_ItemFilter.Config propertyFilterConfig = new SamPanel_ItemFilter.Config();
|
||||
propertyFilterConfig.FilterPropertyTypes.AddRange(config.FilterPropertyTypes);
|
||||
propertyFilterConfig.FiltersToDisplay = config.FiltersToDisplay;
|
||||
if (PanelFilter == null)
|
||||
{
|
||||
PanelFilter = new SamPanel_ItemFilter(propertyFilterConfig);
|
||||
mainLayout.Children.Add(PanelFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
PanelFilter.SetConfig(propertyFilterConfig);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// P a g i n g
|
||||
//-------------------------------------------------------------------
|
||||
public void SetPaging(uint pageNo, ushort pageLength, int totalItems)
|
||||
{
|
||||
paging.PageNo = pageNo;
|
||||
paging.PageLength = pageLength;
|
||||
paging.TotalItems = totalItems;
|
||||
RefreshPaging();
|
||||
}
|
||||
private void RefreshPaging()
|
||||
{
|
||||
String pagingText = "";
|
||||
Boolean paged = (paging.Paged && paging.TotalPages > 1);
|
||||
if (paging.TotalItems > 0)
|
||||
{
|
||||
if (paged)
|
||||
pagingText = "Page " + paging.PageNo + " of " + paging.TotalPages;
|
||||
else
|
||||
pagingText = paging.TotalItems + " items";
|
||||
}
|
||||
labelPaging.Text = pagingText;
|
||||
// Control visibility.
|
||||
labelPaging.IsVisible = !StringUtil.IsEmpty(labelPaging.Text);
|
||||
buttonPagingFirst.IsVisible = paged;
|
||||
buttonPagingPrev.IsVisible = paged;
|
||||
buttonPagingNext.IsVisible = paged;
|
||||
buttonPagingLast.IsVisible = paged;
|
||||
// Button activity.
|
||||
buttonPagingFirst.IsEnabled = paging.PageNo > 1;
|
||||
buttonPagingPrev.IsEnabled = paging.PageNo > 1;
|
||||
buttonPagingNext.IsEnabled = paging.PageNo < paging.TotalPages;
|
||||
buttonPagingLast.IsEnabled = paging.PageNo < paging.TotalPages;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Paging events.
|
||||
public enum PagingActionType
|
||||
{
|
||||
Unknown,
|
||||
First,
|
||||
Next,
|
||||
Prev,
|
||||
Last
|
||||
}
|
||||
public class PagingActionEventArgs : EventArgs
|
||||
{
|
||||
public PagingActionType PagingActionType { get; set; } = PagingActionType.Unknown;
|
||||
}
|
||||
public event EventHandler<PagingActionEventArgs>? PagingAction;
|
||||
private void FirePagingActionEvent(PagingActionType pagingActionType)
|
||||
{
|
||||
PagingActionEventArgs filterChangedEventArgs = new PagingActionEventArgs()
|
||||
{
|
||||
PagingActionType = pagingActionType,
|
||||
};
|
||||
if (PagingAction != null) PagingAction.Invoke(this, filterChangedEventArgs);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Paging actions.
|
||||
private void ButtonPagingFirst_Clicked(object? sender, EventArgs e)
|
||||
{
|
||||
FirePagingActionEvent(PagingActionType.First);
|
||||
}
|
||||
private void ButtonPagingPrev_Clicked(object? sender, EventArgs e)
|
||||
{
|
||||
FirePagingActionEvent(PagingActionType.Prev);
|
||||
}
|
||||
private void ButtonPagingNext_Clicked(object? sender, EventArgs e)
|
||||
{
|
||||
FirePagingActionEvent(PagingActionType.Next);
|
||||
}
|
||||
private void ButtonPagingLast_Clicked(object? sender, EventArgs e)
|
||||
{
|
||||
FirePagingActionEvent(PagingActionType.Last);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// P a n e l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
using Sarand.Net.Mobile.Maui.Controls;
|
||||
using Sarand.Net.Mobile.Maui.Layouts;
|
||||
using Sarand.Net.Mobile.Maui.Utils;
|
||||
using Sarand.Net.Mobile.Maui.Views;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Panels
|
||||
{
|
||||
//=======================================================================
|
||||
/// <summary>
|
||||
/// Panel to display with item list where no filter required, eg. items associated with parent.
|
||||
/// <para>- Message shown to left</para>
|
||||
/// <para>- Buttons shown to right</para>
|
||||
/// </summary>
|
||||
public class SamPanel_ItemListSummary : SamContentView
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private SacsMessage? message;
|
||||
private bool showAddButton = false;
|
||||
private double actionButtonSpacing = 4.0;
|
||||
// Panel layout.
|
||||
private SamStackLayout panelLayout = new SamStackLayout() { Orientation = StackOrientation.Horizontal };
|
||||
private SamContentView panelMessage = new SamContentView();
|
||||
private SamLabel labelMessage = new SamLabel() { HorizontalOptions = LayoutOptions.Start };
|
||||
// Action buttons.
|
||||
private SamStackLayout panelActions = new SamStackLayout() { Orientation = StackOrientation.Horizontal };
|
||||
private SamImageButton buttonAddItem = new SamImageButton() { IsVisible = false, HorizontalOptions = LayoutOptions.End, VerticalOptions = LayoutOptions.Start };
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamPanel_ItemListSummary()
|
||||
{
|
||||
// Panel layout.
|
||||
panelLayout.HorizontalOptions = LayoutOptions.Fill;
|
||||
Content = panelLayout;
|
||||
|
||||
// Message.
|
||||
panelMessage.HorizontalOptions = LayoutOptions.Fill;
|
||||
panelMessage.VerticalOptions = LayoutOptions.Fill;
|
||||
//panelMessage.BackgroundColor = Color.LightGoldenrodYellow;
|
||||
panelLayout.Children.Add(panelMessage);
|
||||
labelMessage.HorizontalOptions = LayoutOptions.Center;
|
||||
labelMessage.VerticalOptions = LayoutOptions.Center;
|
||||
panelMessage.Content = labelMessage;
|
||||
|
||||
// Action buttons.
|
||||
panelActions.HorizontalOptions = LayoutOptions.EndAndExpand;
|
||||
panelLayout.Children.Add(panelActions);
|
||||
|
||||
// 'Add' button.
|
||||
buttonAddItem.IsVisible = showAddButton;
|
||||
buttonAddItem.Padding = new Thickness(0, 0, actionButtonSpacing, 0);
|
||||
buttonAddItem.BackgroundColor = Colors.Transparent;
|
||||
buttonAddItem.Source = SamImageUtil.GetImageFromByteArray(SacsResourceHelper.GetResourceImage(SacsResourceHelper.ImageResource.IconShock_Add_Green_72_png));
|
||||
buttonAddItem.Clicked += ButtonAddItem_Clicked;
|
||||
panelActions.Children.Add(buttonAddItem);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
// Message.
|
||||
public double MessageFontSizeDefault { get { return labelMessage.FontSizeDefault; } }
|
||||
public double MessageFontSize
|
||||
{
|
||||
get { return labelMessage.FontSize; }
|
||||
set { labelMessage.FontSize = value; }
|
||||
}
|
||||
// Action buttons.
|
||||
public double ActionButtonSpacing
|
||||
{
|
||||
get { return actionButtonSpacing; }
|
||||
set
|
||||
{
|
||||
if (actionButtonSpacing == value) return;
|
||||
buttonAddItem.Padding = new Thickness(0, 0, actionButtonSpacing, 0);
|
||||
}
|
||||
}
|
||||
public bool ShowAddButton
|
||||
{
|
||||
get { return showAddButton; }
|
||||
set { if (showAddButton == value) return; showAddButton = value; buttonAddItem.IsVisible = showAddButton; }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// M e s s a g e
|
||||
//-------------------------------------------------------------------
|
||||
public void ClearMessage()
|
||||
{
|
||||
message = null;
|
||||
labelMessage.Text = "";
|
||||
}
|
||||
public void SetMessage(String message, SaMessageLevel messageLevel = SaMessageLevel.Info)
|
||||
{
|
||||
SetMessage(new SacsMessage(message, messageLevel));
|
||||
}
|
||||
public void SetMessage(SacsMessage message)
|
||||
{
|
||||
this.message = message;
|
||||
labelMessage.Text = (message != null ? message.Message : "");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// A c t i o n B u t t o n s
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// P a n e l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
public event EventHandler<EventArgs>? AddClicked;
|
||||
protected virtual void ButtonAddItem_Clicked(object? sender, EventArgs e)
|
||||
{
|
||||
if (AddClicked != null) AddClicked.Invoke(sender, e);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using Sarand.Net.Mobile.Maui.Controls;
|
||||
using Sarand.Net.Mobile.Maui.Layouts;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Panels
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamPanel_Messages : SamPanel
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public class Config
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private Config config;
|
||||
private readonly List<SacsMessage> messages = new List<SacsMessage>();
|
||||
// Components.
|
||||
private SamStackLayout mainLayout = new SamStackLayout() { Orientation = StackOrientation.Vertical };
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamPanel_Messages(Config config)
|
||||
{
|
||||
this.config = config;
|
||||
Content = mainLayout;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// M e s s a g e s
|
||||
//-------------------------------------------------------------------
|
||||
public void ClearMessages()
|
||||
{
|
||||
messages.Clear();
|
||||
RefreshLayout();
|
||||
}
|
||||
public void AddMessage(SacsMessage message)
|
||||
{
|
||||
messages.Add(message);
|
||||
RefreshLayout();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// R e f r e s h L a y o u t
|
||||
//-------------------------------------------------------------------
|
||||
private void RefreshLayout()
|
||||
{
|
||||
// Reset layout.
|
||||
IsVisible = messages.Count > 0;
|
||||
mainLayout.Children.Clear();
|
||||
|
||||
foreach (SacsMessage message in messages)
|
||||
{
|
||||
SamPanel messagePanel = new SamPanel();
|
||||
messagePanel.Content = new SamLabel() { Text = message.Message };
|
||||
mainLayout.Children.Add(messagePanel);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// P a n e l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
using Sarand.Net.Mobile.Maui.App;
|
||||
using Sarand.Net.Mobile.Maui.Controls;
|
||||
using Sarand.Net.Mobile.Maui.Layouts;
|
||||
using Sarand.Net.Mobile.Maui.Utils;
|
||||
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.Panels
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamPanel_Page_Footer : SamPanel
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
// Layout.
|
||||
private VerticalStackLayout panelFooter = new VerticalStackLayout() { BackgroundColor = Sam.Visuals.Page.Footer.BackgroundColor };
|
||||
private SamBoxView panelBorderTop = new SamBoxView() { BackgroundColor = Sam.Visuals.Page.Footer.BorderColor, HeightRequest = Sam.Visuals.Page.Footer.BorderStrokeWidthTop };
|
||||
private SamBoxView panelBorderBottom = new SamBoxView() { BackgroundColor = Sam.Visuals.Page.Footer.BorderColor, HeightRequest = Sam.Visuals.Page.Footer.BorderStrokeWidthBottom };
|
||||
// Grid.
|
||||
private SamGrid gridFooter = new SamGrid() { Padding = Sam.Visuals.Page.Footer.Padding };
|
||||
private ColumnDefinition colLeft = new ColumnDefinition(GridLength.Star);
|
||||
private ColumnDefinition colMiddle = new ColumnDefinition(GridLength.Auto);
|
||||
private ColumnDefinition colRight = new ColumnDefinition(GridLength.Star);
|
||||
// Panels.
|
||||
private VerticalStackLayout panelLeft = new VerticalStackLayout() { HorizontalOptions = LayoutOptions.Start };
|
||||
private VerticalStackLayout panelMiddle = new VerticalStackLayout() { HorizontalOptions = LayoutOptions.Center };
|
||||
private VerticalStackLayout panelRight = new VerticalStackLayout() { HorizontalOptions = LayoutOptions.End };
|
||||
// Date-time display.
|
||||
private String dateTimeFormat = "ddd d-MMM-yyyy HH:mm:ss";
|
||||
private IDispatcherTimer? timerDateTime;
|
||||
private Sam.DisplayPosition dateTimeDisplay = Sam.Visuals.Page.Footer.DateTimeDisplay;
|
||||
private SamLabel labelDateTime = new SamLabel() { FontSize = 12.0, HorizontalTextAlignment = TextAlignment.Center };
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamPanel_Page_Footer()
|
||||
{
|
||||
// Footer panel.
|
||||
Content = panelFooter;
|
||||
|
||||
// Footer border top.
|
||||
panelFooter.Children.Add(panelBorderTop);
|
||||
|
||||
// Footer grid.
|
||||
gridFooter.ColumnDefinitions.Add(colLeft);
|
||||
gridFooter.ColumnDefinitions.Add(colMiddle);
|
||||
gridFooter.ColumnDefinitions.Add(colRight);
|
||||
gridFooter.Add(panelLeft, 0, 0);
|
||||
gridFooter.Add(panelMiddle, 1, 0);
|
||||
gridFooter.Add(panelRight, 2, 0);
|
||||
panelFooter.Children.Add(gridFooter);
|
||||
|
||||
// Footer border bottom.
|
||||
panelFooter.Children.Add(panelBorderBottom);
|
||||
|
||||
RefreshComponents();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public Sam.DisplayPosition DateTimeDisplay
|
||||
{
|
||||
get { return dateTimeDisplay; }
|
||||
set { dateTimeDisplay = value; RefreshComponents(); }
|
||||
}
|
||||
public String DateTimeFormat
|
||||
{
|
||||
get { return dateTimeFormat; }
|
||||
set { dateTimeFormat = value; RefreshComponents(); }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Events.
|
||||
protected override void OnParentChanged()
|
||||
{
|
||||
base.OnParentChanged();
|
||||
if (Parent == null)
|
||||
ClearDateTimeTimer();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// DateTime display.
|
||||
private void ClearDateTimeTimer()
|
||||
{
|
||||
if (timerDateTime != null && timerDateTime.IsRunning)
|
||||
timerDateTime.Stop();
|
||||
}
|
||||
|
||||
private void TimerDateTime_Tick(object? sender, EventArgs e)
|
||||
{
|
||||
String dateTimeValue = DateTime.Now.ToString(dateTimeFormat);
|
||||
if (!labelDateTime.Text.Equals(dateTimeValue))
|
||||
labelDateTime.Text = dateTimeValue;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private void RefreshComponents()
|
||||
{
|
||||
bool contentDisplayed = false;
|
||||
|
||||
// Date time.
|
||||
ClearDateTimeTimer();
|
||||
panelLeft.Children.Remove(labelDateTime);
|
||||
panelMiddle.Children.Remove(labelDateTime);
|
||||
panelRight.Children.Remove(labelDateTime);
|
||||
if (dateTimeDisplay == Sam.DisplayPosition.Left)
|
||||
panelLeft.Children.Add(labelDateTime);
|
||||
else if (dateTimeDisplay == Sam.DisplayPosition.Middle)
|
||||
panelMiddle.Children.Add(labelDateTime);
|
||||
else if (dateTimeDisplay == Sam.DisplayPosition.Right)
|
||||
panelRight.Children.Add(labelDateTime);
|
||||
if (dateTimeDisplay != Sam.DisplayPosition.None)
|
||||
{
|
||||
contentDisplayed = true;
|
||||
timerDateTime = SamTimerUtil.DoTimer(this, TimeSpan.FromMilliseconds(250), true, TimerDateTime_Tick);
|
||||
timerDateTime.Start();
|
||||
}
|
||||
|
||||
// Hide panel if nothing displayed.
|
||||
if (contentDisplayed)
|
||||
IsVisible = true;
|
||||
else IsVisible = false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
using Microsoft.Maui.Controls.Internals;
|
||||
using Sarand.Net.Mobile.Maui.App;
|
||||
using Sarand.Net.Mobile.Maui.Controls;
|
||||
using Sarand.Net.Mobile.Maui.Layouts;
|
||||
using Sarand.Net.Mobile.Maui.Utils;
|
||||
using Sarand.Net.Mobile.Maui.Views;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Panels
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamPanel_Page_Header : SamPanel
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
// Layout.
|
||||
private SamBoxView panelBorderTop = new SamBoxView() { BackgroundColor = Sam.Visuals.Page.Header.BorderColor, HeightRequest = Sam.Visuals.Page.Header.BorderStrokeWidthTop };
|
||||
private VerticalStackLayout panelHeader = new VerticalStackLayout() { BackgroundColor = Sam.Visuals.Page.Header.BackgroundColor };
|
||||
private SamBoxView panelBorderBottom = new SamBoxView() { BackgroundColor = Sam.Visuals.Page.Header.BorderColor, HeightRequest = Sam.Visuals.Page.Header.BorderStrokeWidthBottom };
|
||||
// Grid.
|
||||
private SamGrid gridHeader = new SamGrid() { Padding = Sam.Visuals.Page.Header.Padding };
|
||||
private ColumnDefinition colLeft = new ColumnDefinition(GridLength.Star);
|
||||
private ColumnDefinition colMiddle = new ColumnDefinition(GridLength.Auto);
|
||||
private ColumnDefinition colRight = new ColumnDefinition(GridLength.Star);
|
||||
// Panels.
|
||||
private VerticalStackLayout panelLeft = new VerticalStackLayout() { HorizontalOptions = LayoutOptions.Start };
|
||||
private VerticalStackLayout panelMiddle = new VerticalStackLayout() { HorizontalOptions = LayoutOptions.Center };
|
||||
private VerticalStackLayout panelRight = new VerticalStackLayout() { HorizontalOptions = LayoutOptions.End };
|
||||
// Caption.
|
||||
private SamLabel labelCaption = new SamLabel() { HorizontalOptions = LayoutOptions.Center };
|
||||
private Sam.DisplayPosition captionDisplay = Sam.DisplayPosition.Middle;
|
||||
// Text labels.
|
||||
private SamLabel labelLeft = new SamLabel() { HorizontalOptions = LayoutOptions.Start };
|
||||
private SamLabel labelRight= new SamLabel() { HorizontalOptions = LayoutOptions.End };
|
||||
// Toolbar.
|
||||
private Sam.DisplayPosition toolbarDisplay = Sam.Visuals.Page.Header.ToolbarDisplay;
|
||||
private HorizontalStackLayout panelToolbar = new HorizontalStackLayout() { };
|
||||
private bool display_ToolbarItem_Back = Sam.Visuals.Page.Header.Display_ToolbarItem_Back;
|
||||
private Button toolbarItem_Back = new Button() { WidthRequest = 16, HeightRequest = 16, Text="<", Padding=new Thickness(0), BorderWidth = 0.0, BorderColor = Colors.DarkOliveGreen };
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamPanel_Page_Header()
|
||||
{
|
||||
InitialiseComponents();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public String Caption
|
||||
{
|
||||
get { return labelCaption.Text; }
|
||||
set { labelCaption.Text = value; ConfigureComponents(); }
|
||||
}
|
||||
public Sam.DisplayPosition CaptionDisplay
|
||||
{
|
||||
get { return captionDisplay; }
|
||||
set { captionDisplay = value; ConfigureComponents(); }
|
||||
}
|
||||
|
||||
// Text labels.
|
||||
public String TextLeft
|
||||
{
|
||||
get { return labelLeft.Text; }
|
||||
set { labelLeft.Text = value; ConfigureComponents(); }
|
||||
}
|
||||
public String TextRight
|
||||
{
|
||||
get { return labelRight.Text; }
|
||||
set { labelRight.Text = value; ConfigureComponents(); }
|
||||
}
|
||||
|
||||
// Toolbar.
|
||||
public Sam.DisplayPosition ToolbarDisplay
|
||||
{
|
||||
get { return toolbarDisplay; }
|
||||
set { toolbarDisplay = value; ConfigureComponents(); }
|
||||
}
|
||||
public bool Display_ToolbarItem_Back
|
||||
{
|
||||
get { return display_ToolbarItem_Back; }
|
||||
set { display_ToolbarItem_Back = value; ConfigureComponents(); }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Components.
|
||||
|
||||
private void InitialiseComponents()
|
||||
{
|
||||
// Header panel.
|
||||
Content = panelHeader;
|
||||
|
||||
// Top border.
|
||||
panelBorderTop.Margin = new Thickness(0, 0, 0, Sam.Visuals.Page.Header.Padding.Top);
|
||||
panelHeader.Children.Add(panelBorderTop);
|
||||
|
||||
// Header grid.
|
||||
gridHeader.Margin = new Thickness(Sam.Visuals.Page.Header.Padding.Left, 0, Sam.Visuals.Page.Header.Padding.Right, 0);
|
||||
gridHeader.ColumnDefinitions.Add(colLeft);
|
||||
gridHeader.ColumnDefinitions.Add(colMiddle);
|
||||
gridHeader.ColumnDefinitions.Add(colRight);
|
||||
gridHeader.Add(panelLeft, 0, 0);
|
||||
gridHeader.Add(panelMiddle, 1, 0);
|
||||
gridHeader.Add(panelRight, 2, 0);
|
||||
panelHeader.Children.Add(gridHeader);
|
||||
|
||||
// Bottom border.
|
||||
panelBorderBottom.Margin = new Thickness(0, Sam.Visuals.Page.Header.Padding.Bottom, 0, 0);
|
||||
panelHeader.Children.Add(panelBorderBottom);
|
||||
|
||||
// Configure standard toolbar icons.
|
||||
toolbarItem_Back.Clicked += ToolbarItem_Back_Clicked;
|
||||
}
|
||||
|
||||
public override void ConfigureComponents()
|
||||
{
|
||||
base.ConfigureComponents();
|
||||
bool contentDisplayed = false;
|
||||
|
||||
// Caption.
|
||||
panelLeft.Children.Remove(labelCaption);
|
||||
panelMiddle.Children.Remove(labelCaption);
|
||||
panelRight.Children.Remove(labelCaption);
|
||||
if (captionDisplay != Sam.DisplayPosition.None && !StringUtil.IsBlank(labelCaption.Text))
|
||||
{
|
||||
contentDisplayed = true;
|
||||
if (captionDisplay == Sam.DisplayPosition.Left)
|
||||
panelLeft.Children.Add(labelCaption);
|
||||
else if (captionDisplay == Sam.DisplayPosition.Middle)
|
||||
panelMiddle.Children.Add(labelCaption);
|
||||
else if (captionDisplay == Sam.DisplayPosition.Right)
|
||||
panelRight.Children.Add(labelCaption);
|
||||
}
|
||||
|
||||
// Text labels.
|
||||
panelLeft.Children.Remove(labelLeft);
|
||||
if (!StringUtil.IsBlank(labelLeft.Text))
|
||||
{
|
||||
contentDisplayed = true;
|
||||
panelLeft.Children.Add(labelLeft);
|
||||
}
|
||||
panelRight.Children.Remove(labelRight);
|
||||
if (!StringUtil.IsBlank(labelRight.Text))
|
||||
{
|
||||
contentDisplayed = true;
|
||||
panelRight.Children.Add(labelRight);
|
||||
}
|
||||
|
||||
// Toolbar.
|
||||
panelLeft.Children.Remove(panelToolbar);
|
||||
panelMiddle.Children.Remove(panelToolbar);
|
||||
panelRight.Children.Remove(panelToolbar);
|
||||
panelToolbar.Children.Clear();
|
||||
|
||||
// Toolbar icons.
|
||||
if (display_ToolbarItem_Back)
|
||||
panelToolbar.Children.Add(toolbarItem_Back);
|
||||
if (panelToolbar.Children.Any() && ToolbarDisplay != Sam.DisplayPosition.None)
|
||||
{
|
||||
contentDisplayed = true;
|
||||
if (ToolbarDisplay == Sam.DisplayPosition.Left)
|
||||
panelLeft.Children.Add(panelToolbar);
|
||||
else if (ToolbarDisplay == Sam.DisplayPosition.Middle)
|
||||
panelMiddle.Children.Add(panelToolbar);
|
||||
else if (ToolbarDisplay == Sam.DisplayPosition.Right)
|
||||
panelRight.Children.Add(panelToolbar);
|
||||
}
|
||||
|
||||
// Hide panel if nothing displayed.
|
||||
if (contentDisplayed)
|
||||
IsVisible = true;
|
||||
else IsVisible = false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Toolbar actions.
|
||||
|
||||
private void ToolbarItem_Back_Clicked(object? sender, EventArgs e)
|
||||
{
|
||||
//if (Navigation.NavigationStack.Where(item => System.Object.ReferenceEquals(item, this)).Any())
|
||||
Page? page = this.GetPage();
|
||||
if (Navigation.NavigationStack.Any() && System.Object.ReferenceEquals(Navigation.NavigationStack.Last(), page))
|
||||
{
|
||||
Navigation.PopAsync();
|
||||
return;
|
||||
}
|
||||
if (Navigation.ModalStack.Where(item => System.Object.ReferenceEquals(item, page)).Any())
|
||||
{
|
||||
Navigation.PopModalAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using Sarand.Net.Mobile.Maui.Controls;
|
||||
using Sarand.Net.Mobile.Maui.Layouts;
|
||||
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.Panels
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamPanel_Progress : SamContentView
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public class Config
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private Config config;
|
||||
// Panel layout.
|
||||
private SamGrid gridPanel = new SamGrid();
|
||||
private SamContentView viewPanel = new SamContentView();
|
||||
private SamLabel labelProgressMessage = new SamLabel();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamPanel_Progress(Config config)
|
||||
{
|
||||
this.config = config;
|
||||
InitialiseComponents();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public double ProgressMessageFontSizeDefault { get { return labelProgressMessage.FontSizeDefault; } }
|
||||
public double ProgressMessageFontSize { get { return labelProgressMessage.FontSize; } set { labelProgressMessage.FontSize = value; } }
|
||||
public FontAttributes ProgressMessageFontAttributes { get { return labelProgressMessage.FontAttributes; } set { labelProgressMessage.FontAttributes = value; } }
|
||||
public Color ProgressMessageColor { get { return labelProgressMessage.TextColor; } set { labelProgressMessage.TextColor = value; } }
|
||||
public String ProgressMessage { get { return labelProgressMessage.Text; } set { labelProgressMessage.Text = value; } }
|
||||
public Thickness ProgressMessagePadding { get { return viewPanel.Padding; } set { viewPanel.Padding = value; } }
|
||||
public Color ProgressMessageBackgroundColor { get { return viewPanel.BackgroundColor; } set { viewPanel.BackgroundColor = value; } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// I n i t i a l i s e
|
||||
//-------------------------------------------------------------------
|
||||
private void InitialiseComponents()
|
||||
{
|
||||
// Layout is a 3x3 grid with only the central cell populated.
|
||||
// All other cells are transparent/opaque.
|
||||
gridPanel.BackgroundColor = new Color(0, 0, 0, 0.5f);
|
||||
gridPanel.HorizontalOptions = LayoutOptions.FillAndExpand;
|
||||
gridPanel.VerticalOptions = LayoutOptions.FillAndExpand;
|
||||
gridPanel.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });
|
||||
gridPanel.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
|
||||
gridPanel.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });
|
||||
gridPanel.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Star });
|
||||
gridPanel.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
|
||||
gridPanel.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Star });
|
||||
Content = gridPanel;
|
||||
|
||||
// The panel's view.
|
||||
viewPanel.Padding = new Thickness(12.0);
|
||||
viewPanel.BackgroundColor = Colors.WhiteSmoke;
|
||||
viewPanel.HorizontalOptions = LayoutOptions.Center;
|
||||
viewPanel.VerticalOptions = LayoutOptions.Center;
|
||||
gridPanel.Add(viewPanel, 1, 1);
|
||||
|
||||
// Progress message.
|
||||
viewPanel.Content = labelProgressMessage;
|
||||
|
||||
// Complete panel configuration.
|
||||
ConfigurePanel();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n f i g u r e P a n e l
|
||||
//-------------------------------------------------------------------
|
||||
private void ConfigurePanel()
|
||||
{
|
||||
// Panel initialisation that depends on the configuration.
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// P a n e l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
using Sarand.Net.Mobile.Maui.Controls;
|
||||
using Sarand.Net.Mobile.Maui.Layouts;
|
||||
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.Panels
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamPanel_PropertySummary : SamContentView
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
private class PropertyData
|
||||
{
|
||||
public String Caption { get; set; } = "";
|
||||
public String Value { get; set; } = "";
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private float internalFrameRadiusFactor = 0.8f;
|
||||
private readonly List<PropertyData> properties = new List<PropertyData>();
|
||||
// Panel components.
|
||||
private SamFrame framePanel = new SamFrame();
|
||||
private SamFrame frameInternal = new SamFrame();
|
||||
private SamGrid gridProperties = new SamGrid();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamPanel_PropertySummary()
|
||||
{
|
||||
// View properties.
|
||||
//BackgroundColor = Color.Transparent;
|
||||
framePanel.CornerRadius = 8.0f;
|
||||
framePanel.Padding = new Thickness(2.0);
|
||||
framePanel.BackgroundColor = Colors.Transparent;
|
||||
framePanel.BorderColor = framePanel.BorderColor;
|
||||
Content = framePanel;
|
||||
|
||||
// Frame.
|
||||
frameInternal.CornerRadius = framePanel.CornerRadius * internalFrameRadiusFactor;
|
||||
frameInternal.Padding = new Thickness(0);
|
||||
frameInternal.BorderColor = Colors.White;
|
||||
frameInternal.BackgroundColor = Colors.White;
|
||||
framePanel.Content = frameInternal;
|
||||
frameInternal.Content = gridProperties;
|
||||
|
||||
// Properties grid.
|
||||
gridProperties.Padding = new Thickness(4.0);
|
||||
gridProperties.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
|
||||
gridProperties.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });
|
||||
|
||||
// Property styling.
|
||||
DefaultFontSize = new SamLabel().FontSize;
|
||||
FontSize = DefaultFontSize;
|
||||
|
||||
ConfigureComponents();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public Color BorderColor
|
||||
{
|
||||
get { return framePanel.BorderColor; }
|
||||
set
|
||||
{
|
||||
framePanel.BorderColor = value;
|
||||
framePanel.BackgroundColor = value;
|
||||
}
|
||||
}
|
||||
public Thickness BorderWidth { get { return framePanel.Padding; } set { framePanel.Padding = value; } }
|
||||
public float CornerRadius
|
||||
{
|
||||
get { return framePanel.CornerRadius; }
|
||||
set
|
||||
{
|
||||
framePanel.CornerRadius = value;
|
||||
frameInternal.CornerRadius = framePanel.CornerRadius * internalFrameRadiusFactor;
|
||||
}
|
||||
}
|
||||
public Color PanelBackgroundColor
|
||||
{
|
||||
get { return frameInternal.BackgroundColor; }
|
||||
set
|
||||
{
|
||||
frameInternal.BorderColor = value;
|
||||
frameInternal.BackgroundColor = value;
|
||||
}
|
||||
}
|
||||
// Property label styling.
|
||||
public double DefaultFontSize { get; }
|
||||
public double FontSize { get; set; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// S u m m a r y P r o p e r t i e s
|
||||
//-------------------------------------------------------------------
|
||||
public void AddProperty(String caption, String value)
|
||||
{
|
||||
properties.Add(new PropertyData() { Caption = caption, Value = value });
|
||||
RefreshProperties();
|
||||
}
|
||||
public void ClearProperties()
|
||||
{
|
||||
properties.Clear();
|
||||
RefreshProperties();
|
||||
}
|
||||
private void RefreshProperties()
|
||||
{
|
||||
// Clear existing properties.
|
||||
gridProperties.Children.Clear();
|
||||
gridProperties.RowDefinitions.Clear();
|
||||
|
||||
foreach (PropertyData property in properties)
|
||||
{
|
||||
int rowIdx = gridProperties.RowDefinitions.Count;
|
||||
gridProperties.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
|
||||
gridProperties.Add(new SamLabel() { Text = property.Caption, FontSize = FontSize, HorizontalOptions = LayoutOptions.End }, 0, rowIdx);
|
||||
gridProperties.Add(new SamLabel() { Text = property.Value, FontSize = FontSize, HorizontalOptions = LayoutOptions.StartAndExpand, VerticalOptions = LayoutOptions.StartAndExpand }, 1, rowIdx);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n f i g u r e C o m p o n e n t s
|
||||
//-------------------------------------------------------------------
|
||||
public override void ConfigureComponents()
|
||||
{
|
||||
base.ConfigureComponents();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// P a n e l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
|
||||
using Sarand.Net.Mobile.Maui.Views;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Panels
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamPanel_Tab : SamPanel
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamPanel_Tab()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n f i g u r e C o m p o n e n t s
|
||||
//-------------------------------------------------------------------
|
||||
public override void ConfigureComponents()
|
||||
{
|
||||
base.ConfigureComponents();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l A c t i v i t y
|
||||
//-------------------------------------------------------------------
|
||||
public override void SetControlActivity()
|
||||
{
|
||||
}
|
||||
public override void SetControlsReadOnly()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// P a n e l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnParentSet()
|
||||
{
|
||||
base.OnParentSet();
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnPropertyChanging([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanging(propertyName);
|
||||
}
|
||||
protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnChildAdded(Element child)
|
||||
{
|
||||
base.OnChildAdded(child);
|
||||
}
|
||||
protected override void OnChildRemoved(Element child, int oldLogicalIndex)
|
||||
{
|
||||
base.OnChildRemoved(child, oldLogicalIndex);
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnSizeAllocated(double width, double height)
|
||||
{
|
||||
base.OnSizeAllocated(width, height);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
using Sarand.Net.Mobile.Maui.Views;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Panels
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamPanel_Tabbed : SamPanel
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
private class TabPanelData
|
||||
{
|
||||
public TabPanelData(int tabPos, SamPanel_TabCaption tabCaptionPanel, SamPanel_Tab tabPanel)
|
||||
{
|
||||
TabPos = tabPos;
|
||||
TabCaptionPanel = tabCaptionPanel;
|
||||
TabPanel = tabPanel;
|
||||
}
|
||||
public int TabPos { get; }
|
||||
public SamPanel_TabCaption TabCaptionPanel { get; }
|
||||
public SamPanel_Tab TabPanel { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tab Caption panel
|
||||
/// </summary>
|
||||
public class SamPanel_TabCaption : SamPanel
|
||||
{
|
||||
// Properties.
|
||||
private SamPanel_Tabbed TabbedPanel { get; }
|
||||
public int TabPos { get; }
|
||||
public String Caption { get; }
|
||||
// Data members.
|
||||
private static readonly Color ActiveBackgroundColor = Colors.WhiteSmoke;
|
||||
private static readonly Color ActiveBorderColor = Colors.DarkSlateBlue;
|
||||
private static readonly Color InactiveBackgroundColor = Colors.LightGray;
|
||||
private static readonly Color InactiveBorderColor = Colors.SlateBlue;
|
||||
private Border border = new Border() { Stroke = InactiveBorderColor, StrokeThickness = 2.0 };
|
||||
private TapGestureRecognizer tabCaptionTapGesture = new TapGestureRecognizer();
|
||||
public SamPanel_TabCaption(SamPanel_Tabbed tabbedPanel, int tabPos, String caption)
|
||||
{
|
||||
TabbedPanel = tabbedPanel;
|
||||
TabPos = tabPos;
|
||||
Caption = caption;
|
||||
Content = border;
|
||||
tabCaptionTapGesture.Tapped += TabCaptionTapGesture_Tapped;
|
||||
GestureRecognizers.Add(tabCaptionTapGesture);
|
||||
Deactivate();
|
||||
}
|
||||
private void TabCaptionTapGesture_Tapped(object? sender, TappedEventArgs e)
|
||||
{
|
||||
TabbedPanel.TabCaptionTapped(sender, e, TabPos);
|
||||
}
|
||||
public void Activate()
|
||||
{
|
||||
BackgroundColor = ActiveBackgroundColor;
|
||||
border.Stroke = ActiveBorderColor;
|
||||
}
|
||||
public void Deactivate()
|
||||
{
|
||||
BackgroundColor = InactiveBackgroundColor;
|
||||
border.Stroke = InactiveBorderColor;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
// Content.
|
||||
private VerticalStackLayout contentStack = new VerticalStackLayout() { };
|
||||
private HorizontalStackLayout panelTabCaptions = new HorizontalStackLayout() { Spacing = 8.0 };
|
||||
private ScrollView scrollTabPanels = new ScrollView() { };
|
||||
private VerticalStackLayout panelTabPanels = new VerticalStackLayout() { };
|
||||
|
||||
// Tab panels.
|
||||
private int tabCount = 0;
|
||||
private readonly List<TabPanelData> tabPanels = new List<TabPanelData>();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamPanel_Tabbed()
|
||||
{
|
||||
// Content.
|
||||
Content = contentStack;
|
||||
|
||||
// Tab captions.
|
||||
contentStack.Children.Add(panelTabCaptions);
|
||||
|
||||
// Tab panels.
|
||||
contentStack.Children.Add(scrollTabPanels);
|
||||
scrollTabPanels.Content = panelTabPanels;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Manage tabs.
|
||||
|
||||
public void AddTabPanel(String caption, SamPanel_Tab tabPanel)
|
||||
{
|
||||
tabCount++;
|
||||
|
||||
// Tab caption.
|
||||
if (StringUtil.IsBlank(caption))
|
||||
caption = $"Tab #{tabCount}";
|
||||
SamPanel_TabCaption panelTabCaption = new SamPanel_TabCaption(this, tabCount, caption);
|
||||
panelTabCaptions.Children.Add(panelTabCaption);
|
||||
|
||||
// Tab panel.
|
||||
panelTabPanels.Children.Add(tabPanel);
|
||||
|
||||
// Tab panel data.
|
||||
TabPanelData tabPanelData = new TabPanelData(tabCount, panelTabCaption, tabPanel);
|
||||
tabPanels.Add(tabPanelData);
|
||||
|
||||
if (tabCount == 1)
|
||||
{
|
||||
panelTabCaption.Activate();
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearTabPanels()
|
||||
{
|
||||
tabCount = 0;
|
||||
tabPanels.Clear();
|
||||
panelTabCaptions.Children.Clear();
|
||||
panelTabPanels.Children.Clear();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Actions.
|
||||
|
||||
private void TabCaptionTapped(object? sender, TappedEventArgs e, int tabPos)
|
||||
{
|
||||
foreach (TabPanelData tabPanel in tabPanels)
|
||||
{
|
||||
if (tabPanel.TabPos == tabPos)
|
||||
{
|
||||
tabPanel.TabCaptionPanel.Activate();
|
||||
tabPanel.TabPanel.IsVisible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
tabPanel.TabCaptionPanel.Deactivate();
|
||||
tabPanel.TabPanel.IsVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n f i g u r e C o m p o n e n t s
|
||||
//-------------------------------------------------------------------
|
||||
public override void ConfigureComponents()
|
||||
{
|
||||
base.ConfigureComponents();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// C o n t r o l A c t i v i t y
|
||||
//-------------------------------------------------------------------
|
||||
public override void SetControlActivity()
|
||||
{
|
||||
}
|
||||
public override void SetControlsReadOnly()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// P a n e l E v e n t s
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnParentSet()
|
||||
{
|
||||
base.OnParentSet();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnPropertyChanging([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanging(propertyName);
|
||||
}
|
||||
protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnChildAdded(Element child)
|
||||
{
|
||||
base.OnChildAdded(child);
|
||||
}
|
||||
protected override void OnChildRemoved(Element child, int oldLogicalIndex)
|
||||
{
|
||||
base.OnChildRemoved(child, oldLogicalIndex);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protected override void OnSizeAllocated(double width, double height)
|
||||
{
|
||||
base.OnSizeAllocated(width, height);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
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.Panels
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamTabPanel : SamPanel
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamTabPanel(String caption, SamContentView panel)
|
||||
{
|
||||
Caption = caption;
|
||||
|
||||
// This panel includes border layout around the actual tab panel content.
|
||||
Padding = new Thickness(2.0);
|
||||
BackgroundColor = Colors.LightSlateGray;
|
||||
Content = panel;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public String Caption { get; }
|
||||
public Thickness BorderWidth
|
||||
{
|
||||
get { return Padding; }
|
||||
set { if (Padding == value) return; Padding = value; }
|
||||
}
|
||||
public Color BorderColor
|
||||
{
|
||||
get { return BackgroundColor; }
|
||||
set { if (BackgroundColor == value) return; BackgroundColor = value; }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// T a b P a n e l s
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Utils
|
||||
{
|
||||
//=======================================================================
|
||||
public static class SamElementUtil
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Identify the page fo rthis element.
|
||||
/// </summary>
|
||||
public static Page? GetPage(this Element element)
|
||||
{
|
||||
while (element != null)
|
||||
{
|
||||
if (element is Page) return element as Page;
|
||||
element = element.Parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Utils
|
||||
{
|
||||
//=======================================================================
|
||||
public static class SamFormsUtil
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// D i s p l a y A l e r t a n d W a i t
|
||||
//-------------------------------------------------------------------
|
||||
public static void DisplayAlertSync(String title, String message, String cancel = "OK")
|
||||
{
|
||||
if (Application.Current?.MainPage == null)
|
||||
{
|
||||
SaLogger.Warn(SysUtil.Fn + " Null main page. Message: " + message);
|
||||
return;
|
||||
}
|
||||
SamThreadUtil.InvokeOnMainThreadSync(async () => await Application.Current.MainPage.DisplayAlert(title, message, cancel));
|
||||
}
|
||||
public static bool DisplayConfirmSync(String title, String message, String accept = "Yes", String cancel = "No")
|
||||
{
|
||||
if (Application.Current?.MainPage == null)
|
||||
{
|
||||
SaLogger.Warn(SysUtil.Fn + " Null main page. Message: " + message);
|
||||
return false;
|
||||
}
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
MainThread.BeginInvokeOnMainThread(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
bool result = await Application.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
tcs.SetResult(result);
|
||||
}
|
||||
catch (Exception ex) { tcs.SetException(ex); }
|
||||
});
|
||||
return tcs.Task.Result;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Utils
|
||||
{
|
||||
//=======================================================================
|
||||
public static class SamImageUtil
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Method that uses the ImageConverter object in .Net Framework to convert a byte array,
|
||||
/// presumably containing a JPEG or PNG file image, into an ImageSource.
|
||||
/// </summary>
|
||||
public static ImageSource GetImageFromByteArray(byte[] imageAsBytes)
|
||||
{
|
||||
return ImageSource.FromStream(() => new MemoryStream(imageAsBytes));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Microsoft.Maui.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Utils
|
||||
{
|
||||
//=======================================================================
|
||||
public static class SamPageUtil
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Utils
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamResourceUtil
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Resource as Stream.
|
||||
|
||||
public static Stream? GetResourceStream(String resourcePath)
|
||||
{
|
||||
return GetResourceStream(Assembly.GetExecutingAssembly(), resourcePath);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
public static Stream? GetResourceStream(Assembly assembly, String resourcePath)
|
||||
{
|
||||
Stream? stream = assembly.GetManifestResourceStream(resourcePath);
|
||||
if (stream != null) return stream;
|
||||
|
||||
foreach (var res in assembly.GetManifestResourceNames())
|
||||
{
|
||||
//SaLogger.Info(SysUtil.Fn + $" Resource: {res.ToString()}");
|
||||
|
||||
// Read source file
|
||||
stream = assembly.GetManifestResourceStream(res);
|
||||
//using var reader = new StreamReader(stream);
|
||||
//var content = reader.ReadToEnd();
|
||||
|
||||
// generate target path inside data folder
|
||||
//string targetFile = System.IO.Path.Combine(FileSystem.Current.AppDataDirectory, res);
|
||||
|
||||
// write file into data folder
|
||||
//using FileStream outputStream = System.IO.File.OpenWrite(targetFile);
|
||||
//using StreamWriter streamWriter = new StreamWriter(outputStream);
|
||||
|
||||
//streamWriter.Write(content);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Log resources.
|
||||
public static void LogResources(Assembly assembly)
|
||||
{
|
||||
foreach (var res in assembly.GetManifestResourceNames())
|
||||
SaLogger.Info(SysUtil.Fn + $" Resource: {res.ToString()}");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Utils
|
||||
{
|
||||
//=======================================================================
|
||||
public static class SamThreadUtil
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Thread utilities.
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
/// <summary>Is the current thread the main thread.</summary>
|
||||
public static bool IsMainThread()
|
||||
{
|
||||
return MainThread.IsMainThread;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// I n v o k e o n M a i n T h r e a d a n d W a i t
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
/// <summary>Invoke task on main thread.</summary>
|
||||
public static void InvokeOnMainThread(Action taskFn)
|
||||
{
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
taskFn();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Invoke task on main thread and wait for completion.</summary>
|
||||
public static void InvokeOnMainThreadSync(Action taskFn)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<Object>();
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
taskFn();
|
||||
tcs.SetResult(true);
|
||||
}
|
||||
catch (Exception ex) { tcs.SetException(ex); }
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Invoke task on main thread and wait for completion.</summary>
|
||||
public static T InvokeOnMainThreadSync<T>(Func<T> taskFn)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<T>();
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = taskFn();
|
||||
tcs.SetResult(result);
|
||||
}
|
||||
catch (Exception ex) { tcs.SetException(ex); }
|
||||
});
|
||||
return tcs.Task.Result;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Utils
|
||||
{
|
||||
//=======================================================================
|
||||
public static class SamTimerUtil
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Timer utilities.
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
public static IDispatcherTimer DoTimer (BindableObject bindable, TimeSpan interval, bool isRepeating, EventHandler handler)
|
||||
{
|
||||
IDispatcherTimer timer = bindable.Dispatcher.CreateTimer();
|
||||
timer.Interval = interval;
|
||||
timer.IsRepeating = isRepeating;
|
||||
timer.Tick += handler;
|
||||
timer.Start();
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Views
|
||||
{
|
||||
//======================================================================
|
||||
public interface ISamView
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Configure layout of components when visual properties (eg. change in orientation) occurs.
|
||||
/// <para>Automatically called by parent page when dimensions change.</para>
|
||||
/// <para>NB Not to be used for initial population of components as this method may be called multiple times.</para>
|
||||
/// </summary>
|
||||
void ConfigureComponents();
|
||||
|
||||
void SetControlActivity();
|
||||
|
||||
void SetControlsReadOnly();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//======================================================================
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Views
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamBorder : Border
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamBorder()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Configure components.
|
||||
public virtual void ConfigureComponents()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Control activity.
|
||||
public virtual void SetControlActivity()
|
||||
{
|
||||
SetControlsReadOnly();
|
||||
}
|
||||
public virtual void SetControlsReadOnly()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Views
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamBoxView : BoxView, ISamView
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamBoxView()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Configure components.
|
||||
public virtual void ConfigureComponents()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Control activity.
|
||||
public virtual void SetControlActivity()
|
||||
{
|
||||
SetControlsReadOnly();
|
||||
}
|
||||
public virtual void SetControlsReadOnly()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using Sarand.Net.Mobile.Maui.Utils;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Views
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamContentView : ContentView, ISamView
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private bool readOnly = false;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamContentView()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
public Page? GetPage() { return SamElementUtil.GetPage(this); }
|
||||
|
||||
public bool ReadOnly
|
||||
{
|
||||
get { return readOnly; }
|
||||
set { if (readOnly == value) return; readOnly = value; SetControlActivity(); }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Configure components.
|
||||
public virtual void ConfigureComponents()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Control activity.
|
||||
public virtual void SetControlActivity()
|
||||
{
|
||||
SetControlsReadOnly();
|
||||
}
|
||||
public virtual void SetControlsReadOnly()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// View events.
|
||||
|
||||
protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
if (propertyName.EqualsCI(IsEnabledProperty.PropertyName))
|
||||
{
|
||||
SetControlActivity();
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Views
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamFrame : Frame, ISamView
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamFrame()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Configure components.
|
||||
public virtual void ConfigureComponents()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Control activity.
|
||||
public virtual void SetControlActivity()
|
||||
{
|
||||
SetControlsReadOnly();
|
||||
}
|
||||
public virtual void SetControlsReadOnly()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.Net.Mobile.Maui.Views
|
||||
{
|
||||
//=======================================================================
|
||||
public class SamView : View, ISamView
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SamView()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Configure components.
|
||||
public virtual void ConfigureComponents()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Control activity.
|
||||
public virtual void SetControlActivity()
|
||||
{
|
||||
SetControlsReadOnly();
|
||||
}
|
||||
public virtual void SetControlsReadOnly()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace SacsMobileMaui
|
||||
{
|
||||
// All the code in this file is only included on Android.
|
||||
public class PlatformClass1
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace SacsMobileMaui
|
||||
{
|
||||
// All the code in this file is only included on Mac Catalyst.
|
||||
public class PlatformClass1
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace SacsMobileMaui
|
||||
{
|
||||
// All the code in this file is only included on Tizen.
|
||||
public class PlatformClass1
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace SacsMobileMaui
|
||||
{
|
||||
// All the code in this file is only included on Windows.
|
||||
public class PlatformClass1
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace SacsMobileMaui
|
||||
{
|
||||
// All the code in this file is only included on iOS.
|
||||
public class PlatformClass1
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst</TargetFrameworks>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>
|
||||
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
|
||||
<!-- <TargetFrameworks>$(TargetFrameworks);net8.0-tizen</TargetFrameworks> -->
|
||||
<UseMaui>true</UseMaui>
|
||||
<SingleProject>true</SingleProject>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.4</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">13.1</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
|
||||
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.3</SupportedOSPlatformVersion>
|
||||
<RootNamespace>Sarand.Net.Mobile</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Maui.Controls" Version="8.0.20" />
|
||||
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="8.0.20" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SacsStandardBase\SacsStandardBase.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user