Add design mode

This commit is contained in:
Robert committed 2026-07-31 15:30:11 +02:00
1 parent 5a681a0480
commit eb812cb5e1
50 files changed
+782 -257

No files matched your search

@@ -0,0 +1,46 @@
<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.ProfileEditor.DesignPanels.Section.AddConfigurationItemDesignView">
<ListBox SelectionChanged="SelectingItemsControl_OnSelectionChanged">
<ListBoxItem x:Name="BooleanInputItem">
<StackPanel Margin="0 4">
<TextBlock>Boolean input</TextBlock>
<TextBlock Classes="subtitle">Allows the user enable/disable something via a toggle</TextBlock>
</StackPanel>
</ListBoxItem>
<ListBoxItem x:Name="ColorGradientInputItem">
<StackPanel Margin="0 4">
<TextBlock>Color gradient input</TextBlock>
<TextBlock Classes="subtitle">Allows the user create a color gradient</TextBlock>
</StackPanel>
</ListBoxItem>
<ListBoxItem x:Name="ColorInputItem">
<StackPanel Margin="0 4">
<TextBlock>Color input</TextBlock>
<TextBlock Classes="subtitle">Allows the user to select a color</TextBlock>
</StackPanel>
</ListBoxItem>
<ListBoxItem x:Name="NumericInputItem">
<StackPanel Margin="0 4">
<TextBlock>Numeric input</TextBlock>
<TextBlock Classes="subtitle">Allows the user to a number in either a box or via a slider</TextBlock>
</StackPanel>
</ListBoxItem>
<ListBoxItem x:Name="TextInputItem">
<StackPanel Margin="0 4">
<TextBlock>Text input</TextBlock>
<TextBlock Classes="subtitle">Allows the user to input arbitrary text</TextBlock>
</StackPanel>
</ListBoxItem>
<ListBoxItem x:Name="TextBlockItem">
<StackPanel Margin="0 4">
<TextBlock>Text block</TextBlock>
<TextBlock Classes="subtitle">A simple piece of text, useful for explaining things</TextBlock>
</StackPanel>
</ListBoxItem>
</ListBox>
</UserControl>
@@ -0,0 +1,31 @@
using Artemis.Core;
using Avalonia.Controls;
using ReactiveUI.Avalonia;
namespace Artemis.UI.Screens.ProfileEditor.DesignPanels.Section;
public partial class AddConfigurationItemDesignView : ReactiveUserControl<AddConfigurationItemDesignViewModel>
{
public AddConfigurationItemDesignView()
{
InitializeComponent();
}
private void SelectingItemsControl_OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
{
if (e.AddedItems[0] is not ListBoxItem item) return;
if (item == BooleanInputItem)
ViewModel?.AddItem(new ConfigurationBooleanItem {Name = "New Boolean"});
else if (item == ColorGradientInputItem)
ViewModel?.AddItem(new ConfigurationColorGradientItem {Name = "New Gradient"});
else if (item == ColorInputItem)
ViewModel?.AddItem(new ConfigurationSKColorItem {Name = "New Color"});
else if (item == NumericInputItem)
ViewModel?.AddItem(new ConfigurationNumericItem {Name = "New Numeric"});
else if (item == TextInputItem)
ViewModel?.AddItem(new ConfigurationStringItem {Name = "New String"});
else if (item == TextBlockItem)
ViewModel?.AddItem(new ConfigurationTextItem {Text = "New Text"});
}
}
@@ -0,0 +1,21 @@
using Artemis.Core;
using Artemis.UI.Shared;
using FluentAvalonia.UI.Controls;
namespace Artemis.UI.Screens.ProfileEditor.DesignPanels.Section;
public class AddConfigurationItemDesignViewModel : ContentDialogViewModelBase
{
public AddConfigurationItemDesignViewModel(ConfigurationSection section)
{
Section = section;
}
public ConfigurationSection Section { get; }
public void AddItem(IConfigurationItem item)
{
Section.Items.Add(item);
ContentDialog?.Hide(ContentDialogResult.Primary);
}
}
@@ -3,20 +3,25 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:section="clr-namespace:Artemis.UI.Screens.ProfileEditor.DesignPanels.Section"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.ProfileEditor.DesignPanels.Section.ConfigurationSectionDesignView"
x:DataType="section:ConfigurationSectionDesignViewModel">
<Border Classes="card" VerticalAlignment="Top">
<StackPanel>
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}" Text="{CompiledBinding ConfigurationSection.Name}"/>
<Grid ColumnDefinitions="*, Auto" ColumnSpacing="8">
<TextBox Grid.Row="0" Grid.Column="0" Text="{CompiledBinding ConfigurationSection.Name}" Watermark="Section name" FontSize="18" />
<Button Grid.Row="0" Grid.Column="1" ToolTip.Tip="Remove section" Classes="icon-button-outlined" Command="{CompiledBinding RemoveSection}">
<avalonia:MaterialIcon Kind="Trash" />
</Button>
</Grid>
<Border Classes="card-separator" />
<ItemsControl ItemsSource="{CompiledBinding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Classes="device-view-model-container">
<!-- Your existing item template goes here -->
<ContentControl Content="{CompiledBinding}"/>
<ContentControl Content="{CompiledBinding}" />
<Border Classes="card-separator" Name="Separator" />
</StackPanel>
</DataTemplate>
@@ -29,6 +34,10 @@
</Styles>
</ItemsControl.Styles>
</ItemsControl>
<Button HorizontalAlignment="Stretch" Margin="0 8 0 0" ToolTip.Tip="Add item" Command="{CompiledBinding AddItem}">
<avalonia:MaterialIcon Kind="Add" />
</Button>
</StackPanel>
</Border>
</UserControl>
</UserControl>
@@ -1,33 +1,72 @@
using System.Collections.ObjectModel;
using System;
using System.Collections.ObjectModel;
using System.Reactive.Disposables.Fluent;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.UI.Screens.ProfileEditor.DesignPanels.Items;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using DynamicData;
using DynamicData.Binding;
using PropertyChanged.SourceGenerator;
using ReactiveUI;
namespace Artemis.UI.Screens.ProfileEditor.DesignPanels.Section;
public class ConfigurationSectionDesignViewModel : ActivatableViewModelBase
public partial class ConfigurationSectionDesignViewModel : ActivatableViewModelBase
{
public ConfigurationSection ConfigurationSection { get; }
public ObservableCollection<ActivatableViewModelBase> Items { get; }
private readonly IWindowService _windowService;
[Notify] private ReadOnlyObservableCollection<ConfigurationItemDesignViewModel>? _items;
public ConfigurationSectionDesignViewModel(ConfigurationSection configurationSection)
public ConfigurationSectionDesignViewModel(ConfigurationSection configurationSection, IWindowService windowService)
{
_windowService = windowService;
ConfigurationSection = configurationSection;
Items = [];
foreach (IConfigurationItem item in ConfigurationSection.Items)
this.WhenActivated(d =>
{
if (item is ConfigurationTextItem textItem)
Items.Add(new ConfigurationTextItemDesignViewModel(textItem));
else if (item is ConfigurationStringItem stringItem)
Items.Add(new ConfigurationStringItemDesignViewModel(stringItem));
else if (item is ConfigurationBooleanItem booleanItem)
Items.Add(new ConfigurationBooleanItemDesignViewModel(booleanItem));
else if (item is ConfigurationNumericItem numberItem)
Items.Add(new ConfigurationNumericItemDesignViewModel(numberItem));
else if (item is ConfigurationSKColorItem colorItem)
Items.Add(new ConfigurationSKColorItemDesignViewModel(colorItem));
else if (item is ConfigurationColorGradientItem colorGradientItem)
Items.Add(new ConfigurationColorGradientItemDesignViewModel(colorGradientItem));
}
ConfigurationSection.Items
.ToObservableChangeSet()
.Transform(CreateViewModelForItem)
.Bind(out ReadOnlyObservableCollection<ConfigurationItemDesignViewModel> items)
.Subscribe()
.DisposeWith(d);
Items = items;
});
}
public ConfigurationSection ConfigurationSection { get; }
public async Task RemoveSection()
{
ConfigurationSection.ProfileConfiguration.ConfigurationSections.Remove(ConfigurationSection);
}
public async Task AddItem()
{
await _windowService.CreateContentDialog()
.WithTitle("Add Item")
.WithViewModel(out AddConfigurationItemDesignViewModel _, ConfigurationSection)
.ShowAsync();
}
public void RemoveItem(ConfigurationItemDesignViewModel viewModel)
{
ConfigurationSection.Items.Remove(viewModel.Item);
}
private ConfigurationItemDesignViewModel CreateViewModelForItem(IConfigurationItem item)
{
return item switch
{
ConfigurationTextItem textItem => new ConfigurationTextItemDesignViewModel(textItem, ConfigurationSection),
ConfigurationStringItem stringItem => new ConfigurationStringItemDesignViewModel(stringItem, ConfigurationSection),
ConfigurationBooleanItem booleanItem => new ConfigurationBooleanItemDesignViewModel(booleanItem, ConfigurationSection),
ConfigurationNumericItem numberItem => new ConfigurationNumericItemDesignViewModel(numberItem, ConfigurationSection),
ConfigurationSKColorItem colorItem => new ConfigurationSKColorItemDesignViewModel(colorItem, ConfigurationSection),
ConfigurationColorGradientItem colorGradientItem => new ConfigurationColorGradientItemDesignViewModel(colorGradientItem, ConfigurationSection),
_ => throw new ArgumentException($"Unknown configuration item type: {item.GetType()}")
};
}
}