diff --git a/FunctionZero.Maui.Controls/FunctionZero.Maui.Controls.csproj b/FunctionZero.Maui.Controls/FunctionZero.Maui.Controls.csproj index 007fd8e..2dd2a10 100644 --- a/FunctionZero.Maui.Controls/FunctionZero.Maui.Controls.csproj +++ b/FunctionZero.Maui.Controls/FunctionZero.Maui.Controls.csproj @@ -20,16 +20,16 @@ FunctionZero Controls library including TreeViewZero Keith Pickford FunctionZero Ltd - A MAUI Controls library featuring a cross-platform virtualizing TreeView and ListView and a really cool MaskControl and more, for WinUI, iOS, Mac and Android. + A MAUI Controls library featuring a cross-platform virtualizing TreeView and ListView and Expander and a really cool MaskControl and more, for all MAUI platforms. FunctionZero Ltd https://github.com/Keflon/FunctionZero.Maui.Controls https://github.com/Keflon/FunctionZero.Maui.Controls MAUI; ListView; ListViewZero; TreeView; TreeViewZero; MaskView; iOS; WinUI; Windows; Android; Control - MultiViewZero is getting ready for mainstream. + MultiviewZero is stable and outrageously versatile. Localisation has been moved to a new LocalisationZero library. License.md False snupkg - 8.0.0.3-pre3 + 8.0.0.4 F0 gravatar.png @@ -57,9 +57,9 @@ - - - + + + diff --git a/FunctionZero.Maui.Controls/Services/Localisation/BaseLanguageService.cs b/FunctionZero.Maui.Controls/Services/Localisation/BaseLanguageService.cs deleted file mode 100644 index 5727f02..0000000 --- a/FunctionZero.Maui.Controls/Services/Localisation/BaseLanguageService.cs +++ /dev/null @@ -1,86 +0,0 @@ -using FunctionZero.ExpressionParserZero.BackingStore; -using FunctionZero.Maui.MarkupExtensions; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; - -namespace FunctionZero.Maui.Services.Localisation -{ - /// - /// Goal. To be decoupled enough to allow downloading and selection of new or updated language packs on the fly. - /// - public abstract partial class BaseLanguageService : INotifyPropertyChanged where TEnum : Enum - { - private readonly string _resourceKey; - private ResourceDictionary _resourceHost; - private Dictionary _languages; - public event EventHandler LanguageChanged; - - // INPC raised by SetLanguage(..) - public string CurrentLanguageId { get; protected set; } - - - public event PropertyChangedEventHandler PropertyChanged; - - - // TODO: Expose an ObsColl of languages, so the app can e.g. download new language packs and the UI can bind to it all. - public BaseLanguageService(string resourceKey = "languageResource") - { - _resourceKey = resourceKey; - _languages = new(); - } - - public void Init(ResourceDictionary resourceHost, string initialLanguage) - { - _resourceHost = resourceHost; - SetLanguage(initialLanguage); - } - - public void RegisterLanguage(string id, LanguageProvider language) - { - _languages[id] = language; - } - - /// - /// You probably want resourceHost to be 'Application.Current.Resources' - /// - /// - /// - /// - public void SetLanguage(string id) - { - if (_resourceHost == null) - throw new InvalidOperationException("You must call Init on the LanguageService before you call SetLanguage(string id), e.g. Init(Application.Current.Resources);"); - - if (_languages.TryGetValue(id, out var languageService)) - _resourceHost[_resourceKey] = languageService.GetLookup(); - else - throw new Exception($"Register a language before trying to set it. Language: '{id}' "); - - CurrentLanguageId = id; - - LanguageChanged?.Invoke(this, new LanguageChangedEventArgs(id)); - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentLanguageId))); - } - - //public string[] CurrentLookup => _resourceHost[_resourceKey] as string[]; - - public string GetText(TEnum textId, IBackingStore host) - { - var lookup = _languages[CurrentLanguageId].GetLookup()[(int)(object)textId]; - - foreach (var item in lookup) - { - var result = item.Item1.Evaluate(host).Pop(); - if (result.Type == ExpressionParserZero.Operands.OperandType.Bool) - if ((bool)result.GetValue() == true) - return item.Item2; - } - return $"textId {textId} not found."; - } - } -} diff --git a/FunctionZero.Maui.Controls/Services/Localisation/ExpressionString.cs b/FunctionZero.Maui.Controls/Services/Localisation/ExpressionString.cs deleted file mode 100644 index 3bf443b..0000000 --- a/FunctionZero.Maui.Controls/Services/Localisation/ExpressionString.cs +++ /dev/null @@ -1,35 +0,0 @@ -using FunctionZero.ExpressionParserZero.BackingStore; -using FunctionZero.ExpressionParserZero.Evaluator; - -namespace FunctionZero.Maui.Services.Localisation -{ - public class ExpressionString - { - private ExpressionTree _expression; - private readonly string _resultString; - - public ExpressionString(ExpressionTree expression, string resultString) - { - _expression = expression; - _resultString = resultString; - } - - public bool GetString(object backingStore, ref string result) - { - result = _resultString; - - try - { - if (backingStore is IBackingStore pocoBackingStore) - return (bool)_expression.Evaluate(pocoBackingStore).Pop().GetValue(); - else - return (bool)_expression.Evaluate(new PocoBackingStore(backingStore)).Pop().GetValue(); - } - catch(Exception ex) - { - result = ex.Message; - return false; - } - } - } -} \ No newline at end of file diff --git a/FunctionZero.Maui.Controls/Services/Localisation/LanguageChangedEventArgs.cs b/FunctionZero.Maui.Controls/Services/Localisation/LanguageChangedEventArgs.cs deleted file mode 100644 index 596b84d..0000000 --- a/FunctionZero.Maui.Controls/Services/Localisation/LanguageChangedEventArgs.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace FunctionZero.Maui.Services.Localisation -{ - public class LanguageChangedEventArgs : EventArgs - { - public LanguageChangedEventArgs(string languageId) - { - LanguageId = languageId; - } - - public string LanguageId { get; } - } -} \ No newline at end of file diff --git a/FunctionZero.Maui.Controls/Services/Localisation/LanguageProvider.cs b/FunctionZero.Maui.Controls/Services/Localisation/LanguageProvider.cs deleted file mode 100644 index f6cb123..0000000 --- a/FunctionZero.Maui.Controls/Services/Localisation/LanguageProvider.cs +++ /dev/null @@ -1,42 +0,0 @@ -using FunctionZero.ExpressionParserZero.Binding; -using FunctionZero.ExpressionParserZero.Evaluator; - -namespace FunctionZero.Maui.Services.Localisation -{ - public class LanguageProvider - { - private readonly ExpressionTree _trueExpression; - - public LanguageProvider(Func>> getLookup, string languageName) - { - GetLookup = getLookup; - LanguageName = languageName; - } - //item.Add((parser.Parse("true"), "There are loads of bananas!")); - public LanguageProvider(Func> getLookup, string languageName) - { - var parser = ExpressionParserFactory.GetExpressionParser(); - _trueExpression = parser.Parse("true"); - - GetLookup = GetLookupFromStringList(getLookup); - LanguageName = languageName; - } - - private Func>> GetLookupFromStringList(Func> getLookup) - { - List> lookup = new List>(); - foreach (var theString in getLookup()) - { - var item = new List<(ExpressionTree, string)>(); - item.Add((_trueExpression, theString)); - lookup.Add(item); - } - return () => lookup; - } - - - //public Func GetLookup { get; } - public Func>> GetLookup { get; } - public string LanguageName { get; } - } -} diff --git a/SampleApp/App.xaml.cs b/SampleApp/App.xaml.cs index 59c3c72..e40a14f 100644 --- a/SampleApp/App.xaml.cs +++ b/SampleApp/App.xaml.cs @@ -2,7 +2,6 @@ using FunctionZero.Maui.MvvmZero; using Microsoft.Maui.Platform; using SampleApp.Mvvm.PageViewModels; -using SampleApp.Translations; using SampleApp.Widgets; using System.Diagnostics; @@ -10,13 +9,12 @@ namespace SampleApp { public partial class App : Application { - public App(IPageServiceZero pageService, LangService langService) + public App(IPageServiceZero pageService) { var temp = new WidgetContainer("", "", ""); InitializeComponent(); pageService.Init(this); - langService.Init(this.Resources, "english"); // Uses AdaptedFlyoutPage because https://github.com/dotnet/maui/issues/13496 var flyoutPage = pageService.GetFlyoutPage(); diff --git a/SampleApp/MauiProgram.cs b/SampleApp/MauiProgram.cs index b4538ab..5b4393d 100644 --- a/SampleApp/MauiProgram.cs +++ b/SampleApp/MauiProgram.cs @@ -1,26 +1,20 @@ using FunctionZero.ExpressionParserZero.Binding; using FunctionZero.ExpressionParserZero.Evaluator; -using FunctionZero.ExpressionParserZero.Operands; -using FunctionZero.ExpressionParserZero.Parser; using FunctionZero.Maui.Controls; using FunctionZero.Maui.MvvmZero; using FunctionZero.Maui.Services; -using FunctionZero.Maui.Services.Localisation; using SampleApp.Mvvm.Pages; using SampleApp.Mvvm.Pages.Expander; using SampleApp.Mvvm.Pages.List; using SampleApp.Mvvm.Pages.Mask; using SampleApp.Mvvm.Pages.MultiView; -using SampleApp.Mvvm.Pages.Translations; using SampleApp.Mvvm.Pages.Tree; using SampleApp.Mvvm.PageViewModels; using SampleApp.Mvvm.PageViewModels.Expander; using SampleApp.Mvvm.PageViewModels.List; using SampleApp.Mvvm.PageViewModels.Mask; using SampleApp.Mvvm.PageViewModels.MultiView; -using SampleApp.Mvvm.PageViewModels.Translations; using SampleApp.Mvvm.PageViewModels.Tree; -using SampleApp.Translations; namespace SampleApp { @@ -49,7 +43,6 @@ public static MauiApp CreateMauiApp() .MapVmToView() .MapVmToView() .MapVmToView() - .MapVmToView() ; @@ -101,127 +94,10 @@ public static MauiApp CreateMauiApp() .AddSingleton() .AddSingleton() - - .AddSingleton() - .AddSingleton() - - .AddSingleton(GetConfiguredLanguageService) - + ; return builder.Build(); } - - #region Language translation setup - private static LangService GetConfiguredLanguageService(IServiceProvider provider) - { - var translationService = new LangService(); - translationService.RegisterLanguage("english", new LanguageProvider(GetEnglish, "English")); - translationService.RegisterLanguage("german", new LanguageProvider(GetGerman, "Deutsch")); - - return translationService; - } - - // Example - //private static string[] GetEnglish() => new string[] { "Hello", "World", "Welcome to the Moasure Playground!" }; - private static string[] GetGerman() => new string[] { "Bananas", "Hallo", "Welt", "Willkommen auf dem Moasure Spielplatz!" }; - - private static List> GetEnglish() - { - var parser = ExpressionParserFactory.GetExpressionParser(); - var trueExpression = parser.Parse("true"); - - var retval = new List>(); - - { - var item = new List<(ExpressionTree, string)>(); - - item.Add((parser.Parse("NumBananas == 0"), "There are no bananas!")); - item.Add((parser.Parse("NumBananas == 1"), "There is one banana!")); - item.Add((parser.Parse("NumBananas == 2"), "There are two bananas!")); - item.Add((parser.Parse("NumBananas < 10"), "There are {NumBananas} bananas!")); // TODO: {NumBananas} - item.Add((parser.Parse("true"), "There are loads of bananas!")); - - //HashSet dependsOn = new HashSet(); - - //foreach(var tuple in item) - // foreach(var token in tuple.Item1.RpnTokens) - // if(token is Operand op) - // if(op.Type == OperandType.Variable) - // dependsOn.Add((string)op.GetValue()); - - retval.Add(item); - } - { - var item = new List<(ExpressionTree, string)>(); - - item.Add((trueExpression, "Hello!")); - - retval.Add(item); - } - { - var item = new List<(ExpressionTree, string)>(); - - item.Add((trueExpression, "World")); - - retval.Add(item); - } - { - var item = new List<(ExpressionTree, string)>(); - - item.Add((trueExpression, "This is a demonstration of FunctionZero Translation Service")); - - retval.Add(item); - } - - - return retval; - } - - //private static List> GetGerman() - //{ - // var parser = ExpressionParserFactory.GetExpressionParser(); - // var trueExpression = parser.Parse("true"); - - // var retval = new List>(); - - // { - // var item = new List<(ExpressionTree, string)>(); - - // item.Add((parser.Parse("NumBananas == 0"), "Es gibt keine Bananen!")); - // item.Add((parser.Parse("NumBananas == 1"), "Es gibt eine Banane!")); - // item.Add((parser.Parse("NumBananas == 2"), "Es gibt zwei Bananen!")); - // item.Add((parser.Parse("NumBananas < 10"), "Es gibt {NumBananas} Bananen!")); // TODO: {NumBananas} - // item.Add((parser.Parse("true"), "Es gibt jede Menge Bananen!")); - - // retval.Add(item); - // } - // { - // var item = new List<(ExpressionTree, string)>(); - - // item.Add((trueExpression, "Hallo!")); - - // retval.Add(item); - // } - // { - // var item = new List<(ExpressionTree, string)>(); - - // item.Add((trueExpression, "Welt")); - - // retval.Add(item); - // } - // { - // var item = new List<(ExpressionTree, string)>(); - - // item.Add((trueExpression, "Dies ist eine Demonstration des FunctionZero Translation Service")); - - // retval.Add(item); - // } - - - // return retval; - //} - - #endregion } } \ No newline at end of file diff --git a/SampleApp/Mvvm/PageViewModels/AppFlyoutPageVm.cs b/SampleApp/Mvvm/PageViewModels/AppFlyoutPageVm.cs index 65d6d56..238cb66 100644 --- a/SampleApp/Mvvm/PageViewModels/AppFlyoutPageVm.cs +++ b/SampleApp/Mvvm/PageViewModels/AppFlyoutPageVm.cs @@ -4,7 +4,6 @@ using SampleApp.Mvvm.PageViewModels.List; using SampleApp.Mvvm.PageViewModels.Mask; using SampleApp.Mvvm.PageViewModels.MultiView; -using SampleApp.Mvvm.PageViewModels.Translations; using SampleApp.Mvvm.PageViewModels.Tree; using SampleApp.Mvvm.ViewModels; using System; @@ -32,7 +31,6 @@ public enum AppFlyoutItems ExpanderBar, ExpanderBarTest, MultiViewModal, - TranslationHome } @@ -104,9 +102,7 @@ private void ItemTappedCommandExecute(object arg) case AppFlyoutItems.MultiViewModal: _pageService.FlyoutController.SetDetailVm(typeof(MultiViewModalPageVm), true); break; - case AppFlyoutItems.TranslationHome: - _pageService.FlyoutController.SetDetailVm(typeof(TranslationHomePageVm), true); - break; + } } diff --git a/SampleApp/Mvvm/PageViewModels/Translations/TranslationHomePageVm.cs b/SampleApp/Mvvm/PageViewModels/Translations/TranslationHomePageVm.cs deleted file mode 100644 index e12a12b..0000000 --- a/SampleApp/Mvvm/PageViewModels/Translations/TranslationHomePageVm.cs +++ /dev/null @@ -1,61 +0,0 @@ -using FunctionZero.CommandZero; -using FunctionZero.ExpressionParserZero.BackingStore; -using FunctionZero.Maui.MvvmZero; -using FunctionZero.Maui.Services; -using SampleApp.Mvvm.ViewModels; -using SampleApp.Translations; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Input; - -namespace SampleApp.Mvvm.PageViewModels.Translations -{ - public class TranslationHomePageVm : BasePageVm - { - private readonly LangService _langService; - - public ICommand SetLanguageCommand { get; } - public ICommand DoTheThingCommand { get; } - public TranslationHomePageVm(LangService langService) - { - _langService = langService; - - var thisAsPocoBackingStore = new PocoBackingStore(this); - - SetLanguageCommand = new CommandBuilder() - .AddGuard(this) - .SetExecute(SetLanguageCommandExecute) - .Build(); - - DoTheThingCommand = new CommandBuilder() - .AddGuard(this) - .SetExecute(DoTheThingCommandExecute) - .SetName(() => langService.GetText(LangStrings.E_Bananas, thisAsPocoBackingStore)) - .AddObservedProperty(langService, nameof(LangService.CurrentLanguageId)) - .Build(); - - NumBananas = 1; - } - - private int _numBananas; - public int NumBananas - { - get => _numBananas; - set => SetProperty(ref _numBananas, value); - } - - private void DoTheThingCommandExecute() - { - Debug.WriteLine($"New language: {_langService.CurrentLanguageId}"); - } - - private void SetLanguageCommandExecute(object arg) - { - _langService.SetLanguage((string)arg); - } - } -} diff --git a/SampleApp/Mvvm/Pages/AppFlyoutPage.xaml b/SampleApp/Mvvm/Pages/AppFlyoutPage.xaml index 5fb1148..7a68009 100644 --- a/SampleApp/Mvvm/Pages/AppFlyoutPage.xaml +++ b/SampleApp/Mvvm/Pages/AppFlyoutPage.xaml @@ -110,21 +110,7 @@ - - - - - - - - - diff --git a/SampleApp/Mvvm/Pages/Translations/TranslationHomePage.xaml b/SampleApp/Mvvm/Pages/Translations/TranslationHomePage.xaml deleted file mode 100644 index a20f9dc..0000000 --- a/SampleApp/Mvvm/Pages/Translations/TranslationHomePage.xaml +++ /dev/null @@ -1,16 +0,0 @@ - - - - -