diff --git a/sources/editor/Stride.Core.Assets.Editor.Avalonia/Themes/PropertyViewTheme.axaml b/sources/editor/Stride.Core.Assets.Editor.Avalonia/Themes/PropertyViewTheme.axaml index 7401a4e29b..865f355757 100644 --- a/sources/editor/Stride.Core.Assets.Editor.Avalonia/Themes/PropertyViewTheme.axaml +++ b/sources/editor/Stride.Core.Assets.Editor.Avalonia/Themes/PropertyViewTheme.axaml @@ -7,7 +7,7 @@ - + - + - + @@ -63,9 +63,9 @@ ContentTemplate="{TemplateBinding HeaderTemplate}" HorizontalAlignment="{TemplateBinding Control.HorizontalAlignment}" IsVisible="{sd:MultiBinding {Binding !$parent[sd:PropertyView].((caecp:SessionObjectPropertiesViewModel)DataContext).ShowOverridesOnly, FallbackValue={sd:True}}, - {Binding [IsOverridden]}, - {Binding ![HasBase]}, - Converter={sd:OrMulti}}"/> + {Binding [IsOverridden]}, + {Binding ![HasBase]}, + Converter={sd:OrMulti}}"/> + {Binding [IsOverridden]}, + {Binding ![HasBase]}, + Converter={sd:OrMulti}}"/> diff --git a/sources/editor/Stride.Core.Assets.Editor/ViewModels/SessionViewModel.static.cs b/sources/editor/Stride.Core.Assets.Editor/ViewModels/SessionViewModel.static.cs index 04c6ae4131..cc9cb85ded 100644 --- a/sources/editor/Stride.Core.Assets.Editor/ViewModels/SessionViewModel.static.cs +++ b/sources/editor/Stride.Core.Assets.Editor/ViewModels/SessionViewModel.static.cs @@ -98,7 +98,7 @@ public static SessionViewModel Instance actionService.Resize(200); // And initialize the actions view model - sessionViewModel.ActionHistory?.Initialize(); + sessionViewModel?.ActionHistory?.Initialize(); // Copy the result of the asset loading to the log panel. sessionViewModel?.AssetLog.AddLogger(LogKey.Get("Session"), sessionResult); diff --git a/sources/editor/Stride.GameStudio.Avalonia/App.axaml b/sources/editor/Stride.GameStudio.Avalonia/App.axaml index 7050de5aa8..08773ca267 100644 --- a/sources/editor/Stride.GameStudio.Avalonia/App.axaml +++ b/sources/editor/Stride.GameStudio.Avalonia/App.axaml @@ -1,7 +1,5 @@ @@ -48,131 +46,10 @@ - - - - + + + + + diff --git a/sources/editor/Stride.GameStudio.Avalonia/Themes/DefaultStyles.axaml.cs b/sources/editor/Stride.GameStudio.Avalonia/Themes/DefaultStyles.axaml.cs deleted file mode 100644 index 34f2e82644..0000000000 --- a/sources/editor/Stride.GameStudio.Avalonia/Themes/DefaultStyles.axaml.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Avalonia.Markup.Xaml; -using Avalonia.Styling; - -namespace Stride.GameStudio.Avalonia.Themes; - -internal sealed class DefaultStyles : Styles -{ - public DefaultStyles(IServiceProvider? sp = null) - { - AvaloniaXamlLoader.Load(sp, this); - } -} diff --git a/sources/editor/Stride.GameStudio.Avalonia/Views/MainView.axaml b/sources/editor/Stride.GameStudio.Avalonia/Views/MainView.axaml index a5a29d7137..8b59052e8f 100644 --- a/sources/editor/Stride.GameStudio.Avalonia/Views/MainView.axaml +++ b/sources/editor/Stride.GameStudio.Avalonia/Views/MainView.axaml @@ -29,6 +29,7 @@ + @@ -86,6 +87,8 @@ Command="{Binding CrashCommand}"/> + + - + + - + + - + diff --git a/sources/editor/Stride.GameStudio.Avalonia/Views/MainWindow.axaml b/sources/editor/Stride.GameStudio.Avalonia/Views/MainWindow.axaml index 7f5c0c3373..2cf3a8acbf 100644 --- a/sources/editor/Stride.GameStudio.Avalonia/Views/MainWindow.axaml +++ b/sources/editor/Stride.GameStudio.Avalonia/Views/MainWindow.axaml @@ -10,5 +10,5 @@ Icon="/Assets/GameStudio.ico" Title="{Binding Title}" Width="1280" Height="900"> - + diff --git a/sources/presentation/Stride.Core.Presentation.Avalonia/Controls/ToolBar.cs b/sources/presentation/Stride.Core.Presentation.Avalonia/Controls/ToolBar.cs new file mode 100644 index 0000000000..05b08c64fc --- /dev/null +++ b/sources/presentation/Stride.Core.Presentation.Avalonia/Controls/ToolBar.cs @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Avalonia; +using Avalonia.Controls; +using Avalonia.Layout; + +namespace Stride.Core.Presentation.Avalonia.Controls; + +public sealed class ToolBar : ItemsControl +{ + /// + /// Defines the property. + /// + public static readonly StyledProperty OrientationProperty = + AvaloniaProperty.RegisterAttached(nameof(Orientation), typeof(ToolBar), coerce: CoerceOrientation); + + private static Orientation CoerceOrientation(AvaloniaObject d, Orientation value) + { + ToolBarTray? toolBarTray = ((ToolBar)d).ToolBarTray; + return toolBarTray?.Orientation ?? value; + } + + public Orientation Orientation + { + get => GetValue(OrientationProperty); + } + + private ToolBarTray? ToolBarTray => Parent as ToolBarTray; + + protected override void OnInitialized() + { + base.OnInitialized(); + CoerceValue(OrientationProperty); + } +} diff --git a/sources/presentation/Stride.Core.Presentation.Avalonia/Controls/ToolBarTray.cs b/sources/presentation/Stride.Core.Presentation.Avalonia/Controls/ToolBarTray.cs new file mode 100644 index 0000000000..6b435f6eb7 --- /dev/null +++ b/sources/presentation/Stride.Core.Presentation.Avalonia/Controls/ToolBarTray.cs @@ -0,0 +1,182 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System.Collections.ObjectModel; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Layout; +using Avalonia.Metadata; + +namespace Stride.Core.Presentation.Avalonia.Controls; + +public sealed class ToolBarTray : Control, IAddChild +{ + /// + /// Defines the property. + /// + public static readonly StyledProperty OrientationProperty = + AvaloniaProperty.Register(nameof(Orientation)); + + static ToolBarTray() + { + OrientationProperty.Changed.AddClassHandler((tray, _) => + { + foreach (var toolBar in tray.ToolBars) + { + toolBar.CoerceValue(ToolBar.OrientationProperty); + } + }); + } + + private readonly ToolBarCollection toolBars; + + public ToolBarTray() + { + toolBars = new ToolBarCollection(this); + } + + public Orientation Orientation + { + get => GetValue(OrientationProperty); + set => SetValue(OrientationProperty, value); + } + + public Collection ToolBars => toolBars; + + void IAddChild.AddChild(ToolBar child) + { + ToolBars.Add(child); + } + + // Note: for now follow a similar layouting than StackPanel + protected override Size MeasureOverride(Size availableSize) + { + Size trayDesiredSize = new(); + Size toolBarConstraint = availableSize; + bool isHorizontal = Orientation == Orientation.Horizontal; + toolBarConstraint = isHorizontal + ? toolBarConstraint.WithWidth(double.PositiveInfinity) + : toolBarConstraint.WithHeight(double.PositiveInfinity); + + foreach (var toolBar in toolBars) + { + // Measure the toolbar + toolBar.Measure(toolBarConstraint); + var toolBarDesiredSize = toolBar.DesiredSize; + + // Accumulate the size + if (isHorizontal) + { + trayDesiredSize = trayDesiredSize.WithWidth(trayDesiredSize.Width + toolBarDesiredSize.Width); + trayDesiredSize = trayDesiredSize.WithHeight(Math.Max(trayDesiredSize.Height, toolBarDesiredSize.Height)); + } + else + { + trayDesiredSize = trayDesiredSize.WithWidth(Math.Max(trayDesiredSize.Width, toolBarDesiredSize.Width)); + trayDesiredSize = trayDesiredSize.WithHeight(trayDesiredSize.Height + toolBarDesiredSize.Height); + } + } + + return trayDesiredSize; + } + + // Note: for now follow a similar layouting than StackPanel + protected override Size ArrangeOverride(Size finalSize) + { + bool isHorizontal = Orientation == Orientation.Horizontal; + Rect rcToolBar = new(finalSize); + double previousDimension = 0.0; + + foreach (var toolBar in toolBars) + { + if (!toolBar.IsVisible) continue; + + if (isHorizontal) + { + rcToolBar = rcToolBar.WithX(rcToolBar.X + previousDimension); + previousDimension = toolBar.DesiredSize.Width; + rcToolBar = rcToolBar.WithWidth(previousDimension); + rcToolBar = rcToolBar.WithHeight(Math.Max(finalSize.Height, toolBar.DesiredSize.Height)); + } + else + { + rcToolBar = rcToolBar.WithY(rcToolBar.Y + previousDimension); + previousDimension = toolBar.DesiredSize.Height; + rcToolBar = rcToolBar.WithHeight(previousDimension); + rcToolBar = rcToolBar.WithWidth(Math.Max(finalSize.Width, toolBar.DesiredSize.Width)); + } + + toolBar.Arrange(rcToolBar); + } + + return finalSize; + } + + private sealed class ToolBarCollection : Collection + { + private readonly ToolBarTray parent; + + public ToolBarCollection(ToolBarTray parent) + { + this.parent = parent; + } + + protected override void ClearItems() + { + var count = Count; + if (count > 0) + { + for (var i = 0; i < count; i++) + { + var toolBar = this[i]; + parent.VisualChildren.Remove(toolBar); + parent.LogicalChildren.Remove(toolBar); + } + + parent.InvalidateMeasure(); + } + + base.ClearItems(); + } + + protected override void InsertItem(int index, ToolBar toolBar) + { + base.InsertItem(index, toolBar); + + parent.LogicalChildren.Add(toolBar); + parent.VisualChildren.Add(toolBar); + + parent.InvalidateMeasure(); + } + + protected override void RemoveItem(int index) + { + var toolBar = this[index]; + base.RemoveItem(index); + + parent.VisualChildren.Remove(toolBar); + parent.LogicalChildren.Remove(toolBar); + + parent.InvalidateMeasure(); + } + + protected override void SetItem(int index, ToolBar toolBar) + { + var currentToolBar = this[index]; + if (toolBar != currentToolBar) + { + base.SetItem(index, toolBar); + + // remove current toolBar + parent.VisualChildren.Remove(currentToolBar); + parent.LogicalChildren.Remove(currentToolBar); + + // add new toolBar + parent.LogicalChildren.Add(toolBar); + parent.VisualChildren.Add(toolBar); + + parent.InvalidateMeasure(); + } + } + } +} diff --git a/sources/editor/Stride.GameStudio.Avalonia/Themes/DefaultStyles.axaml b/sources/presentation/Stride.Core.Presentation.Avalonia/Themes/EditorStyles.axaml similarity index 97% rename from sources/editor/Stride.GameStudio.Avalonia/Themes/DefaultStyles.axaml rename to sources/presentation/Stride.Core.Presentation.Avalonia/Themes/EditorStyles.axaml index 8e77ebaefe..142092efcf 100644 --- a/sources/editor/Stride.GameStudio.Avalonia/Themes/DefaultStyles.axaml +++ b/sources/presentation/Stride.Core.Presentation.Avalonia/Themes/EditorStyles.axaml @@ -1,775 +1,772 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/presentation/Stride.Core.Presentation.Avalonia/Themes/HyperlinkStyle.axaml b/sources/presentation/Stride.Core.Presentation.Avalonia/Themes/HyperlinkStyle.axaml index f9aafea7c8..bfbdc26e85 100644 --- a/sources/presentation/Stride.Core.Presentation.Avalonia/Themes/HyperlinkStyle.axaml +++ b/sources/presentation/Stride.Core.Presentation.Avalonia/Themes/HyperlinkStyle.axaml @@ -1,18 +1,17 @@ - - - - + diff --git a/sources/presentation/Stride.Core.Presentation.Avalonia/Themes/ToolBarStyle.axaml b/sources/presentation/Stride.Core.Presentation.Avalonia/Themes/ToolBarStyle.axaml new file mode 100644 index 0000000000..bc2dc2516c --- /dev/null +++ b/sources/presentation/Stride.Core.Presentation.Avalonia/Themes/ToolBarStyle.axaml @@ -0,0 +1,23 @@ + + +