diff --git a/Assets/Blazor/MdiHost.gif b/Assets/Blazor/MdiHost.gif index 08fadde1..0db5e25f 100644 Binary files a/Assets/Blazor/MdiHost.gif and b/Assets/Blazor/MdiHost.gif differ diff --git a/src/CodeGenerators/EficazFramework.Generators/EficazFramework.Generators.csproj b/src/CodeGenerators/EficazFramework.Generators/EficazFramework.Generators.csproj index 87e6f84a..a5cd5a7b 100644 --- a/src/CodeGenerators/EficazFramework.Generators/EficazFramework.Generators.csproj +++ b/src/CodeGenerators/EficazFramework.Generators/EficazFramework.Generators.csproj @@ -34,8 +34,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/src/Core/EficazFramework.Collections/EficazFramework.Collections.csproj b/src/Core/EficazFramework.Collections/EficazFramework.Collections.csproj index b2daba91..b6caf2f7 100644 --- a/src/Core/EficazFramework.Collections/EficazFramework.Collections.csproj +++ b/src/Core/EficazFramework.Collections/EficazFramework.Collections.csproj @@ -2,9 +2,9 @@ net6.0;net7.0 - 6.1.5 - 6.1.5.0 - 6.1.5.0 + 6.1.6 + 6.1.6.0 + 6.1.6.0 EficazFramework true EfCore.snk diff --git a/src/Core/EficazFramework.Data/EficazFramework.Data.csproj b/src/Core/EficazFramework.Data/EficazFramework.Data.csproj index da5c6ce8..0533f51c 100644 --- a/src/Core/EficazFramework.Data/EficazFramework.Data.csproj +++ b/src/Core/EficazFramework.Data/EficazFramework.Data.csproj @@ -2,9 +2,9 @@ net6.0;net7.0 - 6.1.5 - 6.1.5.0 - 6.1.5.0 + 6.1.6 + 6.1.6.0 + 6.1.6.0 EficazFramework true EfCore.snk @@ -90,8 +90,8 @@ - - + + all diff --git a/src/Core/EficazFramework.Expressions/EficazFramework.Expressions.csproj b/src/Core/EficazFramework.Expressions/EficazFramework.Expressions.csproj index a75504ec..5839831b 100644 --- a/src/Core/EficazFramework.Expressions/EficazFramework.Expressions.csproj +++ b/src/Core/EficazFramework.Expressions/EficazFramework.Expressions.csproj @@ -2,9 +2,9 @@ net6.0;net7.0 - 6.1.5 - 6.1.5.0 - 6.1.5.0 + 6.1.6 + 6.1.6.0 + 6.1.6.0 EficazFramework true EfCore.snk diff --git a/src/Core/EficazFramework.Utilities/Application/ApplicationDefinition.cs b/src/Core/EficazFramework.Utilities/Application/ApplicationDefinition.cs index 3682ec42..583c530a 100644 --- a/src/Core/EficazFramework.Utilities/Application/ApplicationDefinition.cs +++ b/src/Core/EficazFramework.Utilities/Application/ApplicationDefinition.cs @@ -5,8 +5,6 @@ namespace EficazFramework.Application; public class ApplicationDefinition { - public const string STARTWINDOWSTATE = "StartWindowState"; - // Metadata public string? Title { get; set; } public string? LongTitle { get; set; } diff --git a/src/Core/EficazFramework.Utilities/Application/ApplicationManager.cs b/src/Core/EficazFramework.Utilities/Application/ApplicationManager.cs index 0c5431ee..a2d62e9d 100644 --- a/src/Core/EficazFramework.Utilities/Application/ApplicationManager.cs +++ b/src/Core/EficazFramework.Utilities/Application/ApplicationManager.cs @@ -215,18 +215,7 @@ private void AddTargetProperties(IDictionary sourceTa { foreach (var sourceTarget in sourceTargets) { - ApplicationTarget appTarget = new() - { - Icon = sourceTarget.Value.Icon, - InitialSize = sourceTarget.Value.InitialSize, - SplashScreen = sourceTarget.Value.SplashScreen, - StartupUriOrType = sourceTarget.Value.StartupUriOrType - }; - foreach (var item in sourceTarget.Value.Properties) - { - appTarget.Properties.Add(item.Key, item.Value); - } - Targets.Add(sourceTarget.Key, appTarget); + Targets.Add(sourceTarget); } } diff --git a/src/Core/EficazFramework.Utilities/Application/ApplicationTarget.cs b/src/Core/EficazFramework.Utilities/Application/ApplicationTarget.cs index f2defe85..7c3515ec 100644 --- a/src/Core/EficazFramework.Utilities/Application/ApplicationTarget.cs +++ b/src/Core/EficazFramework.Utilities/Application/ApplicationTarget.cs @@ -9,7 +9,7 @@ namespace EficazFramework.Application; [ExcludeFromCodeCoverage] -public class ApplicationTarget +public abstract class ApplicationTarget { /// /// Informações de inicialização da aplicação @@ -32,7 +32,7 @@ public class ApplicationTarget /// /// Ativo Visual de inicialização/carregamento do aplicativo /// - public Size InitialSize { get; set; } = new(250, 200); + public Size InitialSize { get; set; } = new(425, 200); /// diff --git a/src/Core/EficazFramework.Utilities/EficazFramework.Utilities.csproj b/src/Core/EficazFramework.Utilities/EficazFramework.Utilities.csproj index 4506da18..53aba512 100644 --- a/src/Core/EficazFramework.Utilities/EficazFramework.Utilities.csproj +++ b/src/Core/EficazFramework.Utilities/EficazFramework.Utilities.csproj @@ -2,9 +2,9 @@ net6.0;net7.0 - 6.1.5 - 6.1.5.0 - 6.1.5.0 + 6.1.6 + 6.1.6.0 + 6.1.6.0 enable EficazFramework Eficaz Sistemas @@ -72,7 +72,7 @@ - + diff --git a/src/DataProviders/EficazFramework.Data.InMemory/EficazFramework.Data.InMemory.csproj b/src/DataProviders/EficazFramework.Data.InMemory/EficazFramework.Data.InMemory.csproj index ce5632a4..c7af4514 100644 --- a/src/DataProviders/EficazFramework.Data.InMemory/EficazFramework.Data.InMemory.csproj +++ b/src/DataProviders/EficazFramework.Data.InMemory/EficazFramework.Data.InMemory.csproj @@ -2,9 +2,9 @@ net6.0;net7.0 - 6.1.5 - 6.1.5.0 - 6.1.5.0 + 6.1.6 + 6.1.6.0 + 6.1.6.0 EficazFramework true EfCore.snk @@ -56,7 +56,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/DataProviders/EficazFramework.Data.MsSqlServer/EficazFramework.Data.MsSqlServer.csproj b/src/DataProviders/EficazFramework.Data.MsSqlServer/EficazFramework.Data.MsSqlServer.csproj index abce66d0..1229cb1a 100644 --- a/src/DataProviders/EficazFramework.Data.MsSqlServer/EficazFramework.Data.MsSqlServer.csproj +++ b/src/DataProviders/EficazFramework.Data.MsSqlServer/EficazFramework.Data.MsSqlServer.csproj @@ -2,9 +2,9 @@ net6.0;net7.0 - 6.1.5 - 6.1.5.0 - 6.1.5.0 + 6.1.6 + 6.1.6.0 + 6.1.6.0 EficazFramework true EfCore.snk @@ -56,7 +56,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/DataProviders/EficazFramework.Data.MySql/EficazFramework.Data.MySql.csproj b/src/DataProviders/EficazFramework.Data.MySql/EficazFramework.Data.MySql.csproj index 702ec45f..8e24ce27 100644 --- a/src/DataProviders/EficazFramework.Data.MySql/EficazFramework.Data.MySql.csproj +++ b/src/DataProviders/EficazFramework.Data.MySql/EficazFramework.Data.MySql.csproj @@ -2,9 +2,9 @@ net6.0;net7.0 - 6.1.5 - 6.1.5.0 - 6.1.5.0 + 6.1.6 + 6.1.6.0 + 6.1.6.0 EficazFramework true EfCore.snk @@ -54,7 +54,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/DataProviders/EficazFramework.Data.SqlLite/EficazFramework.Data.SqlLite.csproj b/src/DataProviders/EficazFramework.Data.SqlLite/EficazFramework.Data.SqlLite.csproj index 9267da7f..ff587bc9 100644 --- a/src/DataProviders/EficazFramework.Data.SqlLite/EficazFramework.Data.SqlLite.csproj +++ b/src/DataProviders/EficazFramework.Data.SqlLite/EficazFramework.Data.SqlLite.csproj @@ -2,9 +2,9 @@ net6.0;net7.0 - 6.1.5 - 6.1.5.0 - 6.1.5.0 + 6.1.6 + 6.1.6.0 + 6.1.6.0 EficazFramework true EfCore.snk @@ -48,7 +48,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Desktop/EficazFramework.WPF/Application/ApplicationDefinition.cs b/src/Desktop/EficazFramework.WPF/Application/ApplicationDefinition.cs new file mode 100644 index 00000000..64b3c1f5 --- /dev/null +++ b/src/Desktop/EficazFramework.WPF/Application/ApplicationDefinition.cs @@ -0,0 +1,99 @@ +namespace EficazFramework.Application; + +public static class ApplicationDefinitionHelpers +{ + public static WpfApplicationTarget Wpf([NotNull] this ApplicationDefinition applicationDefinition) => + (WpfApplicationTarget)applicationDefinition.Targets["WPF"]; + + +} + + +/// +/// Wrapper class for parameters for Blazor target. +/// +public sealed class WpfApplicationTarget : ApplicationTarget +{ + public WindowState StartWindowState + { + get + { + if (!Properties.ContainsKey("StartWindowState")) + Properties["StartWindowState"] = WindowState.Normal; + return (WindowState)Properties["StartWindowState"]; + } + set => Properties["StartWindowState"] = value; + } + + //public bool Resizable + //{ + // get + // { + // if (!Properties.ContainsKey("Resizable")) + // Properties["Resizable"] = true; + // return (bool)Properties["Resizable"]; + // } + // set => Properties["Resizable"] = value; + //} + + + public int OffsetX + { + get + { + if (!Properties.ContainsKey("OffsetX")) + Properties["OffsetX"] = 15; + return (int)Properties["OffsetX"]; + } + + set => Properties["OffsetX"] = value; + } + + public int OffsetY + { + get + { + if (!Properties.ContainsKey("OffsetY")) + Properties["OffsetY"] = 15; + return (int)Properties["OffsetY"]; + } + set => Properties["OffsetY"] = value; + } + + + public int Width + { + get + { + if (!Properties.ContainsKey("Width")) + Properties["Width"] = 425; + return (int)Properties["Width"]; + } + set => Properties["Width"] = value; + } + + public int Height + { + get + { + if (!Properties.ContainsKey("Height")) + Properties["Height"] = 200; + return (int)Properties["Height"]; + } + set => Properties["Height"] = value; + } + + + public int ZIndex + { + get + { + if (!Properties.ContainsKey("ZIndex")) + Properties["ZIndex"] = 1; + return (int)Properties["ZIndex"]; + } + internal set => Properties["ZIndex"] = value; + } + + +} diff --git a/src/Desktop/EficazFramework.WPF/Controls/Selectors/MDIContainer.cs b/src/Desktop/EficazFramework.WPF/Controls/Selectors/MDIContainer.cs index 6e3066dd..341498d1 100644 --- a/src/Desktop/EficazFramework.WPF/Controls/Selectors/MDIContainer.cs +++ b/src/Desktop/EficazFramework.WPF/Controls/Selectors/MDIContainer.cs @@ -1,7 +1,7 @@ -using System.Collections; +using EficazFramework.Application; +using System.Collections; using System.ComponentModel; using System.Diagnostics; -using System.Linq; using System.Threading.Tasks; using System.Windows.Controls.Primitives; @@ -22,7 +22,7 @@ public static void SetApplicationDefinition(DependencyObject obj, Application.Ap public object CustomTaskBarLeftContent { - get => (object)GetValue(CustomTaskBarLeftContentProperty); + get => GetValue(CustomTaskBarLeftContentProperty); set => SetValue(CustomTaskBarLeftContentProperty, value); } public static readonly DependencyProperty CustomTaskBarLeftContentProperty = @@ -39,7 +39,7 @@ public DataTemplate CustomTaskBarLeftContentTemplate public object CustomTaskBarRightContent { - get { return (object)GetValue(CustomTaskBarRightContentProperty); } + get { return GetValue(CustomTaskBarRightContentProperty); } set { SetValue(CustomTaskBarRightContentProperty, value); } } public static readonly DependencyProperty CustomTaskBarRightContentProperty = @@ -121,8 +121,8 @@ protected override void PrepareContainerForItemOverride(DependencyObject element { window.AppDefinition = appinfo; window.Title = appinfo.LongTitle ?? appinfo.Title; - window.WindowState = (WindowState)(appinfo.Targets["WPF"].Properties[Application.ApplicationDefinition.STARTWINDOWSTATE] ?? WindowState.Normal); - target = (UIElement)(appinfo.Content ?? appinfo.Targets["WPF"].SplashScreen); + window.WindowState = appinfo.Wpf().StartWindowState; + target = (UIElement)(appinfo.Content ?? appinfo.Wpf().SplashScreen); } else { @@ -318,7 +318,8 @@ public static async void LoadApplication(Application.ApplicationInstance item) try { await Task.Delay(1000); - UIElement app = await System.Windows.Application.Current.Dispatcher.InvokeAsync(() => System.Windows.Application.LoadComponent(new Uri(item.Targets["WPF"].StartupUriOrType.ToString(), UriKind.RelativeOrAbsolute)) as UIElement); + UIElement app = await System.Windows.Application.Current.Dispatcher.InvokeAsync(() => + System.Windows.Application.LoadComponent(new Uri(item.Wpf().StartupUriOrType.ToString(), UriKind.RelativeOrAbsolute)) as UIElement); if (app != null) item.Content = app; item.IsLoading = false; } diff --git a/src/Desktop/EficazFramework.WPF/Controls/Selectors/StartMenu.cs b/src/Desktop/EficazFramework.WPF/Controls/Selectors/StartMenu.cs index 514b4d36..c7ed8850 100644 --- a/src/Desktop/EficazFramework.WPF/Controls/Selectors/StartMenu.cs +++ b/src/Desktop/EficazFramework.WPF/Controls/Selectors/StartMenu.cs @@ -1,7 +1,7 @@ -using System.Collections.ObjectModel; +using EficazFramework.Application; +using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Globalization; -using System.Linq; using System.Windows.Controls.Primitives; namespace EficazFramework.Controls; @@ -23,7 +23,7 @@ public StartMenu() PinnedApplications.Filter = (app) => { Application.ApplicationDefinition eapp = app as Application.ApplicationDefinition; - return !ExcludedUris.Contains(eapp.Targets["WPF"].StartupUriOrType.ToString()); + return !ExcludedUris.Contains(eapp.Wpf().StartupUriOrType.ToString()); }; SetValue(OpenMenuCommandPropertyKey, new Commands.CommandBase(OpenPopupMenu_Executed)); @@ -203,7 +203,7 @@ private static void OnSearchLiteral_Changed(DependencyObject sender, DependencyP instance.PinnedApplications.Filter = (app) => { Application.ApplicationDefinition eapp = app as Application.ApplicationDefinition; - return !instance.ExcludedUris.Contains(eapp.Targets["WPF"].StartupUriOrType.ToString()); + return !instance.ExcludedUris.Contains(eapp.Wpf().StartupUriOrType.ToString()); }; return; } @@ -220,7 +220,7 @@ private static void OnSearchLiteral_Changed(DependencyObject sender, DependencyP instance.PinnedApplications.Filter = (app) => { Application.ApplicationDefinition eapp = app as Application.ApplicationDefinition; - return (!instance.ExcludedUris.Contains(eapp.Targets["WPF"].StartupUriOrType.ToString())) && + return (!instance.ExcludedUris.Contains(eapp.Wpf().StartupUriOrType.ToString())) && CultureInfo.InvariantCulture.CompareInfo.IndexOf(eapp.TooltipTilte, (string)e.NewValue, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase) >= 0 || @@ -263,9 +263,9 @@ private void PinOffApplication_Executed(object sender, Events.ExecuteEventArgs e { if ((e.Parameter as Application.ApplicationDefinition) == null) return; Application.ApplicationDefinition app = (Application.ApplicationDefinition)e.Parameter; - ExcludedUris.Add(app.Targets["WPF"].StartupUriOrType.ToString()); + ExcludedUris.Add(app.Wpf().StartupUriOrType.ToString()); RefreshPinnedApps(); - ApplicationPinnedOff?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, app.Targets["WPF"].StartupUriOrType.ToString())); + ApplicationPinnedOff?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, app.Wpf().StartupUriOrType.ToString())); } private void ChangeAppsViewMode_Executed(object sender, Events.ExecuteEventArgs e) diff --git a/src/Desktop/EficazFramework.WPF/EficazFramework.WPF.csproj b/src/Desktop/EficazFramework.WPF/EficazFramework.WPF.csproj index f951dfc4..7cb9d350 100644 --- a/src/Desktop/EficazFramework.WPF/EficazFramework.WPF.csproj +++ b/src/Desktop/EficazFramework.WPF/EficazFramework.WPF.csproj @@ -3,9 +3,9 @@ net6.0-windows;net7.0-windows true - 6.1.5 - 6.1.5.0 - 6.1.5.0 + 6.1.6 + 6.1.6.0 + 6.1.6.0 EficazFramework Eficaz Sistemas Eficaz Sistemas de Gestão e Inteligência Tributária diff --git a/src/Tests/Core/EficazFramework.Tests/EficazFramework.Tests.csproj b/src/Tests/Core/EficazFramework.Tests/EficazFramework.Tests.csproj index fb8b4c4f..92e007e4 100644 --- a/src/Tests/Core/EficazFramework.Tests/EficazFramework.Tests.csproj +++ b/src/Tests/Core/EficazFramework.Tests/EficazFramework.Tests.csproj @@ -37,19 +37,19 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -61,7 +61,7 @@ - + diff --git a/src/Tests/Desktop/EficazFramework.Tests.WPF/EficazFramework.Tests.WPF.csproj b/src/Tests/Desktop/EficazFramework.Tests.WPF/EficazFramework.Tests.WPF.csproj index 2f770592..617778e1 100644 --- a/src/Tests/Desktop/EficazFramework.Tests.WPF/EficazFramework.Tests.WPF.csproj +++ b/src/Tests/Desktop/EficazFramework.Tests.WPF/EficazFramework.Tests.WPF.csproj @@ -24,15 +24,15 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/src/Tests/Docs/EficazFramework.Tests.DocsApiPlugin/EficazFramework.Tests.DocsApiPlugin.csproj b/src/Tests/Docs/EficazFramework.Tests.DocsApiPlugin/EficazFramework.Tests.DocsApiPlugin.csproj index 5097e2c9..332c1613 100644 --- a/src/Tests/Docs/EficazFramework.Tests.DocsApiPlugin/EficazFramework.Tests.DocsApiPlugin.csproj +++ b/src/Tests/Docs/EficazFramework.Tests.DocsApiPlugin/EficazFramework.Tests.DocsApiPlugin.csproj @@ -25,10 +25,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Tests/Generators/EficazFramework.Tests.Generators/EficazFramework.Tests.Generators.csproj b/src/Tests/Generators/EficazFramework.Tests.Generators/EficazFramework.Tests.Generators.csproj index d6adb0f6..3220d747 100644 --- a/src/Tests/Generators/EficazFramework.Tests.Generators/EficazFramework.Tests.Generators.csproj +++ b/src/Tests/Generators/EficazFramework.Tests.Generators/EficazFramework.Tests.Generators.csproj @@ -8,9 +8,9 @@ - + - + diff --git a/src/Tests/Web/EficazFramework.Tests.Blazor.Views/Pages/Components/Panels/Mdi.razor b/src/Tests/Web/EficazFramework.Tests.Blazor.Views/Pages/Components/Panels/Mdi.razor index c2594a71..f4fbe65b 100644 --- a/src/Tests/Web/EficazFramework.Tests.Blazor.Views/Pages/Components/Panels/Mdi.razor +++ b/src/Tests/Web/EficazFramework.Tests.Blazor.Views/Pages/Components/Panels/Mdi.razor @@ -41,7 +41,7 @@ @bind-CurrentSection="ApplicationManager!.SectionManager!.CurrentSectionId" SectionChanged="SectionChanged" /> - +@*
@($"Mdi: {_mdi!.CurrentSection}")
@@ -50,5 +50,5 @@ @($"Service, Instance: {ApplicationManager!.SectionManager.CurrentSection?.ID ?? 0}")
- + *@ diff --git a/src/Tests/Web/EficazFramework.Tests.Blazor.Views/Resources/Mocks/Applications.cs b/src/Tests/Web/EficazFramework.Tests.Blazor.Views/Resources/Mocks/Applications.cs index a875b93d..85d9f01b 100644 --- a/src/Tests/Web/EficazFramework.Tests.Blazor.Views/Resources/Mocks/Applications.cs +++ b/src/Tests/Web/EficazFramework.Tests.Blazor.Views/Resources/Mocks/Applications.cs @@ -1,4 +1,6 @@ -namespace EficazFramework.Tests.Blazor.Views.Resources.Mocks; +using EficazFramework.Application; + +namespace EficazFramework.Tests.Blazor.Views.Resources.Mocks; public static class Applications { @@ -24,7 +26,7 @@ public static void GenerateApps(EficazFramework.Application.IApplicationManager? Group = "Free Apps", Title = $"My App 1", }; - appHello.Targets.Add("Blazor", new() + appHello.Targets.Add("Blazor", new BlazorApplicationTarget() { Icon = MudBlazor.Icons.Custom.Brands.WhatsApp, StartupUriOrType = typeof(EficazFramework.Tests.Blazor.Views.Pages.Components.Panels.MdiApps.MdiAppHelloWorld) @@ -37,7 +39,7 @@ public static void GenerateApps(EficazFramework.Application.IApplicationManager? Group = "Free Apps", Title = $"My App 2", }; - appAnother.Targets.Add("Blazor", new() + appAnother.Targets.Add("Blazor", new BlazorApplicationTarget() { Icon = MudBlazor.Icons.Custom.Brands.Facebook, StartupUriOrType = typeof(EficazFramework.Tests.Blazor.Views.Pages.Components.Panels.MdiApps.MdiAnotherApp) @@ -50,7 +52,7 @@ public static void GenerateApps(EficazFramework.Application.IApplicationManager? Group = "Paid Apps", Title = $"My Scoped App", }; - appPerSection.Targets.Add("Blazor", new() + appPerSection.Targets.Add("Blazor", new BlazorApplicationTarget() { Icon = MudBlazor.Icons.Custom.Brands.GitHub, StartupUriOrType = typeof(EficazFramework.Tests.Blazor.Views.Pages.Components.Panels.MdiApps.MdiScopedApp) @@ -63,12 +65,12 @@ public static void GenerateApps(EficazFramework.Application.IApplicationManager? Group = "Free Apps", Title = $"Full Screen", }; - appHello2.Targets.Add("Blazor", new() + appHello2.Targets.Add("Blazor", new BlazorApplicationTarget() { Icon = MudBlazor.Icons.Custom.Brands.Microsoft, - StartupUriOrType = typeof(EficazFramework.Tests.Blazor.Views.Pages.Components.Panels.MdiApps.MdiIconApp) + StartupUriOrType = typeof(EficazFramework.Tests.Blazor.Views.Pages.Components.Panels.MdiApps.MdiIconApp), + IsMaximized = true, }); - appHello2.Targets["Blazor"].Properties.Add("IsMaximized", true); appAnother2 = new() { @@ -77,10 +79,12 @@ public static void GenerateApps(EficazFramework.Application.IApplicationManager? Group = "Free Apps", Title = $"My New App 2", }; - appAnother2.Targets.Add("Blazor", new() + appAnother2.Targets.Add("Blazor", new BlazorApplicationTarget() { Icon = MudBlazor.Icons.Custom.Brands.Google, - StartupUriOrType = typeof(EficazFramework.Tests.Blazor.Views.Pages.Components.Panels.MdiApps.AnotherCoolApp) + StartupUriOrType = typeof(EficazFramework.Tests.Blazor.Views.Pages.Components.Panels.MdiApps.AnotherCoolApp), + InitialSize = new(200, 225), + Resizable = false }); appPerSection2 = new() @@ -90,7 +94,7 @@ public static void GenerateApps(EficazFramework.Application.IApplicationManager? Group = "Paid Apps", Title = $"New Scoped App", }; - appPerSection2.Targets.Add("Blazor", new() + appPerSection2.Targets.Add("Blazor", new BlazorApplicationTarget() { Icon = MudBlazor.Icons.Custom.Brands.Linux, StartupUriOrType = typeof(EficazFramework.Tests.Blazor.Views.Pages.Components.Panels.MdiApps.MdiScopedApp) @@ -103,7 +107,7 @@ public static void GenerateApps(EficazFramework.Application.IApplicationManager? Group = "Paid Apps", Title = $"Default Icon", }; - appEmptyIcon.Targets.Add("Blazor", new() + appEmptyIcon.Targets.Add("Blazor", new BlazorApplicationTarget() { StartupUriOrType = typeof(EficazFramework.Tests.Blazor.Views.Pages.Components.Panels.MdiApps.MdiScopedApp) }); @@ -115,7 +119,7 @@ public static void GenerateApps(EficazFramework.Application.IApplicationManager? Group = "Free Apps", Title = $"DataGrid App", }; - appDataGrid.Targets.Add("Blazor", new() + appDataGrid.Targets.Add("Blazor", new BlazorApplicationTarget() { Icon = MudBlazor.Icons.Material.Filled.DataArray, StartupUriOrType = typeof(EficazFramework.Tests.Blazor.Views.Pages.Components.Panels.MdiApps.MdiDataGridApp) @@ -128,12 +132,12 @@ public static void GenerateApps(EficazFramework.Application.IApplicationManager? Group = "Free Apps", Title = $"DataGrid App (Full Scrren)", }; - appDataGrid2.Targets.Add("Blazor", new() + appDataGrid2.Targets.Add("Blazor", new BlazorApplicationTarget() { Icon = MudBlazor.Icons.Material.Filled.DataArray, - StartupUriOrType = typeof(EficazFramework.Tests.Blazor.Views.Pages.Components.Panels.MdiApps.MdiDataGridApp) + StartupUriOrType = typeof(EficazFramework.Tests.Blazor.Views.Pages.Components.Panels.MdiApps.MdiDataGridApp), + IsMaximized = true }); - appDataGrid2.Targets["Blazor"].Properties.Add("IsMaximized", true); applicationManager.AllApplications.Add(appHello); diff --git a/src/Tests/Web/EficazFramework.Tests.Blazor/EficazFramework.Tests.Blazor.csproj b/src/Tests/Web/EficazFramework.Tests.Blazor/EficazFramework.Tests.Blazor.csproj index d54d8201..daed7381 100644 --- a/src/Tests/Web/EficazFramework.Tests.Blazor/EficazFramework.Tests.Blazor.csproj +++ b/src/Tests/Web/EficazFramework.Tests.Blazor/EficazFramework.Tests.Blazor.csproj @@ -13,20 +13,20 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + @@ -39,7 +39,7 @@ - + diff --git a/src/Web/EficazFramework.Blazor/Application/ApplicationDefinition.cs b/src/Web/EficazFramework.Blazor/Application/ApplicationDefinition.cs new file mode 100644 index 00000000..25c0ac9f --- /dev/null +++ b/src/Web/EficazFramework.Blazor/Application/ApplicationDefinition.cs @@ -0,0 +1,101 @@ +using System.Diagnostics.CodeAnalysis; + +namespace EficazFramework.Application; + +public static class ApplicationDefinitionHelpers +{ + public static BlazorApplicationTarget? Blazor([NotNull] this ApplicationDefinition applicationDefinition) => + (BlazorApplicationTarget)applicationDefinition.Targets["Blazor"]; + + +} + + +/// +/// Wrapper class for parameters for Blazor target. +/// +public sealed class BlazorApplicationTarget : ApplicationTarget +{ + public bool IsMaximized + { + get + { + if (!Properties.ContainsKey("IsMaximized")) + Properties["IsMaximized"] = false; + return (bool)Properties["IsMaximized"]; + } + set => Properties["IsMaximized"] = value; + } + + public bool Resizable + { + get + { + if (!Properties.ContainsKey("Resizable")) + Properties["Resizable"] = true; + return (bool)Properties["Resizable"]; + } + set => Properties["Resizable"] = value; + } + + + public int OffsetX + { + get + { + if (!Properties.ContainsKey("OffsetX")) + Properties["OffsetX"] = 15; + return (int)Properties["OffsetX"]; + } + + set => Properties["OffsetX"] = value; + } + + public int OffsetY + { + get + { + if (!Properties.ContainsKey("OffsetY")) + Properties["OffsetY"] = 15; + return (int)Properties["OffsetY"]; + } + set => Properties["OffsetY"] = value; + } + + + public int Width + { + get + { + if (!Properties.ContainsKey("Width")) + Properties["Width"] = 425; + return (int)Properties["Width"]; + } + set => Properties["Width"] = value; + } + + public int Height + { + get + { + if (!Properties.ContainsKey("Height")) + Properties["Height"] = 200; + return (int)Properties["Height"]; + } + set => Properties["Height"] = value; + } + + + public int ZIndex + { + get + { + if (!Properties.ContainsKey("ZIndex")) + Properties["ZIndex"] = 1; + return (int)Properties["ZIndex"]; + } + internal set => Properties["ZIndex"] = value; + } + + +} diff --git a/src/Web/EficazFramework.Blazor/Components/Panels/ApplicationsMenu.razor b/src/Web/EficazFramework.Blazor/Components/Panels/ApplicationsMenu.razor index 1bbdeaf7..e05f273c 100644 --- a/src/Web/EficazFramework.Blazor/Components/Panels/ApplicationsMenu.razor +++ b/src/Web/EficazFramework.Blazor/Components/Panels/ApplicationsMenu.razor @@ -1,5 +1,6 @@ @namespace EficazFramework.Components @inherits MudBlazor.MudComponentBase +@using EficazFramework.Application
@@ -43,7 +44,7 @@ Size="@MudBlazor.Size.Large" Class="pt-5 pb-7 ef-application-button" OnClick="() => SelectionCallBack?.Invoke(app)"> - @foreach (var app in group) { - @app.LongTitle diff --git a/src/Web/EficazFramework.Blazor/Components/Panels/MdiHost.razor b/src/Web/EficazFramework.Blazor/Components/Panels/MdiHost.razor index d5721d12..80d88925 100644 --- a/src/Web/EficazFramework.Blazor/Components/Panels/MdiHost.razor +++ b/src/Web/EficazFramework.Blazor/Components/Panels/MdiHost.razor @@ -5,7 +5,10 @@ @inherits MudBlazor.MudComponentBase
+ style="@StyleName" + @onpointerup="OnHeaderPointerUpOrLeave" + @onpointermove="OnHeaderPointerMove" + @onpointerleave="OnHeaderPointerUpOrLeave"> @*MDI AREA*@ @if (BreakpointListener.IsMediaSize(Breakpoint, _breakpoint)) @@ -15,9 +18,10 @@ { - + }
@@ -31,9 +35,10 @@ { - + Icon="@item.Blazor()!.Icon?.ToString()" + Resizable="@item.Blazor()!.Resizable" + IsMaximized="@item.Blazor()!.IsMaximized"> + }
@@ -47,7 +52,7 @@ @ToolbarRightContent - + \ No newline at end of file diff --git a/src/Web/EficazFramework.Blazor/Components/Panels/MdiHost.razor.cs b/src/Web/EficazFramework.Blazor/Components/Panels/MdiHost.razor.cs index 6f63f71f..8ff2b05c 100644 --- a/src/Web/EficazFramework.Blazor/Components/Panels/MdiHost.razor.cs +++ b/src/Web/EficazFramework.Blazor/Components/Panels/MdiHost.razor.cs @@ -1,9 +1,9 @@ -using Microsoft.AspNetCore.Components; -using MudBlazor.Utilities; -using EficazFramework.Application; -using Microsoft.JSInterop; +using EficazFramework.Application; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; using MudBlazor; using MudBlazor.Services; +using MudBlazor.Utilities; namespace EficazFramework.Components; public partial class MdiHost : MudComponentBase @@ -51,6 +51,73 @@ protected override async Task OnAfterRenderAsync(bool firstRender) [Parameter] public RenderFragment? ToolbarRightContent { get; set; } + //! Selected MdiWindow drag move & resize + internal double offsetX, offsetY; + internal double width, height; + internal MdiWindow? _movingWindow; + /// + /// Ends a Drag operation for Current Application + /// + private void OnHeaderPointerUpOrLeave(PointerEventArgs args) + { + _movingWindow?.CancelMove(); + _movingWindow?.CancelResize(); + _movingWindow = null; + } + + /// + /// Smoothly Drags this instance + /// + private void OnHeaderPointerMove(PointerEventArgs args) + { + if (_movingWindow?.IsMoving ?? false) + { + MoveSeletedWindow(args); + return; + } + + if ((_movingWindow?.IsResizing ?? false) && !(_movingWindow?.IsMoving ?? false)) + ResizeSeletedWindow(args); + } + + private void MoveSeletedWindow(PointerEventArgs args) + { +#if NET7_0_OR_GREATER + offsetX += args.MovementX; + offsetY += args.MovementY; +#else + double deltaX = args.OffsetX - offsetX; + double deltaY = args.OffsetY - offsetY; + offsetX += deltaX; + offsetY += deltaY; +#endif + if (SelectedApp != null) + { + SelectedApp.Blazor()!.OffsetX = (int)offsetX; + SelectedApp.Blazor()!.OffsetY = (int)offsetY; + } + } + + private void ResizeSeletedWindow(PointerEventArgs args) + { +#if NET7_0_OR_GREATER + width += args.MovementX; + height += args.MovementY; +#else + double deltaX = args.OffsetX - width; + double deltaY = args.OffsetY - height; + width += deltaX; + height += deltaY; +#endif + if (SelectedApp != null) + { + SelectedApp.Blazor()!.Width = (int)width; + SelectedApp.Blazor()!.Height = (int)height; + } + } + + + private long _currentSection = 0; /// /// Current MDI Section (for multi tenant purposes) @@ -127,21 +194,9 @@ public void LoadApplication(ApplicationDefinition app) if (instance == null) { instance = ApplicationInstance.Create(app, CurrentSection); - - if (!instance.Targets["Blazor"].Properties.ContainsKey("IsMaximized")) - instance.Targets["Blazor"].Properties.Add("IsMaximized", false); - - instance.Targets["Blazor"].Properties.Add("OffsetX", 15); - instance.Targets["Blazor"].Properties.Add("OffsetY", 15); - - if (!instance.Targets["Blazor"].Properties.ContainsKey("Width")) - instance.Targets["Blazor"].Properties.Add("Width", 425); - - if (!instance.Targets["Blazor"].Properties.ContainsKey("Height")) - instance.Targets["Blazor"].Properties.Add("Height", 250); - - instance.Targets["Blazor"].Properties["ZIndex"] = (ApplicationsSource?.Count() ?? 0) + 1; - + instance.Blazor()!.ZIndex = (ApplicationsSource?.Count() ?? 0) + 1; + instance.Blazor()!.Width = instance.Blazor()!.InitialSize.Width; + instance.Blazor()!.Height = instance.Blazor()!.InitialSize.Height; (ApplicationsSource as IList)?.Add(instance); } @@ -157,12 +212,12 @@ public void MoveTo(ApplicationInstance app) var runningAps = RunningApplications(); foreach(var anotherApp in runningAps.Where(a => !object.ReferenceEquals(a, app))) { - int zIndex = (int?)anotherApp.Targets["Blazor"].Properties["ZIndex"] ?? 1; - anotherApp.Targets["Blazor"].Properties["ZIndex"] = Math.Max(1, zIndex -= 1); + int zIndex = anotherApp.Blazor()!.ZIndex; + anotherApp.Blazor()!.ZIndex = Math.Max(1, zIndex -= 1); } if (app != null) - app.Targets["Blazor"].Properties["ZIndex"] = runningAps.Count(); + app.Blazor()!.ZIndex = runningAps.Count(); SelectedApp = app; StateHasChanged(); diff --git a/src/Web/EficazFramework.Blazor/Components/Panels/MdiWindow.razor b/src/Web/EficazFramework.Blazor/Components/Panels/MdiWindow.razor index b9678e16..77d8747d 100644 --- a/src/Web/EficazFramework.Blazor/Components/Panels/MdiWindow.razor +++ b/src/Web/EficazFramework.Blazor/Components/Panels/MdiWindow.razor @@ -6,25 +6,27 @@ Outlined Class="@Classname" Style="@StyleName" - @onclick="OnClick"> + @onclick="OnClick" + @onpointerdown="OnBorderPointerDown" + @onpointerup="OnBorderPointerUp"> -
+
+ Style="width: 14px; height: 14px;" + @onpointermove:preventDefault/>
+ Class="mr-2 mt-1" + @onpointermove:preventDefault> @(ApplicationInstance != null ? ApplicationInstance.Title : Title)
+ @onpointermove:preventDefault> @HeaderContent
@@ -35,13 +37,15 @@ Size="MudBlazor.Size.Small" Class="align-self-start" Style="top:2px;" - Title="Close"/> + Title="Close" + @onpointermove:preventDefault/>
-
- +
+ @ChildContent
diff --git a/src/Web/EficazFramework.Blazor/Components/Panels/MdiWindow.razor.cs b/src/Web/EficazFramework.Blazor/Components/Panels/MdiWindow.razor.cs index e8d56afa..c307be58 100644 --- a/src/Web/EficazFramework.Blazor/Components/Panels/MdiWindow.razor.cs +++ b/src/Web/EficazFramework.Blazor/Components/Panels/MdiWindow.razor.cs @@ -1,9 +1,9 @@ -using Microsoft.AspNetCore.Components; +using EficazFramework.Application; +using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; -using MudBlazor.Utilities; -using System.Drawing; -using EficazFramework.Application; using Microsoft.JSInterop; +using MudBlazor; +using MudBlazor.Utilities; namespace EficazFramework.Components; @@ -19,6 +19,13 @@ public partial class MdiWindow: MudBlazor.MudComponentBase [Parameter] public bool IsMaximized { get; set; } = false; + + /// + /// Gets or Sets if user can resize the MdiWindow content + /// + [Parameter] public bool Resizable { get; set; } = true; + + /// /// Gets or Sets if ef-mdi-window-host element should render a vertical scrollbar /// @@ -29,16 +36,10 @@ public partial class MdiWindow: MudBlazor.MudComponentBase ///
[Parameter] public RenderFragment? HeaderContent { get; set; } - [CascadingParameter] public MdiHost MdiHost { get; set; } [Inject] IJSRuntime JsRutinme { get; set; } - private object myRef; - - //internal Size FrameSize() => - // (Size)ApplicationInstance.Targets["Blazor"].Properties["Size"] ?? new Size(300, 250) - /// /// Css classes for main div element @@ -61,12 +62,21 @@ public partial class MdiWindow: MudBlazor.MudComponentBase protected string StyleName => new StyleBuilder() .AddStyle(Style) - .AddStyle("left", $"{(int)ApplicationInstance.Targets["Blazor"].Properties["OffsetX"]}px", !IsMaximized) - .AddStyle("top", $"{(int)ApplicationInstance.Targets["Blazor"].Properties["OffsetY"]}px", !IsMaximized) - .AddStyle("width", $"{(int)ApplicationInstance.Targets["Blazor"].Properties["Width"]}px", !IsMaximized) - .AddStyle("height", $"{(int)ApplicationInstance.Targets["Blazor"].Properties["Height"]}px", !IsMaximized) - .AddStyle("z-index", $"{(int)ApplicationInstance.Targets["Blazor"].Properties["ZIndex"]}") + .AddStyle("left", $"{ApplicationInstance.Blazor()!.OffsetX}px", !IsMaximized) + .AddStyle("top", $"{ApplicationInstance.Blazor()!.OffsetY}px", !IsMaximized) + .AddStyle("width", $"{ApplicationInstance.Blazor()!.Width}px", !IsMaximized) + .AddStyle("height", $"{ApplicationInstance.Blazor()!.Height}px", !IsMaximized) + .AddStyle("z-index", $"{ApplicationInstance.Blazor()!.ZIndex}") + .AddStyle("-webkit-user-select", "none", !IsMoving) + .AddStyle("-ms-user-select", "none", !IsMoving) + .AddStyle("user-select", "none", !IsMoving) + .AddStyle("cursor", "move", Resizable) + .AddStyle("outline", "5px solid transparent") + .AddStyle("outline-offset", "-5px") .Build(); + //.AddStyle("resize", "both", Resizable && !IsMaximized) + //.AddStyle("overflow", "auto", Resizable && !IsMaximized) + /// /// Css classes app host div @@ -87,8 +97,6 @@ protected override void OnInitialized() base.OnInitialized(); } - private double startX, startY, offsetX, offsetY; - private bool isDragging = false; /// /// Set this instance as SelectedItem on the host when it's clicked @@ -98,55 +106,99 @@ private void OnClick(MouseEventArgs e) => MdiHost.MoveTo(ApplicationInstance); /// - /// Start a Drag operation for move + /// Set a header custom content /// - private void OnDragStart(DragEventArgs args) + /// + /// + public void OverrideFrameParameters(RenderFragment? customHeader = null, + bool scrolable = false) { - //Utilities.JsInterop.SetDragImage(JsRutinme, args); - MdiHost.MoveTo(ApplicationInstance); - isDragging = true; - startX = args.OffsetX; - startY = args.OffsetY; + HeaderContent = customHeader; + Scrollable = scrolable; + StateHasChanged(); } + /// - /// Ends a Drag operation and update the screen coordinates of this instance. + /// Close Button Click action /// - private void OnDragEnd(DragEventArgs args) + private void OnClose() { - isDragging = false; - - offsetX += args.OffsetX - startX; - if (offsetX < 0) - offsetX = 0; + CancelMove(); + MdiHost.SelectedApp = ApplicationInstance; + MdiHost.CloseApplication(this); + } - offsetY += args.OffsetY - startY; - if (offsetY < 0) - offsetY = 0; - ApplicationInstance.Targets["Blazor"].Properties["OffsetX"] = (int)offsetX; - ApplicationInstance.Targets["Blazor"].Properties["OffsetY"] = (int)offsetY; - } + //! Move Behavior + internal bool IsMoving { get; private set; } = false; /// - /// Close Button Click action + /// Starts a Drag operation for move /// - private void OnClose() + private void OnHeaderPointerDown(PointerEventArgs args) { - MdiHost.SelectedApp = ApplicationInstance; - MdiHost.CloseApplication(this); + if ((args.PointerType == "mouse" && args.Button == 0) + || args.PointerType == "touch") + { + if (IsMaximized) + return; + + MdiHost.MoveTo(ApplicationInstance); + MdiHost._movingWindow = this; + IsMoving = true; + IsResizing = false; + MdiHost.offsetX = ApplicationInstance.Blazor()!.OffsetX; + MdiHost.offsetY = ApplicationInstance.Blazor()!.OffsetY; + } } + /// + /// Ends a Drag operation and update the screen coordinates of this instance. + /// + private void OnHeaderPointerUp(PointerEventArgs args) => + CancelMove(); - public void OverrideFrameParameters(RenderFragment? customHeader = null, - bool scrolable = false) + /// + /// Cancels a dragging operation by external component + /// + internal void CancelMove() => + IsMoving = false; + + + //! Resize Behavior + internal bool IsResizing { get; private set; } = false; + internal double width, height; + /// + /// Starts a Drag operation for resize + /// + private void OnBorderPointerDown(PointerEventArgs args) { - HeaderContent = customHeader; - Scrollable = scrolable; - StateHasChanged(); + if ((args.PointerType == "mouse" && args.Button == 0) + || args.PointerType == "touch") + { + if (IsMaximized || !Resizable) + return; + + MdiHost.MoveTo(ApplicationInstance); + MdiHost._movingWindow = this; + IsResizing = true; + MdiHost.width = ApplicationInstance.Blazor()!.Width; + MdiHost.height = ApplicationInstance.Blazor()!.Height; + } } + /// + /// Ends a Drag operation and update the measures of this instance. + /// + private void OnBorderPointerUp(PointerEventArgs args) => + CancelResize(); + /// + /// Cancels a dragging operation by external component + /// + internal void CancelResize() => + IsResizing = false; } public enum WindowState diff --git a/src/Web/EficazFramework.Blazor/Components/Panels/SectionsView.razor b/src/Web/EficazFramework.Blazor/Components/Panels/SectionsView.razor index 0aaf2709..cce7f8c4 100644 --- a/src/Web/EficazFramework.Blazor/Components/Panels/SectionsView.razor +++ b/src/Web/EficazFramework.Blazor/Components/Panels/SectionsView.razor @@ -89,7 +89,7 @@ @if (ItemsSource.Count(f => f.ID > 0) > 1) { - + s.ID) + 1; (ItemsSource as IList)?.Add(new EficazFramework.Application.Section(id) { Name = $"Section {id}" diff --git a/src/Web/EficazFramework.Blazor/Configuration/ServicesOptions.cs b/src/Web/EficazFramework.Blazor/Configuration/ServicesOptions.cs index 8919c4d5..da8d8b22 100644 --- a/src/Web/EficazFramework.Blazor/Configuration/ServicesOptions.cs +++ b/src/Web/EficazFramework.Blazor/Configuration/ServicesOptions.cs @@ -4,7 +4,7 @@ public class ServiceConfiguration { public MudBlazor.MudTheme Theme { get; set; } = new MudBlazor.MudTheme() { - Palette = new MudBlazor.Palette() + Palette = new MudBlazor.PaletteLight() { PrimaryDarken = "#00172b", Primary = "#0060ad", @@ -24,7 +24,7 @@ public class ServiceConfiguration AppbarBackground = "#0078d7", AppbarText = "#fff", }, - PaletteDark = new MudBlazor.Palette() + PaletteDark = new MudBlazor.PaletteDark() { TextDisabled = "#404040ff", @@ -135,5 +135,5 @@ public class ServiceConfiguration public bool UseApplicationManager { get; set; } = false; - public MudBlazor.Services.MudServicesConfiguration MudBlazorConfigurations { get; set; } + public MudBlazor.Services.MudServicesConfiguration MudBlazorConfigurations { get; set; } = new(); } diff --git a/src/Web/EficazFramework.Blazor/EficazFramework.Blazor.csproj b/src/Web/EficazFramework.Blazor/EficazFramework.Blazor.csproj index cdf94257..9d87307b 100644 --- a/src/Web/EficazFramework.Blazor/EficazFramework.Blazor.csproj +++ b/src/Web/EficazFramework.Blazor/EficazFramework.Blazor.csproj @@ -5,9 +5,9 @@ enable enable true - 6.1.6-preview001 - 6.1.6.1 - 6.1.6.1 + 6.1.6 + 6.1.6.2 + 6.1.6.2 EficazFramework Eficaz Sistemas Eficaz Sistemas de Gestão e Inteligência Tributária @@ -96,7 +96,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - +