mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-12 13:28:33 +00:00
Sidebar - Added subitems support
This commit is contained in:
parent
229d93901b
commit
99a365be0b
@ -62,7 +62,15 @@ public abstract class RoutableScreen<TScreen> : ActivatableViewModelBase, IRouta
|
||||
|
||||
void IRoutableScreen.InternalChangeScreen(object? screen)
|
||||
{
|
||||
Screen = screen as TScreen;
|
||||
if (screen == null)
|
||||
{
|
||||
Screen = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (screen is not TScreen typedScreen)
|
||||
throw new ArtemisRoutingException($"Screen cannot be hosted, {screen.GetType().Name} is not assignable to {typeof(TScreen).Name}.");
|
||||
Screen = typedScreen;
|
||||
}
|
||||
|
||||
async Task IRoutableScreen.InternalOnNavigating(NavigationArguments args, CancellationToken cancellationToken)
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
|
||||
namespace Artemis.UI.Shared.Routing.ParameterParsers;
|
||||
|
||||
internal class IntParameterParser : IRouteParameterParser
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public bool IsMatch(RouteSegment segment, string source)
|
||||
{
|
||||
return int.TryParse(source, out _);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object GetValue(RouteSegment segment, string source)
|
||||
{
|
||||
return int.Parse(source);
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using DryIoc;
|
||||
|
||||
namespace Artemis.UI.Shared.Routing;
|
||||
|
||||
@ -48,11 +48,14 @@ public partial class RouteSegment
|
||||
|
||||
private IRouteParameterParser GetParameterParser(string parameterType)
|
||||
{
|
||||
if (parameterType == "guid")
|
||||
return new GuidParameterParser();
|
||||
return parameterType switch
|
||||
{
|
||||
"guid" => new GuidParameterParser(),
|
||||
"int" => new IntParameterParser(),
|
||||
_ => new StringParameterParser()
|
||||
};
|
||||
|
||||
// Default to a string parser which just returns the segment as is
|
||||
return new StringParameterParser();
|
||||
}
|
||||
|
||||
[GeneratedRegex(@"\{(\w+):(\w+)\}")]
|
||||
|
||||
@ -13,9 +13,15 @@
|
||||
|
||||
<!-- Add Styles Here -->
|
||||
<Style Selector="ListBox.sidebar-listbox ListBoxItem">
|
||||
<Setter Property="MinHeight" Value="35" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="MinHeight" Value="{DynamicResource NavigationViewItemOnLeftMinHeight}" />
|
||||
</Style>
|
||||
<Style Selector="ListBox.sidebar-listbox ContentPresenter">
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<!-- <Style Selector="ListBox.sidebar-listbox ContentPresenter"> -->
|
||||
<!-- <Setter Property="Margin" Value="0" /> -->
|
||||
<!-- </Style> -->
|
||||
|
||||
<Style Selector="ListBox.sidebar-listbox ListBoxItem /template/ ContentPresenter#PART_ContentPresenter">
|
||||
<Setter Property="MinHeight" Value="{DynamicResource NavigationViewItemOnLeftMinHeight}" />
|
||||
<Setter Property="CornerRadius" Value="{DynamicResource OverlayCornerRadius}" />
|
||||
</Style>
|
||||
</Styles>
|
||||
@ -43,4 +43,16 @@
|
||||
<ItemGroup>
|
||||
<AvaloniaResource Include="Assets\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="Screens\Workshop\Layout\LayoutDetailsView.axaml" />
|
||||
<AdditionalFiles Include="Screens\Workshop\Layout\LayoutListView.axaml" />
|
||||
<AdditionalFiles Include="Screens\Workshop\Profile\ProfileDetailsView.axaml" />
|
||||
<AdditionalFiles Include="Screens\Workshop\Profile\ProfileListView.axaml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<UpToDateCheckInput Remove="Screens\Workshop\Categories\Profile\ProfileDetailsView.axaml" />
|
||||
<UpToDateCheckInput Remove="Screens\Workshop\Categories\Profile\ProfileListView.axaml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Reactive;
|
||||
using Artemis.Core;
|
||||
@ -30,6 +31,8 @@ using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Routing;
|
||||
using Artemis.WebClient.Updating;
|
||||
using DryIoc;
|
||||
using DynamicData;
|
||||
using Material.Icons;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.DryIoc.Factories;
|
||||
@ -137,7 +140,7 @@ public class SidebarVmFactory : ISidebarVmFactory
|
||||
{
|
||||
_container = container;
|
||||
}
|
||||
|
||||
|
||||
public SidebarCategoryViewModel SidebarCategoryViewModel(ProfileCategory profileCategory)
|
||||
{
|
||||
return _container.Resolve<SidebarCategoryViewModel>(new object[] { profileCategory });
|
||||
|
||||
@ -5,6 +5,8 @@ using Artemis.UI.Screens.Settings;
|
||||
using Artemis.UI.Screens.Settings.Updating;
|
||||
using Artemis.UI.Screens.SurfaceEditor;
|
||||
using Artemis.UI.Screens.Workshop;
|
||||
using Artemis.UI.Screens.Workshop.Layout;
|
||||
using Artemis.UI.Screens.Workshop.Profile;
|
||||
using Artemis.UI.Shared.Routing;
|
||||
|
||||
namespace Artemis.UI.Routing;
|
||||
@ -14,8 +16,15 @@ public static class Routes
|
||||
public static List<IRouterRegistration> ArtemisRoutes = new()
|
||||
{
|
||||
new RouteRegistration<HomeViewModel>("home"),
|
||||
|
||||
new RouteRegistration<WorkshopViewModel>("workshop"),
|
||||
new RouteRegistration<ProfileListViewModel>("workshop/profiles/{page:int}"),
|
||||
new RouteRegistration<ProfileDetailsViewModel>("workshop/profiles/{entryId:guid}"),
|
||||
new RouteRegistration<LayoutListViewModel>("workshop/layouts/{page:int}"),
|
||||
new RouteRegistration<LayoutDetailsViewModel>("workshop/layouts/{entryId:guid}"),
|
||||
|
||||
new RouteRegistration<SurfaceEditorViewModel>("surface-editor"),
|
||||
|
||||
new RouteRegistration<SettingsViewModel>("settings")
|
||||
{
|
||||
Children = new List<IRouterRegistration>
|
||||
@ -25,7 +34,7 @@ public static class Routes
|
||||
new RouteRegistration<DevicesTabViewModel>("devices"),
|
||||
new RouteRegistration<ReleasesTabViewModel>("releases")
|
||||
{
|
||||
Children = new List<IRouterRegistration>()
|
||||
Children = new List<IRouterRegistration>
|
||||
{
|
||||
new RouteRegistration<ReleaseDetailsViewModel>("{releaseId:guid}")
|
||||
}
|
||||
|
||||
@ -99,7 +99,6 @@
|
||||
</Style>
|
||||
|
||||
<Style Selector="ListBox.sidebar-listbox ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="(i:Interaction.Behaviors)">
|
||||
<i:BehaviorCollectionTemplate>
|
||||
<i:BehaviorCollection>
|
||||
|
||||
@ -76,8 +76,8 @@
|
||||
x:Name="ProfileIcon"
|
||||
VerticalAlignment="Center"
|
||||
ConfigurationIcon="{CompiledBinding ProfileConfiguration.Icon}"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Width="22"
|
||||
Height="22"
|
||||
Margin="0 0 5 0">
|
||||
<shared:ProfileConfigurationIcon.Transitions>
|
||||
<Transitions>
|
||||
|
||||
@ -4,11 +4,11 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||
xmlns:vm="clr-namespace:Artemis.UI.Screens.Sidebar;assembly=Artemis.UI"
|
||||
x:DataType="vm:SidebarScreenViewModel"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Sidebar.SidebarScreenView">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<avalonia:MaterialIcon Kind="{CompiledBinding Icon}" Width="16" Height="16" />
|
||||
<TextBlock FontSize="12" Margin="10 0" VerticalAlignment="Center" Text="{CompiledBinding DisplayName}" />
|
||||
x:Class="Artemis.UI.Screens.Sidebar.SidebarScreenView"
|
||||
x:DataType="vm:SidebarScreenViewModel">
|
||||
<StackPanel Orientation="Horizontal" Background="Transparent" PointerReleased="InputElement_OnPointerReleased" DoubleTapped="InputElement_OnDoubleTapped">
|
||||
<avalonia:MaterialIcon Kind="{CompiledBinding Icon}" Width="18" Height="18" />
|
||||
<TextBlock Margin="10 0" VerticalAlignment="Center" FontSize="13" Text="{CompiledBinding DisplayName}" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -1,13 +1,25 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Sidebar;
|
||||
|
||||
public partial class SidebarScreenView : UserControl
|
||||
public partial class SidebarScreenView : ReactiveUserControl<SidebarScreenViewModel>
|
||||
{
|
||||
public SidebarScreenView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InputElement_OnPointerReleased(object? sender, PointerReleasedEventArgs e)
|
||||
{
|
||||
// if (ViewModel != null)
|
||||
// ViewModel.IsExpanded = !ViewModel.IsExpanded;
|
||||
}
|
||||
|
||||
private void InputElement_OnDoubleTapped(object? sender, TappedEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
@ -1,25 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Routing;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Avalonia.Threading;
|
||||
using Material.Icons;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Sidebar;
|
||||
|
||||
public class SidebarScreenViewModel : ViewModelBase
|
||||
{
|
||||
public SidebarScreenViewModel(MaterialIconKind icon, string displayName, string path)
|
||||
private bool _isExpanded;
|
||||
|
||||
public SidebarScreenViewModel(MaterialIconKind icon, string displayName, string path, string? rootPath = null, ObservableCollection<SidebarScreenViewModel>? screens = null)
|
||||
{
|
||||
Icon = icon;
|
||||
Path = path;
|
||||
RootPath = rootPath ?? path;
|
||||
DisplayName = displayName;
|
||||
Screens = screens ?? new ObservableCollection<SidebarScreenViewModel>();
|
||||
}
|
||||
|
||||
|
||||
public MaterialIconKind Icon { get; }
|
||||
public string Path { get; }
|
||||
public string RootPath { get; }
|
||||
|
||||
public ObservableCollection<SidebarScreenViewModel> Screens { get; }
|
||||
|
||||
public bool IsExpanded
|
||||
{
|
||||
get => _isExpanded;
|
||||
set => RaiseAndSetIfChanged(ref _isExpanded, value);
|
||||
}
|
||||
|
||||
public bool Matches(string? path)
|
||||
{
|
||||
if (path == null)
|
||||
return false;
|
||||
return path.StartsWith(Path, StringComparison.InvariantCultureIgnoreCase);
|
||||
return path.StartsWith(RootPath, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
public SidebarScreenViewModel? GetMatch(string path)
|
||||
{
|
||||
foreach (SidebarScreenViewModel sidebarScreenViewModel in Screens)
|
||||
{
|
||||
SidebarScreenViewModel? match = sidebarScreenViewModel.GetMatch(path);
|
||||
if (match != null)
|
||||
return match;
|
||||
}
|
||||
|
||||
return Screens.FirstOrDefault(s => s.Matches(path));
|
||||
}
|
||||
|
||||
public void ExpandIfRequired(SidebarScreenViewModel selected)
|
||||
{
|
||||
if (selected == this && Screens.Any())
|
||||
{
|
||||
IsExpanded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Screens.Contains(selected))
|
||||
IsExpanded = true;
|
||||
|
||||
foreach (SidebarScreenViewModel sidebarScreenViewModel in Screens)
|
||||
sidebarScreenViewModel.ExpandIfRequired(selected);
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:sidebar="clr-namespace:Artemis.UI.Screens.Sidebar"
|
||||
mc:Ignorable="d" d:DesignWidth="240" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Sidebar.SidebarView"
|
||||
@ -20,11 +20,23 @@
|
||||
</Grid>
|
||||
|
||||
<!-- Built-in screens -->
|
||||
<ListBox Classes="sidebar-listbox"
|
||||
Grid.Row="1"
|
||||
Margin="10 2"
|
||||
ItemsSource="{CompiledBinding SidebarScreens}"
|
||||
SelectedItem="{CompiledBinding SelectedSidebarScreen}" />
|
||||
<TreeView Grid.Row="1"
|
||||
Margin="10 2"
|
||||
ItemsSource="{CompiledBinding SidebarScreen.Screens}"
|
||||
SelectedItem="{CompiledBinding SelectedScreen}"
|
||||
ItemContainerTheme="{StaticResource MenuTreeViewItem}">
|
||||
<TreeView.Styles>
|
||||
<Style Selector="TreeViewItem">
|
||||
<Setter Property="IsExpanded" Value="{CompiledBinding IsExpanded, Mode=TwoWay, DataType=sidebar:SidebarScreenViewModel}" />
|
||||
</Style>
|
||||
</TreeView.Styles>
|
||||
<TreeView.ItemTemplate>
|
||||
<TreeDataTemplate ItemsSource="{CompiledBinding Screens}">
|
||||
<ContentControl Content="{CompiledBinding}" />
|
||||
</TreeDataTemplate>
|
||||
</TreeView.ItemTemplate>
|
||||
</TreeView>
|
||||
|
||||
<Border Grid.Row="2" Margin="8" Height="1" Background="{DynamicResource ButtonBorderBrush}"></Border>
|
||||
|
||||
<!-- Categories -->
|
||||
@ -41,51 +53,51 @@
|
||||
<!-- Bottom buttons -->
|
||||
<Border Grid.Row="4" Margin="8" Height="1" Background="{DynamicResource ButtonBorderBrush}"></Border>
|
||||
<WrapPanel Grid.Row="5" Orientation="Horizontal" HorizontalAlignment="Left" Margin="5 0 5 5">
|
||||
<controls:HyperlinkButton Classes="icon-button"
|
||||
Width="44"
|
||||
Height="44"
|
||||
ToolTip.Tip="View website"
|
||||
ToolTip.Placement="Top"
|
||||
ToolTip.VerticalOffset="-5"
|
||||
NavigateUri="https://artemis-rgb.com?mtm_campaign=artemis&mtm_kwd=sidebar">
|
||||
<ui:HyperlinkButton Classes="icon-button"
|
||||
Width="44"
|
||||
Height="44"
|
||||
ToolTip.Tip="View website"
|
||||
ToolTip.Placement="Top"
|
||||
ToolTip.VerticalOffset="-5"
|
||||
NavigateUri="https://artemis-rgb.com?mtm_campaign=artemis&mtm_kwd=sidebar">
|
||||
<avalonia:MaterialIcon Kind="Web" Width="20" Height="20" />
|
||||
</controls:HyperlinkButton>
|
||||
<controls:HyperlinkButton Classes="icon-button"
|
||||
Width="44"
|
||||
Height="44"
|
||||
ToolTip.Tip="View GitHub repository"
|
||||
ToolTip.Placement="Top"
|
||||
ToolTip.VerticalOffset="-5"
|
||||
NavigateUri="https://github.com/Artemis-RGB/Artemis">
|
||||
</ui:HyperlinkButton>
|
||||
<ui:HyperlinkButton Classes="icon-button"
|
||||
Width="44"
|
||||
Height="44"
|
||||
ToolTip.Tip="View GitHub repository"
|
||||
ToolTip.Placement="Top"
|
||||
ToolTip.VerticalOffset="-5"
|
||||
NavigateUri="https://github.com/Artemis-RGB/Artemis">
|
||||
<avalonia:MaterialIcon Kind="Github" Width="20" Height="20" />
|
||||
</controls:HyperlinkButton>
|
||||
<controls:HyperlinkButton Classes="icon-button"
|
||||
Width="44"
|
||||
Height="44"
|
||||
ToolTip.Tip="View Wiki"
|
||||
ToolTip.Placement="Top"
|
||||
ToolTip.VerticalOffset="-5"
|
||||
NavigateUri="https://wiki.artemis-rgb.com?mtm_campaign=artemis&mtm_kwd=sidebar">
|
||||
</ui:HyperlinkButton>
|
||||
<ui:HyperlinkButton Classes="icon-button"
|
||||
Width="44"
|
||||
Height="44"
|
||||
ToolTip.Tip="View Wiki"
|
||||
ToolTip.Placement="Top"
|
||||
ToolTip.VerticalOffset="-5"
|
||||
NavigateUri="https://wiki.artemis-rgb.com?mtm_campaign=artemis&mtm_kwd=sidebar">
|
||||
<avalonia:MaterialIcon Kind="BookOpenOutline" Width="20" Height="20" />
|
||||
</controls:HyperlinkButton>
|
||||
<controls:HyperlinkButton Classes="icon-button"
|
||||
Width="44"
|
||||
Height="44"
|
||||
ToolTip.Tip="Join our Discord"
|
||||
ToolTip.Placement="Top"
|
||||
ToolTip.VerticalOffset="-5"
|
||||
NavigateUri="https://discord.gg/S3MVaC9">
|
||||
</ui:HyperlinkButton>
|
||||
<ui:HyperlinkButton Classes="icon-button"
|
||||
Width="44"
|
||||
Height="44"
|
||||
ToolTip.Tip="Join our Discord"
|
||||
ToolTip.Placement="Top"
|
||||
ToolTip.VerticalOffset="-5"
|
||||
NavigateUri="https://discord.gg/S3MVaC9">
|
||||
<avalonia:MaterialIcon Kind="Chat" Width="20" Height="20" />
|
||||
</controls:HyperlinkButton>
|
||||
<controls:HyperlinkButton Classes="icon-button"
|
||||
Width="44"
|
||||
Height="44"
|
||||
ToolTip.Tip="View donation options"
|
||||
ToolTip.Placement="Top"
|
||||
ToolTip.VerticalOffset="-5"
|
||||
NavigateUri="https://wiki.artemis-rgb.com/en/donating?mtm_campaign=artemis&mtm_kwd=sidebar">
|
||||
</ui:HyperlinkButton>
|
||||
<ui:HyperlinkButton Classes="icon-button"
|
||||
Width="44"
|
||||
Height="44"
|
||||
ToolTip.Tip="View donation options"
|
||||
ToolTip.Placement="Top"
|
||||
ToolTip.VerticalOffset="-5"
|
||||
NavigateUri="https://wiki.artemis-rgb.com/en/donating?mtm_campaign=artemis&mtm_kwd=sidebar">
|
||||
<avalonia:MaterialIcon Kind="Gift" Width="20" Height="20" />
|
||||
</controls:HyperlinkButton>
|
||||
</ui:HyperlinkButton>
|
||||
</WrapPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
@ -23,34 +24,38 @@ namespace Artemis.UI.Screens.Sidebar;
|
||||
|
||||
public class SidebarViewModel : ActivatableViewModelBase
|
||||
{
|
||||
public const string ROOT_SCREEN = "root";
|
||||
|
||||
private readonly IRouter _router;
|
||||
private readonly IWindowService _windowService;
|
||||
private SidebarScreenViewModel? _selectedSidebarScreen;
|
||||
private ReadOnlyObservableCollection<SidebarCategoryViewModel> _sidebarCategories = new(new ObservableCollection<SidebarCategoryViewModel>());
|
||||
private SidebarScreenViewModel? _selectedScreen;
|
||||
|
||||
public SidebarViewModel(IRouter router, IProfileService profileService, IWindowService windowService, ISidebarVmFactory sidebarVmFactory)
|
||||
{
|
||||
_router = router;
|
||||
_windowService = windowService;
|
||||
|
||||
SidebarScreens = new ObservableCollection<SidebarScreenViewModel>
|
||||
SidebarScreen = new SidebarScreenViewModel(MaterialIconKind.Abacus, ROOT_SCREEN, "", null, new ObservableCollection<SidebarScreenViewModel>()
|
||||
{
|
||||
new(MaterialIconKind.Home, "Home", "home"),
|
||||
#if DEBUG
|
||||
new(MaterialIconKind.TestTube, "Workshop", "workshop"),
|
||||
#endif
|
||||
new(MaterialIconKind.HomeOutline, "Home", "home"),
|
||||
new(MaterialIconKind.TestTube, "Workshop", "workshop", null, new ObservableCollection<SidebarScreenViewModel>
|
||||
{
|
||||
new(MaterialIconKind.FolderVideo, "Profiles", "workshop/profiles/1", "workshop/profiles"),
|
||||
new(MaterialIconKind.KeyboardVariant, "Layouts", "workshop/layouts/1", "workshop/layouts"),
|
||||
}),
|
||||
new(MaterialIconKind.Devices, "Surface Editor", "surface-editor"),
|
||||
new(MaterialIconKind.Cog, "Settings", "settings")
|
||||
};
|
||||
new(MaterialIconKind.SettingsOutline, "Settings", "settings")
|
||||
});
|
||||
|
||||
AddCategory = ReactiveCommand.CreateFromTask(ExecuteAddCategory);
|
||||
this.WhenAnyValue(vm => vm.SelectedScreen).WhereNotNull().Subscribe(NavigateToScreen);
|
||||
this.WhenAnyValue(vm => vm.SelectedScreen).WhereNotNull().Subscribe(s => SidebarScreen.ExpandIfRequired(s));
|
||||
|
||||
SourceList<ProfileCategory> profileCategories = new();
|
||||
|
||||
this.WhenAnyValue(vm => vm.SelectedSidebarScreen).WhereNotNull().Subscribe(NavigateToScreen);
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
_router.CurrentPath.WhereNotNull().Subscribe(r => SelectedSidebarScreen = SidebarScreens.FirstOrDefault(s => s.Matches(r))).DisposeWith(d);
|
||||
_router.CurrentPath.WhereNotNull().Subscribe(r => SelectedScreen = SidebarScreen.GetMatch(r)).DisposeWith(d);
|
||||
|
||||
Observable.FromEventPattern<ProfileCategoryEventArgs>(x => profileService.ProfileCategoryAdded += x, x => profileService.ProfileCategoryAdded -= x)
|
||||
.Subscribe(e => profileCategories.Add(e.EventArgs.ProfileCategory))
|
||||
@ -75,11 +80,17 @@ public class SidebarViewModel : ActivatableViewModelBase
|
||||
.DisposeWith(d);
|
||||
|
||||
SidebarCategories = categoryViewModels;
|
||||
SelectedSidebarScreen = SidebarScreens.First();
|
||||
});
|
||||
SelectedScreen = SidebarScreen.Screens.First();
|
||||
}
|
||||
|
||||
public ObservableCollection<SidebarScreenViewModel> SidebarScreens { get; }
|
||||
public SidebarScreenViewModel SidebarScreen { get; }
|
||||
|
||||
public SidebarScreenViewModel? SelectedScreen
|
||||
{
|
||||
get => _selectedScreen;
|
||||
set => RaiseAndSetIfChanged(ref _selectedScreen, value);
|
||||
}
|
||||
|
||||
public ReadOnlyObservableCollection<SidebarCategoryViewModel> SidebarCategories
|
||||
{
|
||||
@ -87,12 +98,6 @@ public class SidebarViewModel : ActivatableViewModelBase
|
||||
set => RaiseAndSetIfChanged(ref _sidebarCategories, value);
|
||||
}
|
||||
|
||||
public SidebarScreenViewModel? SelectedSidebarScreen
|
||||
{
|
||||
get => _selectedSidebarScreen;
|
||||
set => RaiseAndSetIfChanged(ref _selectedSidebarScreen, value);
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> AddCategory { get; }
|
||||
|
||||
private async Task ExecuteAddCategory()
|
||||
@ -112,7 +117,7 @@ public class SidebarViewModel : ActivatableViewModelBase
|
||||
{
|
||||
try
|
||||
{
|
||||
await _router.Navigate(sidebarScreenViewModel.Path, new RouterNavigationOptions {IgnoreOnPartialMatch = true});
|
||||
await _router.Navigate(sidebarScreenViewModel.Path);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:ui="clr-namespace:Artemis.UI"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.Layout.LayoutDetailsView">
|
||||
<Border Classes="router-container">
|
||||
<Grid ColumnDefinitions="300,*" Margin="10">
|
||||
<Border Classes="card-condensed" Grid.Column="0" Margin="0 0 10 0">
|
||||
<TextBlock>Side panel</TextBlock>
|
||||
</Border>
|
||||
|
||||
<Border Classes="card-condensed" Grid.Column="1">
|
||||
<TextBlock>Main panel</TextBlock>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
</UserControl>
|
||||
@ -0,0 +1,17 @@
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Layout;
|
||||
|
||||
public partial class LayoutDetailsView : ReactiveUserControl<LayoutDetailsViewModel>
|
||||
{
|
||||
public LayoutDetailsView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
using Artemis.UI.Shared;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Layout;
|
||||
|
||||
public class LayoutDetailsViewModel : ActivatableViewModelBase
|
||||
{
|
||||
|
||||
}
|
||||
22
src/Artemis.UI/Screens/Workshop/Layout/LayoutListView.axaml
Normal file
22
src/Artemis.UI/Screens/Workshop/Layout/LayoutListView.axaml
Normal file
@ -0,0 +1,22 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:layout="clr-namespace:Artemis.UI.Screens.Workshop.Layout"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.Layout.LayoutListView"
|
||||
x:DataType="layout:LayoutListViewModel">
|
||||
<Border Classes="router-container">
|
||||
<Grid ColumnDefinitions="300,*" Margin="10">
|
||||
<Border Classes="card-condensed" Grid.Column="0" Margin="0 0 10 0">
|
||||
<TextBlock>Side panel</TextBlock>
|
||||
</Border>
|
||||
|
||||
<Border Classes="card-condensed" Grid.Column="1">
|
||||
<TextBlock>
|
||||
<Run Text="Layout list main panel, page: " /><Run Text="{CompiledBinding Page}"></Run>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@ -0,0 +1,17 @@
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Layout;
|
||||
|
||||
public partial class LayoutListView : ReactiveUserControl<LayoutListViewModel>
|
||||
{
|
||||
public LayoutListView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Routing;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Layout;
|
||||
|
||||
public class LayoutListViewModel : RoutableScreen<ActivatableViewModelBase, WorkshopListParameters>, IMainScreenViewModel
|
||||
{
|
||||
private int _page;
|
||||
|
||||
public int Page
|
||||
{
|
||||
get => _page;
|
||||
set => RaiseAndSetIfChanged(ref _page, value);
|
||||
}
|
||||
|
||||
public override Task OnNavigating(WorkshopListParameters parameters, NavigationArguments args, CancellationToken cancellationToken)
|
||||
{
|
||||
Page = Math.Max(1, parameters.Page);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public ViewModelBase? TitleBarViewModel => null;
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.Profile.ProfileDetailsView">
|
||||
Welcome to Avalonia!
|
||||
</UserControl>
|
||||
@ -0,0 +1,17 @@
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Profile;
|
||||
|
||||
public partial class ProfileDetailsView : ReactiveUserControl<ProfileDetailsViewModel>
|
||||
{
|
||||
public ProfileDetailsView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
using Artemis.UI.Shared;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Profile;
|
||||
|
||||
public class ProfileDetailsViewModel : ActivatableViewModelBase
|
||||
{
|
||||
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:profile="clr-namespace:Artemis.UI.Screens.Workshop.Profile"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.Profile.ProfileListView"
|
||||
x:DataType="profile:ProfileListViewModel">
|
||||
<Border Classes="router-container">
|
||||
<Grid ColumnDefinitions="300,*" Margin="10">
|
||||
<Border Classes="card-condensed" Grid.Column="0" Margin="0 0 10 0">
|
||||
<TextBlock>Side panel</TextBlock>
|
||||
</Border>
|
||||
|
||||
<Border Classes="card-condensed" Grid.Column="1">
|
||||
<TextBlock>
|
||||
<Run Text="Profile list main panel, page: " /><Run Text="{CompiledBinding Page}"></Run>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@ -0,0 +1,17 @@
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Profile;
|
||||
|
||||
public partial class ProfileListView : ReactiveUserControl<ProfileListViewModel>
|
||||
{
|
||||
public ProfileListView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Routing;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Profile;
|
||||
|
||||
public class ProfileListViewModel : RoutableScreen<ActivatableViewModelBase, WorkshopListParameters>, IMainScreenViewModel
|
||||
{
|
||||
private int _page;
|
||||
|
||||
public int Page
|
||||
{
|
||||
get => _page;
|
||||
set => RaiseAndSetIfChanged(ref _page, value);
|
||||
}
|
||||
|
||||
public override Task OnNavigating(WorkshopListParameters parameters, NavigationArguments args, CancellationToken cancellationToken)
|
||||
{
|
||||
Page = Math.Max(1, parameters.Page);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public ViewModelBase? TitleBarViewModel => null;
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
namespace Artemis.UI.Screens.Workshop;
|
||||
|
||||
public class WorkshopListParameters
|
||||
{
|
||||
public int Page { get; set; }
|
||||
}
|
||||
@ -2,35 +2,13 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:builders="clr-namespace:Artemis.UI.Shared.Services.Builders;assembly=Artemis.UI.Shared"
|
||||
xmlns:controls1="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:attachedProperties="clr-namespace:Artemis.UI.Shared.AttachedProperties;assembly=Artemis.UI.Shared"
|
||||
xmlns:workshop="clr-namespace:Artemis.UI.Screens.Workshop"
|
||||
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
|
||||
xmlns:gradientPicker="clr-namespace:Artemis.UI.Shared.Controls.GradientPicker;assembly=Artemis.UI.Shared"
|
||||
xmlns:materialIconPicker="clr-namespace:Artemis.UI.Shared.MaterialIconPicker;assembly=Artemis.UI.Shared"
|
||||
xmlns:workshop1="clr-namespace:Artemis.WebClient.Workshop;assembly=Artemis.WebClient.Workshop"
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:ui="clr-namespace:Artemis.UI"
|
||||
mc:Ignorable="d" d:DesignWidth="800"
|
||||
x:Class="Artemis.UI.Screens.Workshop.WorkshopView"
|
||||
x:DataType="workshop:WorkshopViewModel">
|
||||
<Border Classes="router-container">
|
||||
<Grid ColumnDefinitions="300,*" Margin="0 10">
|
||||
<Border Classes="card-condensed" Grid.Column="0" Margin="0 0 10 0">
|
||||
<ListBox ItemsSource="{CompiledBinding Test}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="workshop1:IGetEntries_Entries_Nodes">
|
||||
<Panel>
|
||||
<StackPanel Margin="4">
|
||||
<TextBlock Text="{CompiledBinding Name}" VerticalAlignment="Center" />
|
||||
<TextBlock Text="{CompiledBinding Author}" VerticalAlignment="Center" Classes="subtitle" FontSize="13" />
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Border>
|
||||
<ContentControl Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Right" Content="{CompiledBinding CurrentUserViewModel}" Margin="8"></ContentControl>
|
||||
</Grid>
|
||||
<TextBlock>Workshop overview</TextBlock>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@ -1,4 +1,3 @@
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop;
|
||||
@ -9,5 +8,4 @@ public partial class WorkshopView : ReactiveUserControl<WorkshopViewModel>
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,55 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Screens.Workshop.CurrentUser;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Artemis.UI.Shared.Services.Builders;
|
||||
using Artemis.WebClient.Workshop;
|
||||
using Avalonia.Input;
|
||||
using ReactiveUI;
|
||||
using SkiaSharp;
|
||||
using StrawberryShake;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Routing;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop;
|
||||
|
||||
public class WorkshopViewModel : ActivatableViewModelBase, IMainScreenViewModel
|
||||
public class WorkshopViewModel : RoutableScreen<object>, IMainScreenViewModel
|
||||
{
|
||||
private readonly IWorkshopClient _workshopClient;
|
||||
|
||||
public WorkshopViewModel(IScreen hostScreen, IWorkshopClient workshopClient, CurrentUserViewModel currentUserViewModel) : base(hostScreen, "workshop")
|
||||
public WorkshopViewModel()
|
||||
{
|
||||
CurrentUserViewModel = currentUserViewModel;
|
||||
_workshopClient = workshopClient;
|
||||
DisplayName = "Workshop";
|
||||
|
||||
Task.Run(() => GetEntries());
|
||||
}
|
||||
|
||||
public ObservableCollection<IGetEntries_Entries_Nodes> Test { get; set; } = new();
|
||||
public CurrentUserViewModel CurrentUserViewModel { get; set; }
|
||||
|
||||
private async Task GetEntries()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
IOperationResult<IGetEntriesResult> entries = await _workshopClient.GetEntries.ExecuteAsync();
|
||||
if (entries.Data?.Entries?.Nodes == null)
|
||||
return;
|
||||
|
||||
foreach (IGetEntries_Entries_Nodes getEntriesEntriesNodes in entries.Data.Entries.Nodes)
|
||||
{
|
||||
Console.WriteLine(getEntriesEntriesNodes);
|
||||
Test.Add(getEntriesEntriesNodes);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
public ViewModelBase? TitleBarViewModel => null;
|
||||
}
|
||||
@ -8,4 +8,12 @@
|
||||
|
||||
<!-- <FluentTheme Mode="Dark"></FluentTheme> -->
|
||||
<StyleInclude Source="avares://Artemis.UI.Shared/Styles/Artemis.axaml" />
|
||||
|
||||
<Styles.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<MergeResourceInclude Source="TreeView.axaml"></MergeResourceInclude>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Styles.Resources>
|
||||
</Styles>
|
||||
122
src/Artemis.UI/Styles/TreeView.axaml
Normal file
122
src/Artemis.UI/Styles/TreeView.axaml
Normal file
@ -0,0 +1,122 @@
|
||||
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:converters="clr-namespace:Avalonia.Controls.Converters;assembly=Avalonia.Controls"
|
||||
xmlns:ui="using:FluentAvalonia.UI.Controls"
|
||||
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||
x:CompileBindings="True">
|
||||
<Design.PreviewWith>
|
||||
<Border Padding="30" MinWidth="350">
|
||||
<TreeView ItemContainerTheme="{StaticResource MenuTreeViewItem}">
|
||||
<TreeViewItem>
|
||||
<TreeViewItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<avalonia:MaterialIcon Kind="Home" Width="16" Height="16" />
|
||||
<TextBlock FontSize="12" Margin="10 0" VerticalAlignment="Center" Text="Home" />
|
||||
</StackPanel>
|
||||
</TreeViewItem.Header>
|
||||
</TreeViewItem>
|
||||
<TreeViewItem IsExpanded="True">
|
||||
<TreeViewItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<avalonia:MaterialIcon Kind="TestTube" Width="16" Height="16" />
|
||||
<TextBlock FontSize="12" Margin="10 0" VerticalAlignment="Center" Text="Workshop" />
|
||||
</StackPanel>
|
||||
</TreeViewItem.Header>
|
||||
<TreeViewItem>
|
||||
<TreeViewItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<avalonia:MaterialIcon Kind="FolderVideo" Width="16" Height="16" />
|
||||
<TextBlock FontSize="12" Margin="10 0" VerticalAlignment="Center" Text="Profiles" />
|
||||
</StackPanel>
|
||||
</TreeViewItem.Header>
|
||||
</TreeViewItem>
|
||||
<TreeViewItem>
|
||||
<TreeViewItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<avalonia:MaterialIcon Kind="KeyboardVariant" Width="16" Height="16" />
|
||||
<TextBlock FontSize="12" Margin="10 0" VerticalAlignment="Center" Text="Layouts" />
|
||||
</StackPanel>
|
||||
</TreeViewItem.Header>
|
||||
</TreeViewItem>
|
||||
</TreeViewItem>
|
||||
<TreeViewItem>
|
||||
<TreeViewItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<avalonia:MaterialIcon Kind="Devices" Width="16" Height="16" />
|
||||
<TextBlock FontSize="12" Margin="10 0" VerticalAlignment="Center" Text="Surface Editor" />
|
||||
</StackPanel>
|
||||
</TreeViewItem.Header>
|
||||
</TreeViewItem>
|
||||
<TreeViewItem>
|
||||
<TreeViewItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<avalonia:MaterialIcon Kind="Cog" Width="16" Height="16" />
|
||||
<TextBlock FontSize="12" Margin="10 0" VerticalAlignment="Center" Text="Settings" />
|
||||
</StackPanel>
|
||||
</TreeViewItem.Header>
|
||||
</TreeViewItem>
|
||||
</TreeView>
|
||||
</Border>
|
||||
</Design.PreviewWith>
|
||||
|
||||
<x:Double x:Key="TreeViewItemIndent">31</x:Double>
|
||||
<x:Double x:Key="TreeViewItemExpandCollapseChevronSize">12</x:Double>
|
||||
<Thickness x:Key="TreeViewItemExpandCollapseChevronMargin">12, 0, 12, 0</Thickness>
|
||||
<converters:MarginMultiplierConverter Indent="{StaticResource TreeViewItemIndent}"
|
||||
Left="True"
|
||||
x:Key="TreeViewItemLeftMarginConverter" />
|
||||
|
||||
<ControlTheme TargetType="TreeViewItem" x:Key="MenuTreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}">
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate>
|
||||
<StackPanel>
|
||||
<Border Name="PART_LayoutRoot"
|
||||
Classes="TreeViewItemLayoutRoot"
|
||||
Focusable="True"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
MinHeight="{DynamicResource NavigationViewItemOnLeftMinHeight}"
|
||||
CornerRadius="{DynamicResource OverlayCornerRadius}"
|
||||
TemplatedControl.IsTemplateFocusTarget="True"
|
||||
Margin="2">
|
||||
<Panel>
|
||||
<Grid Name="PART_Header"
|
||||
ColumnDefinitions="12, *, Auto"
|
||||
Margin="{TemplateBinding Level, Mode=OneWay, Converter={StaticResource TreeViewItemLeftMarginConverter}}">
|
||||
<Rectangle Name="SelectionIndicator"
|
||||
Width="3"
|
||||
Height="16"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
RadiusX="2"
|
||||
RadiusY="2"
|
||||
IsVisible="False"
|
||||
Fill="{DynamicResource TreeViewItemSelectionIndicatorForeground}" />
|
||||
|
||||
<ContentPresenter Name="PART_HeaderPresenter"
|
||||
Grid.Column="1"
|
||||
Focusable="False"
|
||||
Content="{TemplateBinding Header}"
|
||||
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalAlignment}"
|
||||
Margin="{TemplateBinding Padding}" />
|
||||
<Panel Name="PART_ExpandCollapseChevronContainer" Grid.Column="2">
|
||||
<ToggleButton Name="PART_ExpandCollapseChevron"
|
||||
Theme="{StaticResource TreeViewChevronButton}"
|
||||
Focusable="False"
|
||||
Margin="{StaticResource TreeViewItemExpandCollapseChevronMargin}"
|
||||
IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" />
|
||||
</Panel>
|
||||
</Grid>
|
||||
</Panel>
|
||||
</Border>
|
||||
<ItemsPresenter Name="PART_ItemsPresenter"
|
||||
IsVisible="{TemplateBinding IsExpanded}"
|
||||
ItemsPanel="{TemplateBinding ItemsPanel}" />
|
||||
</StackPanel>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
</ControlTheme>
|
||||
</ResourceDictionary>
|
||||
Loading…
x
Reference in New Issue
Block a user