Saxonite 1.2.11.3. Sandtrap.
This commit is contained in:
+12
-6
@@ -7,8 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsStandardBase", "SacsSta
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsStandardDbas", "SacsStandardDbas\SacsStandardDbas.csproj", "{14768EB5-6FA5-4F62-9347-44A667A760C1}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsStandardDbas", "SacsStandardDbas\SacsStandardDbas.csproj", "{14768EB5-6FA5-4F62-9347-44A667A760C1}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsStandardMob", "SacsStandardMob\SacsStandardMob.csproj", "{E507AB63-28E3-4FF4-9EA8-2E87C42FFC20}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsCoreWeb", "SacsCoreWeb\SacsCoreWeb.csproj", "{AE8FCC39-D13D-4E32-995E-C69352F9F95E}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsCoreWeb", "SacsCoreWeb\SacsCoreWeb.csproj", "{AE8FCC39-D13D-4E32-995E-C69352F9F95E}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsCoreUnitTests", "SacsCoreUnitTests\SacsCoreUnitTests.csproj", "{70F1302F-E8F2-49CB-A09D-889DA59681DD}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsCoreUnitTests", "SacsCoreUnitTests\SacsCoreUnitTests.csproj", "{70F1302F-E8F2-49CB-A09D-889DA59681DD}"
|
||||||
@@ -22,6 +20,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsStandardAccounts", "Sac
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsStandardProc", "SacsStandardProc\SacsStandardProc.csproj", "{3988EE9F-FFCD-481A-AF5E-AA7E5DB5A415}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsStandardProc", "SacsStandardProc\SacsStandardProc.csproj", "{3988EE9F-FFCD-481A-AF5E-AA7E5DB5A415}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsMobileXamarin", "SacsMobileXamarin\SacsMobileXamarin.csproj", "{8DB58994-2E78-4F87-8630-63A3C7F5D8BD}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SacsMobileMaui", "SacsMobileMaui\SacsMobileMaui.csproj", "{F167BCF8-8B99-4103-A710-D4B8FD5518A7}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -36,10 +38,6 @@ Global
|
|||||||
{14768EB5-6FA5-4F62-9347-44A667A760C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{14768EB5-6FA5-4F62-9347-44A667A760C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{14768EB5-6FA5-4F62-9347-44A667A760C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{14768EB5-6FA5-4F62-9347-44A667A760C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{14768EB5-6FA5-4F62-9347-44A667A760C1}.Release|Any CPU.Build.0 = Release|Any CPU
|
{14768EB5-6FA5-4F62-9347-44A667A760C1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{E507AB63-28E3-4FF4-9EA8-2E87C42FFC20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{E507AB63-28E3-4FF4-9EA8-2E87C42FFC20}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{E507AB63-28E3-4FF4-9EA8-2E87C42FFC20}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{E507AB63-28E3-4FF4-9EA8-2E87C42FFC20}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{AE8FCC39-D13D-4E32-995E-C69352F9F95E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{AE8FCC39-D13D-4E32-995E-C69352F9F95E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{AE8FCC39-D13D-4E32-995E-C69352F9F95E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{AE8FCC39-D13D-4E32-995E-C69352F9F95E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{AE8FCC39-D13D-4E32-995E-C69352F9F95E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{AE8FCC39-D13D-4E32-995E-C69352F9F95E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@@ -56,6 +54,14 @@ Global
|
|||||||
{3988EE9F-FFCD-481A-AF5E-AA7E5DB5A415}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{3988EE9F-FFCD-481A-AF5E-AA7E5DB5A415}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{3988EE9F-FFCD-481A-AF5E-AA7E5DB5A415}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{3988EE9F-FFCD-481A-AF5E-AA7E5DB5A415}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{3988EE9F-FFCD-481A-AF5E-AA7E5DB5A415}.Release|Any CPU.Build.0 = Release|Any CPU
|
{3988EE9F-FFCD-481A-AF5E-AA7E5DB5A415}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{8DB58994-2E78-4F87-8630-63A3C7F5D8BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{8DB58994-2E78-4F87-8630-63A3C7F5D8BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{8DB58994-2E78-4F87-8630-63A3C7F5D8BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{8DB58994-2E78-4F87-8630-63A3C7F5D8BD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{F167BCF8-8B99-4103-A710-D4B8FD5518A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{F167BCF8-8B99-4103-A710-D4B8FD5518A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{F167BCF8-8B99-4103-A710-D4B8FD5518A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{F167BCF8-8B99-4103-A710-D4B8FD5518A7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
<ProjectReference Include="..\SacsStandardAccounts\SacsStandardAccounts.csproj" />
|
<ProjectReference Include="..\SacsStandardAccounts\SacsStandardAccounts.csproj" />
|
||||||
<ProjectReference Include="..\SacsStandardBase\SacsStandardBase.csproj" />
|
<ProjectReference Include="..\SacsStandardBase\SacsStandardBase.csproj" />
|
||||||
<ProjectReference Include="..\SacsStandardDbas\SacsStandardDbas.csproj" />
|
<ProjectReference Include="..\SacsStandardDbas\SacsStandardDbas.csproj" />
|
||||||
<ProjectReference Include="..\SacsStandardMob\SacsStandardMob.csproj" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -8,12 +8,51 @@ namespace Sacs.UnitTests.Net.Standard.Base.Generic
|
|||||||
{
|
{
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Data members.
|
// Data members.
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Regex_FolderPaths()
|
public void Regex_FolderPaths()
|
||||||
{
|
{
|
||||||
Assert.AreEqual(true, Regex.IsMatch("abcabcabc\\.metadata\\.plugins\\abcabcabc", ".*?\\\\\\.metadata\\\\\\.plugins\\\\.*?"));
|
Assert.AreEqual(true, Regex.IsMatch("abcabcabc\\.metadata\\.plugins\\abcabcabc", ".*?\\\\\\.metadata\\\\\\.plugins\\\\.*?"));
|
||||||
|
|
||||||
|
// Path ends in.
|
||||||
|
Assert.AreEqual(true, Regex.IsMatch("D:\\Home\\Data\\Logs\\App", "[\\\\/]app$", RegexOptions.IgnoreCase));
|
||||||
|
Assert.AreEqual(true, Regex.IsMatch("/home/data/logs/app", "[\\\\/]app$", RegexOptions.IgnoreCase));
|
||||||
|
|
||||||
|
// Path doesn't end in.
|
||||||
|
Assert.AreEqual(false, Regex.IsMatch("D:\\Home\\Data\\Logs", "[\\\\/]app$", RegexOptions.IgnoreCase));
|
||||||
|
Assert.AreEqual(false, Regex.IsMatch("/home/data/logs", "[\\\\/]app$", RegexOptions.IgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
[TestMethod]
|
||||||
|
public void Regex_IsMatch()
|
||||||
|
{
|
||||||
|
string input = "abcdefghi";
|
||||||
|
|
||||||
|
Assert.AreEqual(true, Regex.IsMatch(input, "a"));
|
||||||
|
Assert.AreEqual(true, Regex.IsMatch(input, "^a"));
|
||||||
|
Assert.AreEqual(true, Regex.IsMatch(input, "d"));
|
||||||
|
Assert.AreEqual(true, Regex.IsMatch(input, "i$"));
|
||||||
|
|
||||||
|
// Combination characters.
|
||||||
|
Assert.AreEqual(true, Regex.IsMatch(input, "[adg]"));
|
||||||
|
Assert.AreEqual(true, Regex.IsMatch(input, "[cba]"));
|
||||||
|
|
||||||
|
// Blank matches input.
|
||||||
|
Assert.AreEqual(true, Regex.IsMatch(input, ""));
|
||||||
|
|
||||||
|
// Characters at incorrect position.
|
||||||
|
Assert.AreEqual(false, Regex.IsMatch(input, "a$"));
|
||||||
|
Assert.AreEqual(false, Regex.IsMatch(input, "^d"));
|
||||||
|
Assert.AreEqual(false, Regex.IsMatch(input, "d$"));
|
||||||
|
Assert.AreEqual(false, Regex.IsMatch(input, "^i"));
|
||||||
|
|
||||||
|
// Incorrect characters.
|
||||||
|
Assert.AreEqual(false, Regex.IsMatch(input, "j"));
|
||||||
|
Assert.AreEqual(false, Regex.IsMatch(input, " "));
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ namespace Sacs.Web.Components
|
|||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Properties.
|
// Properties.
|
||||||
private static String ClassName { get; } = nameof(SaController);
|
|
||||||
public DateTime CreatedAt { get; } = DateTime.Now;
|
public DateTime CreatedAt { get; } = DateTime.Now;
|
||||||
public bool DebugMode { get; } = SacsSystem.DebugMode;
|
public bool DebugMode { get; } = SacsSystem.DebugMode;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -125,7 +124,6 @@ namespace Sacs.Web.Components
|
|||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
public static String EncryptParameters(NameValueCollection parameters, String base64IV, String base64Key)
|
public static String EncryptParameters(NameValueCollection parameters, String base64IV, String base64Key)
|
||||||
{
|
{
|
||||||
String fn = ClassName + ".EncryptParameters";
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Copy the list of parameters and sort the keys.
|
// Copy the list of parameters and sort the keys.
|
||||||
@@ -140,22 +138,21 @@ namespace Sacs.Web.Components
|
|||||||
|
|
||||||
// Encrypt data.
|
// Encrypt data.
|
||||||
String encrypted = SacsEncryptionHelper.Encrypt(queryString, base64IV, base64Key);
|
String encrypted = SacsEncryptionHelper.Encrypt(queryString, base64IV, base64Key);
|
||||||
//if (SacsSystem.DebugMode) SaLogger.Debug(fn + "\n\tData: " + queryString + " \n\tEncrypted: " + encrypted);
|
//if (SacsSystem.DebugMode) SaLogger.Debug(SysUtil.Fn + "\n\tData: " + queryString + " \n\tEncrypted: " + encrypted);
|
||||||
return encrypted;
|
return encrypted;
|
||||||
}
|
}
|
||||||
catch (Exception exc) { SaLogger.Warn(fn + " " + ExceptionUtil.GetErrorStateMessage(exc)); }
|
catch (Exception exc) { SaLogger.Warn(SysUtil.Fn + " " + ExceptionUtil.GetErrorStateMessage(exc)); }
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
public static NameValueCollection DecryptParameters(String encrypted, String base64IV, String base64Key)
|
public static NameValueCollection DecryptParameters(String encrypted, String base64IV, String base64Key)
|
||||||
{
|
{
|
||||||
String fn = ClassName + ".DecryptParameters";
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String queryString = SacsEncryptionHelper.Decrypt(encrypted, base64IV, base64Key);
|
String queryString = SacsEncryptionHelper.Decrypt(encrypted, base64IV, base64Key);
|
||||||
//if (SacsSystem.DebugMode) SaLogger.Debug(fn + " \n\tEncrypted: " + encrypted + "\n\tData: " + queryString);
|
//if (SacsSystem.DebugMode) SaLogger.Debug(SysUtil.Fn + " \n\tEncrypted: " + encrypted + "\n\tData: " + queryString);
|
||||||
return HttpUtility.ParseQueryString(queryString);
|
return HttpUtility.ParseQueryString(queryString);
|
||||||
}
|
}
|
||||||
catch (Exception exc) { SaLogger.Warn(fn + " " + ExceptionUtil.GetErrorStateMessage(exc)); }
|
catch (Exception exc) { SaLogger.Warn(SysUtil.Fn + " " + ExceptionUtil.GetErrorStateMessage(exc)); }
|
||||||
return new NameValueCollection();
|
return new NameValueCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +233,7 @@ namespace Sacs.Web.Components
|
|||||||
public MessageData Message { get; private set; }
|
public MessageData Message { get; private set; }
|
||||||
public AjaxResponse_Base SetMessage(String title, String text)
|
public AjaxResponse_Base SetMessage(String title, String text)
|
||||||
{
|
{
|
||||||
if (!StringUtil.IsEmpty(text))
|
if (!StringUtil.IsBlank(text))
|
||||||
Message = new MessageData() { Title = title, Text = text };
|
Message = new MessageData() { Title = title, Text = text };
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -368,7 +365,7 @@ namespace Sacs.Web.Components
|
|||||||
{
|
{
|
||||||
foreach (FormControlValue controlValue in controlValues.Values)
|
foreach (FormControlValue controlValue in controlValues.Values)
|
||||||
{
|
{
|
||||||
if (!StringUtil.IsEmpty(controlValue.Error)) return true;
|
if (!StringUtil.IsBlank(controlValue.Error)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
//=======================================================================
|
||||||
|
}
|
||||||
+13
-13
@@ -1,13 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Templates
|
namespace Sarand.Net.Mobile.Maui.Layouts
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxGrid : Grid
|
public class SamGrid : Grid
|
||||||
{
|
{
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Definitions.
|
// Definitions.
|
||||||
@@ -17,7 +18,7 @@ namespace Sarand.Net.Standard.Mobile.Forms.Templates
|
|||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Construction.
|
// Construction.
|
||||||
public SaxGrid ()
|
public SamGrid()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,32 +33,31 @@ namespace Sarand.Net.Standard.Mobile.Forms.Templates
|
|||||||
base.OnParentSet();
|
base.OnParentSet();
|
||||||
}
|
}
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
protected override void OnPropertyChanging ([CallerMemberName] string propertyName = null)
|
protected override void OnPropertyChanging([CallerMemberName] string propertyName = "")
|
||||||
{
|
{
|
||||||
base.OnPropertyChanging(propertyName);
|
base.OnPropertyChanging(propertyName);
|
||||||
}
|
}
|
||||||
protected override void OnPropertyChanged ([CallerMemberName] string propertyName = null)
|
protected override void OnPropertyChanged([CallerMemberName] string propertyName = "")
|
||||||
{
|
{
|
||||||
base.OnPropertyChanged(propertyName);
|
base.OnPropertyChanged(propertyName);
|
||||||
}
|
}
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
protected override void OnAdded (View view)
|
protected override void OnAdd(int index, IView view)
|
||||||
{
|
{
|
||||||
base.OnAdded(view);
|
base.OnAdd(index, view);
|
||||||
}
|
}
|
||||||
protected override void OnChildAdded(Element child)
|
protected override void OnChildAdded(Element child)
|
||||||
{
|
{
|
||||||
base.OnChildAdded(child);
|
base.OnChildAdded(child);
|
||||||
}
|
}
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
protected override void OnRemoved (View view)
|
protected override void OnRemove(int index, IView view)
|
||||||
{
|
{
|
||||||
base.OnRemoved(view);
|
base.OnRemove(index, view);
|
||||||
}
|
}
|
||||||
[Obsolete("OnChildRemoved(Element) is obsolete as of version 4.8.0. Please use OnChildRemoved(Element, int) instead.")]
|
protected override void OnChildRemoved(Element child, int oldLogicalIndex)
|
||||||
protected override void OnChildRemoved (Element child)
|
|
||||||
{
|
{
|
||||||
base.OnChildRemoved(child);
|
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>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<RootNamespace>Sarand.Net.Standard</RootNamespace>
|
<RootNamespace>Sarand.Net.Mobile</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
+2
-1
@@ -6,7 +6,7 @@ using System.Text;
|
|||||||
using Xamarin.Essentials;
|
using Xamarin.Essentials;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.App
|
namespace Sarand.Net.Mobile.Xamarin.App
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public abstract class SaxApplication : Application
|
public abstract class SaxApplication : Application
|
||||||
@@ -36,6 +36,7 @@ namespace Sarand.Net.Standard.Mobile.App
|
|||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Properties.
|
// Properties.
|
||||||
|
|
||||||
// Device screen size and orientation.
|
// Device screen size and orientation.
|
||||||
public static bool Landscape => DeviceWidth > DeviceHeight;
|
public static bool Landscape => DeviceWidth > DeviceHeight;
|
||||||
public static double DeviceWidth => DeviceDisplay.MainDisplayInfo.Width;
|
public static double DeviceWidth => DeviceDisplay.MainDisplayInfo.Width;
|
||||||
+1
-1
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Base
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Base
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxComponents
|
public class SaxComponents
|
||||||
+1
-1
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Controls
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxButton : Button
|
public class SaxButton : Button
|
||||||
+3
-3
@@ -1,13 +1,13 @@
|
|||||||
using Sarand.Net.Standard.Base.Core;
|
using Sarand.Net.Standard.Base.Core;
|
||||||
using Sarand.Net.Standard.Base.Utils;
|
using Sarand.Net.Standard.Base.Utils;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Layouts;
|
using Sarand.Net.Mobile.Xamarin.Forms.Layouts;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Views;
|
using Sarand.Net.Mobile.Xamarin.Forms.Views;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Controls
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxDatePicker : SaxContentView
|
public class SaxDatePicker : SaxContentView
|
||||||
+4
-4
@@ -1,14 +1,14 @@
|
|||||||
using Sarand.Net.Standard.Base.Core;
|
using Sarand.Net.Standard.Base.Core;
|
||||||
using Sarand.Net.Standard.Base.Utils;
|
using Sarand.Net.Standard.Base.Utils;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Layouts;
|
using Sarand.Net.Mobile.Xamarin.Forms.Layouts;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Views;
|
using Sarand.Net.Mobile.Xamarin.Forms.Views;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Controls
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxDateTimePicker : SaxContentView
|
public class SaxDateTimePicker : SaxContentView
|
||||||
@@ -16,7 +16,7 @@ namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
|||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Definitions.
|
// Definitions.
|
||||||
// Control layout.
|
// Control layout.
|
||||||
private SaxStackLayout layoutControl = new SaxStackLayout() { Orientation = Xamarin.Forms.StackOrientation.Horizontal };
|
private SaxStackLayout layoutControl = new SaxStackLayout() { Orientation = StackOrientation.Horizontal };
|
||||||
private SaxDatePicker pickerDate = new SaxDatePicker();
|
private SaxDatePicker pickerDate = new SaxDatePicker();
|
||||||
private SaxLabel labelTimePrefix = new SaxLabel();
|
private SaxLabel labelTimePrefix = new SaxLabel();
|
||||||
private SaxTimePicker pickerTime = new SaxTimePicker();
|
private SaxTimePicker pickerTime = new SaxTimePicker();
|
||||||
+1
-1
@@ -6,7 +6,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Controls
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxEditor : Editor
|
public class SaxEditor : Editor
|
||||||
+1
-1
@@ -7,7 +7,7 @@ using System.Globalization;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Controls
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxEntry : Entry
|
public class SaxEntry : Entry
|
||||||
+1
-1
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Controls
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxImageButton : ImageButton
|
public class SaxImageButton : ImageButton
|
||||||
+1
-1
@@ -4,7 +4,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Controls
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxLabel : Label
|
public class SaxLabel : Label
|
||||||
+11
-11
@@ -6,14 +6,14 @@ using System.Text;
|
|||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Sarand.Net.Standard.Base.Utils;
|
using Sarand.Net.Standard.Base.Utils;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Controls
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxPicker : Picker
|
public class SaxPicker : Picker
|
||||||
{
|
{
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Definitions.
|
// Definitions.
|
||||||
public class SlmPickerItem
|
public class SaxPickerItem
|
||||||
{
|
{
|
||||||
public SysId Id { get; set; } = new SysId();
|
public SysId Id { get; set; } = new SysId();
|
||||||
public String Code { get; set; } = "";
|
public String Code { get; set; } = "";
|
||||||
@@ -27,7 +27,7 @@ namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
|||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Data members.
|
// Data members.
|
||||||
private readonly List<SlmPickerItem> pickerItems = new List<SlmPickerItem>();
|
private readonly List<SaxPickerItem> pickerItems = new List<SaxPickerItem>();
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Construction.
|
// Construction.
|
||||||
@@ -69,7 +69,7 @@ namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
|||||||
pickerItems.Clear();
|
pickerItems.Clear();
|
||||||
}
|
}
|
||||||
/// <summary>Replace existing picker item list.</summary>
|
/// <summary>Replace existing picker item list.</summary>
|
||||||
public void SetItems (List<SlmPickerItem> pickerItems)
|
public void SetItems (List<SaxPickerItem> pickerItems)
|
||||||
{
|
{
|
||||||
ClearItems();
|
ClearItems();
|
||||||
this.pickerItems.AddRange(pickerItems);
|
this.pickerItems.AddRange(pickerItems);
|
||||||
@@ -83,7 +83,7 @@ namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
|||||||
public bool AddItem (SysId id, String caption)
|
public bool AddItem (SysId id, String caption)
|
||||||
{
|
{
|
||||||
if (ContainsItemId(id)) return false;
|
if (ContainsItemId(id)) return false;
|
||||||
pickerItems.Add(new SlmPickerItem() { Id = id, Caption = caption });
|
pickerItems.Add(new SaxPickerItem() { Id = id, Caption = caption });
|
||||||
RefreshPickerItems();
|
RefreshPickerItems();
|
||||||
return ContainsItemId(id);
|
return ContainsItemId(id);
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
|||||||
public bool AddItem (String code, String caption)
|
public bool AddItem (String code, String caption)
|
||||||
{
|
{
|
||||||
if (ContainsItemCode(code)) return false;
|
if (ContainsItemCode(code)) return false;
|
||||||
pickerItems.Add(new SlmPickerItem() { Code = code, Caption = caption });
|
pickerItems.Add(new SaxPickerItem() { Code = code, Caption = caption });
|
||||||
RefreshPickerItems();
|
RefreshPickerItems();
|
||||||
return ContainsItemCode(code);
|
return ContainsItemCode(code);
|
||||||
}
|
}
|
||||||
@@ -112,13 +112,13 @@ namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
|||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// I t e m S e l e c t i o n
|
// I t e m S e l e c t i o n
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
public SlmPickerItem SelectedPickerItem
|
public SaxPickerItem SelectedPickerItem
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
object selectedItem = SelectedItem;
|
object selectedItem = SelectedItem;
|
||||||
if (selectedItem == null || !(selectedItem is SlmPickerItem)) return null;
|
if (selectedItem == null || !(selectedItem is SaxPickerItem)) return null;
|
||||||
return (selectedItem as SlmPickerItem);
|
return (selectedItem as SaxPickerItem);
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
@@ -131,7 +131,7 @@ namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
SlmPickerItem selectedPickerItem = SelectedPickerItem;
|
SaxPickerItem selectedPickerItem = SelectedPickerItem;
|
||||||
return selectedPickerItem != null ? selectedPickerItem.Id : new SysId();
|
return selectedPickerItem != null ? selectedPickerItem.Id : new SysId();
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
@@ -143,7 +143,7 @@ namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
SlmPickerItem selectedPickerItem = SelectedPickerItem;
|
SaxPickerItem selectedPickerItem = SelectedPickerItem;
|
||||||
return selectedPickerItem != null ? selectedPickerItem.Code : "";
|
return selectedPickerItem != null ? selectedPickerItem.Code : "";
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
+4
-4
@@ -1,12 +1,12 @@
|
|||||||
using Sarand.Net.Standard.Mobile.Forms.Layouts;
|
using Sarand.Net.Mobile.Xamarin.Forms.Layouts;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Panels;
|
using Sarand.Net.Mobile.Xamarin.Forms.Panels;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Views;
|
using Sarand.Net.Mobile.Xamarin.Forms.Views;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Controls
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxTabControl : ContentView
|
public class SaxTabControl : ContentView
|
||||||
+1
-1
@@ -6,7 +6,7 @@ using System.Runtime.CompilerServices;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Controls
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxTimePicker : TimePicker
|
public class SaxTimePicker : TimePicker
|
||||||
+1
-1
@@ -6,7 +6,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Controls
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Controls
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxWebView : WebView
|
public class SaxWebView : WebView
|
||||||
+1
-1
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Layouts
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Layouts
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxAbsoluteLayout : AbsoluteLayout
|
public class SaxAbsoluteLayout : AbsoluteLayout
|
||||||
+1
-1
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Layouts
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Layouts
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxFlexLayout : FlexLayout
|
public class SaxFlexLayout : FlexLayout
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Layouts
|
||||||
|
{
|
||||||
|
//=======================================================================
|
||||||
|
public class SaxGrid : Grid
|
||||||
|
{
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Definitions.
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Data members.
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Construction.
|
||||||
|
public SaxGrid()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Properties.
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// G r i d E v e n t s
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
protected override void OnParentSet()
|
||||||
|
{
|
||||||
|
base.OnParentSet();
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
protected override void OnPropertyChanging([CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
base.OnPropertyChanging(propertyName);
|
||||||
|
}
|
||||||
|
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
base.OnPropertyChanged(propertyName);
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
protected override void OnAdded(View view)
|
||||||
|
{
|
||||||
|
base.OnAdded(view);
|
||||||
|
}
|
||||||
|
protected override void OnChildAdded(Element child)
|
||||||
|
{
|
||||||
|
base.OnChildAdded(child);
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
protected override void OnRemoved(View view)
|
||||||
|
{
|
||||||
|
base.OnRemoved(view);
|
||||||
|
}
|
||||||
|
[Obsolete("OnChildRemoved(Element) is obsolete as of version 4.8.0. Please use OnChildRemoved(Element, int) instead.")]
|
||||||
|
protected override void OnChildRemoved(Element child)
|
||||||
|
{
|
||||||
|
base.OnChildRemoved(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
//=======================================================================
|
||||||
|
}
|
||||||
+1
-1
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Layouts
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Layouts
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxStackLayout : StackLayout
|
public class SaxStackLayout : StackLayout
|
||||||
+1
-1
@@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Layouts
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Layouts
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
/// <summary>
|
/// <summary>
|
||||||
+1
-1
@@ -8,7 +8,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Pages
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Pages
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public abstract class SaxContentPage : ContentPage
|
public abstract class SaxContentPage : ContentPage
|
||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
using Sarand.Net.Standard.Mobile.Forms.Views;
|
using Sarand.Net.Mobile.Xamarin.Forms.Views;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -7,7 +7,7 @@ using System.Text;
|
|||||||
|
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Panels
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxPanel : SaxContentView
|
public class SaxPanel : SaxContentView
|
||||||
+3
-4
@@ -1,12 +1,11 @@
|
|||||||
using Sarand.Net.Standard.Mobile.Forms.Controls;
|
using Sarand.Net.Mobile.Xamarin.Forms.Controls;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Layouts;
|
using Sarand.Net.Mobile.Xamarin.Forms.Layouts;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Templates;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Panels
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SacsFilterPropertyType
|
public class SacsFilterPropertyType
|
||||||
+3
-3
@@ -1,13 +1,13 @@
|
|||||||
using Sarand.Net.Standard.Base.Core;
|
using Sarand.Net.Standard.Base.Core;
|
||||||
using Sarand.Net.Standard.Base.Utils;
|
using Sarand.Net.Standard.Base.Utils;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Controls;
|
using Sarand.Net.Mobile.Xamarin.Forms.Controls;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Templates;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
using Sarand.Net.Mobile.Xamarin.Forms.Layouts;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Panels
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxPanel_ItemFilterProperty : SaxPanel
|
public class SaxPanel_ItemFilterProperty : SaxPanel
|
||||||
+15
-14
@@ -3,16 +3,16 @@ using Sarand.Net.Standard.Base.Core;
|
|||||||
using Sarand.Net.Standard.Base.Dbas;
|
using Sarand.Net.Standard.Base.Dbas;
|
||||||
using Sarand.Net.Standard.Base.Helpers;
|
using Sarand.Net.Standard.Base.Helpers;
|
||||||
using Sarand.Net.Standard.Base.Utils;
|
using Sarand.Net.Standard.Base.Utils;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Controls;
|
using Sarand.Net.Mobile.Xamarin.Forms.Controls;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Layouts;
|
using Sarand.Net.Mobile.Xamarin.Forms.Layouts;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Views;
|
using Sarand.Net.Mobile.Xamarin.Forms.Views;
|
||||||
using Sarand.Net.Standard.Mobile.Utils;
|
using Sarand.Net.Mobile.Xamarin.Utils;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Panels
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxPanel_ItemListHeader : SaxPanel
|
public class SaxPanel_ItemListHeader : SaxPanel
|
||||||
@@ -21,7 +21,7 @@ namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
|||||||
// Definitions.
|
// Definitions.
|
||||||
public class Config
|
public class Config
|
||||||
{
|
{
|
||||||
public Thickness Margin { get; set; } = new Thickness(0, 0, 0, 8);
|
public Thickness? Margin { get; set; } = new Thickness(0, 0, 0, 8);
|
||||||
public String Caption { get; set; }
|
public String Caption { get; set; }
|
||||||
public double HeaderBorderWidth { get; set; } = 4.0;
|
public double HeaderBorderWidth { get; set; } = 4.0;
|
||||||
public float HeaderBorderRadius { get; set; } = 8.0f;
|
public float HeaderBorderRadius { get; set; } = 8.0f;
|
||||||
@@ -31,7 +31,7 @@ namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
|||||||
// Styling.
|
// Styling.
|
||||||
public double CaptionLabelFontSizeRatio { get; set; } = 1.0;
|
public double CaptionLabelFontSizeRatio { get; set; } = 1.0;
|
||||||
public double PagingLabelFontSizeRatio { get; set; } = 1.0;
|
public double PagingLabelFontSizeRatio { get; set; } = 1.0;
|
||||||
public Thickness LabelMargin { get; set; }
|
public Thickness? LabelMargin { get; set; } = null;
|
||||||
// Paging controls.
|
// Paging controls.
|
||||||
public static int PagingButtonWidthMin { get; } = 40;
|
public static int PagingButtonWidthMin { get; } = 40;
|
||||||
public static int PagingButtonWidthMax { get; } = 64;
|
public static int PagingButtonWidthMax { get; } = 64;
|
||||||
@@ -150,7 +150,8 @@ namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
|||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
private void ConfigurePanel()
|
private void ConfigurePanel()
|
||||||
{
|
{
|
||||||
frame.Margin = config.Margin;
|
if (config.Margin != null)
|
||||||
|
frame.Margin = (Thickness)config.Margin;
|
||||||
|
|
||||||
// Header.
|
// Header.
|
||||||
labelCaption.Text = StringUtil.EmptyOnNull(config.Caption);
|
labelCaption.Text = StringUtil.EmptyOnNull(config.Caption);
|
||||||
@@ -164,21 +165,21 @@ namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
|||||||
labelPaging.FontSize = initialLabelFontSize * config.PagingLabelFontSizeRatio;
|
labelPaging.FontSize = initialLabelFontSize * config.PagingLabelFontSizeRatio;
|
||||||
if (config.LabelMargin != null)
|
if (config.LabelMargin != null)
|
||||||
{
|
{
|
||||||
labelCaption.Margin = config.LabelMargin;
|
labelCaption.Margin = (Thickness)config.LabelMargin;
|
||||||
labelPaging.Margin = config.LabelMargin;
|
labelPaging.Margin = (Thickness)config.LabelMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paging controls.
|
// Paging controls.
|
||||||
buttonPagingFirst.Source = SacsImageUtils.GetImageFromByteArray(SacsResourceHelper.GetImageResource(SacsResourceHelper.ImageResource.Arrow_Left_Double_Black_24_png));
|
buttonPagingFirst.Source = SacsImageUtils.GetImageFromByteArray(SacsResourceHelper.GetResourceImage(SacsResourceHelper.ImageResource.Arrow_Left_Double_Black_24_png));
|
||||||
buttonPagingFirst.WidthRequest = Math.Max(Config.PagingButtonWidthMin, Math.Min(Config.PagingButtonWidthMax, config.PagingButtonWidth));
|
buttonPagingFirst.WidthRequest = Math.Max(Config.PagingButtonWidthMin, Math.Min(Config.PagingButtonWidthMax, config.PagingButtonWidth));
|
||||||
buttonPagingFirst.HeightRequest = Math.Max(Config.PagingButtonHeightMin, Math.Min(Config.PagingButtonHeightMax, config.PagingButtonHeight));
|
buttonPagingFirst.HeightRequest = Math.Max(Config.PagingButtonHeightMin, Math.Min(Config.PagingButtonHeightMax, config.PagingButtonHeight));
|
||||||
buttonPagingPrev.Source = SacsImageUtils.GetImageFromByteArray(SacsResourceHelper.GetImageResource(SacsResourceHelper.ImageResource.Arrow_Left_Black_24_png));
|
buttonPagingPrev.Source = SacsImageUtils.GetImageFromByteArray(SacsResourceHelper.GetResourceImage(SacsResourceHelper.ImageResource.Arrow_Left_Black_24_png));
|
||||||
buttonPagingPrev.WidthRequest = Math.Max(Config.PagingButtonWidthMin, Math.Min(Config.PagingButtonWidthMax, config.PagingButtonWidth));
|
buttonPagingPrev.WidthRequest = Math.Max(Config.PagingButtonWidthMin, Math.Min(Config.PagingButtonWidthMax, config.PagingButtonWidth));
|
||||||
buttonPagingPrev.HeightRequest = Math.Max(Config.PagingButtonHeightMin, Math.Min(Config.PagingButtonHeightMax, config.PagingButtonHeight));
|
buttonPagingPrev.HeightRequest = Math.Max(Config.PagingButtonHeightMin, Math.Min(Config.PagingButtonHeightMax, config.PagingButtonHeight));
|
||||||
buttonPagingNext.Source = SacsImageUtils.GetImageFromByteArray(SacsResourceHelper.GetImageResource(SacsResourceHelper.ImageResource.Arrow_Right_Black_24_png));
|
buttonPagingNext.Source = SacsImageUtils.GetImageFromByteArray(SacsResourceHelper.GetResourceImage(SacsResourceHelper.ImageResource.Arrow_Right_Black_24_png));
|
||||||
buttonPagingNext.WidthRequest = Math.Max(Config.PagingButtonWidthMin, Math.Min(Config.PagingButtonWidthMax, config.PagingButtonWidth));
|
buttonPagingNext.WidthRequest = Math.Max(Config.PagingButtonWidthMin, Math.Min(Config.PagingButtonWidthMax, config.PagingButtonWidth));
|
||||||
buttonPagingNext.HeightRequest = Math.Max(Config.PagingButtonHeightMin, Math.Min(Config.PagingButtonHeightMax, config.PagingButtonHeight));
|
buttonPagingNext.HeightRequest = Math.Max(Config.PagingButtonHeightMin, Math.Min(Config.PagingButtonHeightMax, config.PagingButtonHeight));
|
||||||
buttonPagingLast.Source = SacsImageUtils.GetImageFromByteArray(SacsResourceHelper.GetImageResource(SacsResourceHelper.ImageResource.Arrow_Right_Double_Black_24_png));
|
buttonPagingLast.Source = SacsImageUtils.GetImageFromByteArray(SacsResourceHelper.GetResourceImage(SacsResourceHelper.ImageResource.Arrow_Right_Double_Black_24_png));
|
||||||
buttonPagingLast.WidthRequest = Math.Max(Config.PagingButtonWidthMin, Math.Min(Config.PagingButtonWidthMax, config.PagingButtonWidth));
|
buttonPagingLast.WidthRequest = Math.Max(Config.PagingButtonWidthMin, Math.Min(Config.PagingButtonWidthMax, config.PagingButtonWidth));
|
||||||
buttonPagingLast.HeightRequest = Math.Max(Config.PagingButtonHeightMin, Math.Min(Config.PagingButtonHeightMax, config.PagingButtonHeight));
|
buttonPagingLast.HeightRequest = Math.Max(Config.PagingButtonHeightMin, Math.Min(Config.PagingButtonHeightMax, config.PagingButtonHeight));
|
||||||
RefreshPaging();
|
RefreshPaging();
|
||||||
+8
-8
@@ -1,16 +1,16 @@
|
|||||||
using Sarand.Net.Standard.Base.App;
|
using Sarand.Net.Standard.Base.App;
|
||||||
using Sarand.Net.Standard.Base.Core;
|
using Sarand.Net.Standard.Base.Core;
|
||||||
using Sarand.Net.Standard.Base.Helpers;
|
using Sarand.Net.Standard.Base.Helpers;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Controls;
|
using Sarand.Net.Mobile.Xamarin.Forms.Controls;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Layouts;
|
using Sarand.Net.Mobile.Xamarin.Forms.Layouts;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Views;
|
using Sarand.Net.Mobile.Xamarin.Forms.Views;
|
||||||
using Sarand.Net.Standard.Mobile.Utils;
|
using Sarand.Net.Mobile.Xamarin.Utils;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Panels
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -29,11 +29,11 @@ namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
|||||||
private bool showAddButton = false;
|
private bool showAddButton = false;
|
||||||
private double actionButtonSpacing = 4.0;
|
private double actionButtonSpacing = 4.0;
|
||||||
// Panel layout.
|
// Panel layout.
|
||||||
private SaxStackLayout panelLayout = new SaxStackLayout() { Orientation = Xamarin.Forms.StackOrientation.Horizontal };
|
private SaxStackLayout panelLayout = new SaxStackLayout() { Orientation = StackOrientation.Horizontal };
|
||||||
private SaxContentView panelMessage = new SaxContentView();
|
private SaxContentView panelMessage = new SaxContentView();
|
||||||
private SaxLabel labelMessage = new SaxLabel() { HorizontalOptions = LayoutOptions.Start};
|
private SaxLabel labelMessage = new SaxLabel() { HorizontalOptions = LayoutOptions.Start};
|
||||||
// Action butons.
|
// Action butons.
|
||||||
private SaxStackLayout panelActions = new SaxStackLayout() { Orientation = Xamarin.Forms.StackOrientation.Horizontal };
|
private SaxStackLayout panelActions = new SaxStackLayout() { Orientation = StackOrientation.Horizontal };
|
||||||
private SaxImageButton buttonAddItem = new SaxImageButton() { IsVisible = false, HorizontalOptions = LayoutOptions.End, VerticalOptions = LayoutOptions.Start };
|
private SaxImageButton buttonAddItem = new SaxImageButton() { IsVisible = false, HorizontalOptions = LayoutOptions.End, VerticalOptions = LayoutOptions.Start };
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
@@ -61,7 +61,7 @@ namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
|||||||
buttonAddItem.IsVisible = showAddButton;
|
buttonAddItem.IsVisible = showAddButton;
|
||||||
buttonAddItem.Padding = new Thickness(0, 0, actionButtonSpacing, 0);
|
buttonAddItem.Padding = new Thickness(0, 0, actionButtonSpacing, 0);
|
||||||
buttonAddItem.BackgroundColor = Color.Transparent;
|
buttonAddItem.BackgroundColor = Color.Transparent;
|
||||||
buttonAddItem.Source = SacsImageUtils.GetImageFromByteArray(SacsResourceHelper.GetImageResource(SacsResourceHelper.ImageResource.IconShock_Add_Green_72_png));
|
buttonAddItem.Source = SacsImageUtils.GetImageFromByteArray(SacsResourceHelper.GetResourceImage(SacsResourceHelper.ImageResource.IconShock_Add_Green_72_png));
|
||||||
buttonAddItem.Clicked += ButtonAddItem_Clicked;
|
buttonAddItem.Clicked += ButtonAddItem_Clicked;
|
||||||
panelActions.Children.Add(buttonAddItem);
|
panelActions.Children.Add(buttonAddItem);
|
||||||
}
|
}
|
||||||
+5
-4
@@ -1,11 +1,12 @@
|
|||||||
using Sarand.Net.Standard.Base.Core;
|
using Sarand.Net.Standard.Base.Core;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Controls;
|
using Sarand.Net.Mobile.Xamarin.Forms.Controls;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Layouts;
|
using Sarand.Net.Mobile.Xamarin.Forms.Layouts;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Panels
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxPanel_Messages : SaxPanel
|
public class SaxPanel_Messages : SaxPanel
|
||||||
@@ -21,7 +22,7 @@ namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
|||||||
private Config config;
|
private Config config;
|
||||||
private readonly List<SacsMessage> messages = new List<SacsMessage>();
|
private readonly List<SacsMessage> messages = new List<SacsMessage>();
|
||||||
// Components.
|
// Components.
|
||||||
private SaxStackLayout mainLayout = new SaxStackLayout() { Orientation = Xamarin.Forms.StackOrientation.Vertical };
|
private SaxStackLayout mainLayout = new SaxStackLayout() { Orientation = StackOrientation.Vertical };
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Construction.
|
// Construction.
|
||||||
+4
-4
@@ -1,12 +1,12 @@
|
|||||||
using Sarand.Net.Standard.Mobile.Forms.Controls;
|
using Sarand.Net.Mobile.Xamarin.Forms.Controls;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Templates;
|
using Sarand.Net.Mobile.Xamarin.Forms.Layouts;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Views;
|
using Sarand.Net.Mobile.Xamarin.Forms.Views;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Panels
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxPanel_Progress : SaxContentView
|
public class SaxPanel_Progress : SaxContentView
|
||||||
+4
-4
@@ -1,12 +1,12 @@
|
|||||||
using Sarand.Net.Standard.Mobile.Forms.Controls;
|
using Sarand.Net.Mobile.Xamarin.Forms.Controls;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Templates;
|
using Sarand.Net.Mobile.Xamarin.Forms.Layouts;
|
||||||
using Sarand.Net.Standard.Mobile.Forms.Views;
|
using Sarand.Net.Mobile.Xamarin.Forms.Views;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Panels
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxPanel_PropertySummary : SaxContentView
|
public class SaxPanel_PropertySummary : SaxContentView
|
||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
using Sarand.Net.Standard.Mobile.Forms.Views;
|
using Sarand.Net.Mobile.Xamarin.Forms.Views;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Panels
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Panels
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxTabPanel : SaxPanel
|
public class SaxTabPanel : SaxPanel
|
||||||
+2
-2
@@ -1,11 +1,11 @@
|
|||||||
using Sarand.Net.Standard.Mobile.Tasks;
|
using Sarand.Net.Mobile.Xamarin.Tasks;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Utils
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Utils
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public static class SaxFormsUtil
|
public static class SaxFormsUtil
|
||||||
+1
-1
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Utils
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Utils
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public static class SaxPageUtil
|
public static class SaxPageUtil
|
||||||
+1
-1
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Views
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Views
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxBoxView : BoxView
|
public class SaxBoxView : BoxView
|
||||||
+1
-1
@@ -8,7 +8,7 @@ using System.Text;
|
|||||||
|
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Views
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Views
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxContentView : ContentView
|
public class SaxContentView : ContentView
|
||||||
+1
-1
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Views
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Views
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxFrame : Frame
|
public class SaxFrame : Frame
|
||||||
+1
-1
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Forms.Views
|
namespace Sarand.Net.Mobile.Xamarin.Forms.Views
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public class SaxView : View
|
public class SaxView : View
|
||||||
+1
-1
@@ -4,7 +4,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Tasks
|
namespace Sarand.Net.Mobile.Xamarin.Tasks
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public static class SaxThreadUtil
|
public static class SaxThreadUtil
|
||||||
+1
-1
@@ -4,7 +4,7 @@ using System.IO;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Sarand.Net.Standard.Mobile.Utils
|
namespace Sarand.Net.Mobile.Xamarin.Utils
|
||||||
{
|
{
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
public static class SacsImageUtils
|
public static class SacsImageUtils
|
||||||
@@ -45,6 +45,10 @@ namespace Sarand.Net.Standard.Base.Helpers
|
|||||||
IconShock_TrashCan_Grey_72_png,
|
IconShock_TrashCan_Grey_72_png,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Properties.
|
||||||
|
public static Assembly MyAssembly { get; } = typeof(SacsResourceHelper).GetTypeInfo().Assembly;
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// NB 'Properties' not available in Core .Net project.
|
// NB 'Properties' not available in Core .Net project.
|
||||||
// Resources must be loaded via csproj so that they are available in the Manifest Resources:
|
// Resources must be loaded via csproj so that they are available in the Manifest Resources:
|
||||||
@@ -58,7 +62,7 @@ namespace Sarand.Net.Standard.Base.Helpers
|
|||||||
// </ItemGroup>
|
// </ItemGroup>
|
||||||
// REf. https://stackoverflow.com/questions/38762368/embedded-resource-in-net-core-libraries
|
// REf. https://stackoverflow.com/questions/38762368/embedded-resource-in-net-core-libraries
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
public static String GetTextResource(TextResource textResource)
|
public static String GetResourceText(TextResource textResource)
|
||||||
{
|
{
|
||||||
String partialPath = "";
|
String partialPath = "";
|
||||||
String resourceFilename = "";
|
String resourceFilename = "";
|
||||||
@@ -85,18 +89,17 @@ namespace Sarand.Net.Standard.Base.Helpers
|
|||||||
resourceFilename = "jquery-ui-1.12.1.min.js";
|
resourceFilename = "jquery-ui-1.12.1.min.js";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!StringUtil.IsEmpty(resourceFilename))
|
if (!StringUtil.IsBlank(resourceFilename))
|
||||||
{
|
{
|
||||||
var assembly = typeof(SacsResourceHelper).GetTypeInfo().Assembly;
|
String resourceText = GetManifestResourceAsText(MyAssembly, partialPath, resourceFilename);
|
||||||
String resourceText = GetManifestResourceAsText(assembly, partialPath, resourceFilename);
|
if (!StringUtil.IsBlank(resourceText))
|
||||||
if (!StringUtil.IsEmpty(resourceText))
|
|
||||||
return resourceText;
|
return resourceText;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
public static byte[] GetImageResource(ImageResource imageResource)
|
public static byte[] GetResourceImage(ImageResource imageResource)
|
||||||
{
|
{
|
||||||
String partialPath = "";
|
String partialPath = "";
|
||||||
String resourceFilename = "";
|
String resourceFilename = "";
|
||||||
@@ -164,10 +167,9 @@ namespace Sarand.Net.Standard.Base.Helpers
|
|||||||
break;
|
break;
|
||||||
//-----------------------------------------------------------
|
//-----------------------------------------------------------
|
||||||
}
|
}
|
||||||
if (!StringUtil.IsEmpty(resourceFilename))
|
if (!StringUtil.IsBlank(resourceFilename))
|
||||||
{
|
{
|
||||||
var assembly = typeof(SacsResourceHelper).GetTypeInfo().Assembly;
|
byte[] resourceData = GetManifestResourceAsBinary(MyAssembly, partialPath, resourceFilename);
|
||||||
byte[] resourceData = GetManifestResourceAsBinary(assembly, partialPath, resourceFilename);
|
|
||||||
if (resourceData != null)
|
if (resourceData != null)
|
||||||
return resourceData;
|
return resourceData;
|
||||||
}
|
}
|
||||||
@@ -175,11 +177,12 @@ namespace Sarand.Net.Standard.Base.Helpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
|
// Text resources.
|
||||||
|
|
||||||
/// <summary>Retrieve resource as String based on assembly and partial resource name.</summary>
|
/// <summary>Retrieve resource as String based on assembly and partial resource name.</summary>
|
||||||
public static String GetManifestResourceAsText(Assembly assembly, String partialPath, String resourceNameEndsWith)
|
public static String GetManifestResourceAsText(Assembly assembly, String partialPath, String resourceNameEndsWith)
|
||||||
{
|
{
|
||||||
String fn = typeof(SacsResourceHelper).Name + ".GetManifestResourceAsText";
|
if (StringUtil.IsBlank(resourceNameEndsWith)) return "";
|
||||||
if (StringUtil.IsEmpty(resourceNameEndsWith)) return "";
|
|
||||||
|
|
||||||
using (Stream resourceStream = GetManifestResourceStream(assembly, partialPath, resourceNameEndsWith))
|
using (Stream resourceStream = GetManifestResourceStream(assembly, partialPath, resourceNameEndsWith))
|
||||||
{
|
{
|
||||||
@@ -195,12 +198,13 @@ namespace Sarand.Net.Standard.Base.Helpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
|
// Binary resources.
|
||||||
|
|
||||||
/// <summary>Retrieve resource as byte array based on assembly and partial resource name.</summary>
|
/// <summary>Retrieve resource as byte array based on assembly and partial resource name.</summary>
|
||||||
public static byte[] GetManifestResourceAsBinary(Assembly assembly, String partialPath, String resourceNameEndsWith)
|
public static byte[] GetManifestResourceAsBinary(Assembly assembly, String partialPath, String resourceNameEndsWith)
|
||||||
{
|
{
|
||||||
String fn = typeof(SacsResourceHelper).Name + ".GetManifestResourceAsBinary";
|
|
||||||
if (
|
if (
|
||||||
StringUtil.IsEmpty(resourceNameEndsWith)) return null;
|
StringUtil.IsBlank(resourceNameEndsWith)) return null;
|
||||||
using (Stream resourceStream = GetManifestResourceStream(assembly, partialPath, resourceNameEndsWith))
|
using (Stream resourceStream = GetManifestResourceStream(assembly, partialPath, resourceNameEndsWith))
|
||||||
{
|
{
|
||||||
if (resourceStream != null)
|
if (resourceStream != null)
|
||||||
@@ -211,29 +215,36 @@ namespace Sarand.Net.Standard.Base.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SaLogger.Warn(fn + " Failed to locate text resource: " + resourceNameEndsWith);
|
SaLogger.Warn(SysUtil.Fn + " Failed to locate text resource: " + resourceNameEndsWith);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
|
// Resource stream.
|
||||||
|
|
||||||
|
/// <summary>Retrieve resource as stream based on assembly and partial resource name.</summary>
|
||||||
|
public static Stream GetResourceStream(String partialPath, String resourceNameEndsWith)
|
||||||
|
{
|
||||||
|
return GetManifestResourceStream(MyAssembly, partialPath, resourceNameEndsWith);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Retrieve resource as stream based on assembly and partial resource name.</summary>
|
/// <summary>Retrieve resource as stream based on assembly and partial resource name.</summary>
|
||||||
public static Stream GetManifestResourceStream(Assembly assembly, String partialPath, String resourceNameEndsWith)
|
public static Stream GetManifestResourceStream(Assembly assembly, String partialPath, String resourceNameEndsWith)
|
||||||
{
|
{
|
||||||
String fn = typeof(SacsResourceHelper).Name + ".GetManifestResourceStream";
|
//Logger.Debug(SysUtil.Fn + " Manifest resource names: " + new List<String>(assembly.GetManifestResourceNames()).Concat("","\n\t"));
|
||||||
//Logger.Debug(fn + " Manifest resource names: " + new List<String>(assembly.GetManifestResourceNames()).Concat("","\n\t"));
|
|
||||||
foreach (String resourceName in assembly.GetManifestResourceNames())
|
foreach (String resourceName in assembly.GetManifestResourceNames())
|
||||||
{
|
{
|
||||||
//SaLogger.Debug(fn + " Resource: " + resourceName);
|
//SaLogger.Debug(SysUtil.Fn + " Resource: " + resourceName);
|
||||||
|
|
||||||
// Match the partial path.
|
// Match the partial path.
|
||||||
if (!StringUtil.IsEmpty(partialPath) && !resourceName.ContainsCI(partialPath)) continue;
|
if (!StringUtil.IsBlank(partialPath) && !resourceName.ContainsCI(partialPath)) continue;
|
||||||
// Match the resource filename to the end of the resource name - resource names start with default namespace (eg. 'Sarand').
|
// Match the resource filename to the end of the resource name - resource names start with default namespace (eg. 'Sarand').
|
||||||
if (!resourceName.EndsWithCI(resourceNameEndsWith)) continue;
|
if (!resourceName.EndsWithCI(resourceNameEndsWith)) continue;
|
||||||
|
|
||||||
//SaLogger.Debug(fn + " Resource filename: " + resourceNameEndsWith + ". Matched to resource: " + resourceName);
|
//SaLogger.Debug(SysUtil.Fn + " Resource filename: " + resourceNameEndsWith + ". Matched to resource: " + resourceName);
|
||||||
return assembly.GetManifestResourceStream(resourceName);
|
return assembly.GetManifestResourceStream(resourceName);
|
||||||
}
|
}
|
||||||
SaLogger.Warn(fn + " Resource filename not found: " + resourceNameEndsWith);
|
SaLogger.Warn(SysUtil.Fn + " Resource filename not found: " + resourceNameEndsWith);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user