1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Profile settigns - Added activation condition visual scripting

This commit is contained in:
Robert 2022-05-28 19:24:37 +02:00
parent bcd03becc7
commit d563d17270
8 changed files with 173 additions and 179 deletions

View File

@ -27,6 +27,7 @@
<entry key="Artemis.UI/Screens/Device/Tabs/InputMappingsTabView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Artemis.UI/Screens/Device/Tabs/InputMappingsTabView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
<entry key="Artemis.UI/Screens/Plugins/PluginFeatureView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Artemis.UI/Screens/Plugins/PluginFeatureView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
<entry key="Artemis.UI/Screens/Plugins/PluginSettingsView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Artemis.UI/Screens/Plugins/PluginSettingsView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
<entry key="Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/StaticConditionView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
<entry key="Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
<entry key="Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/CategoryAdaptionHintView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/CategoryAdaptionHintView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
<entry key="Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/DeviceAdaptionHintView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/DeviceAdaptionHintView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
@ -54,7 +55,7 @@
<entry key="Artemis.UI/Screens/Root/SplashView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Artemis.UI/Screens/Root/SplashView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
<entry key="Artemis.UI/Screens/Settings/Tabs/GeneralTabView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Artemis.UI/Screens/Settings/Tabs/GeneralTabView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
<entry key="Artemis.UI/Screens/Sidebar/ContentDialogs/SidebarCategoryEditView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Artemis.UI/Screens/Sidebar/ContentDialogs/SidebarCategoryEditView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
<entry key="Artemis.UI/Screens/Sidebar/Dialogs/ProfileConfigurationEditView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Artemis.UI/Screens/Sidebar/Dialogs/ProfileConfigurationEditView.axaml" value="Artemis.UI.Windows/Artemis.UI.Windows.csproj" />
<entry key="Artemis.UI/Screens/Sidebar/SidebarCategoryView.axaml" value="Artemis.UI.Windows/Artemis.UI.Windows.csproj" /> <entry key="Artemis.UI/Screens/Sidebar/SidebarCategoryView.axaml" value="Artemis.UI.Windows/Artemis.UI.Windows.csproj" />
<entry key="Artemis.UI/Screens/Sidebar/SidebarProfileConfigurationView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Artemis.UI/Screens/Sidebar/SidebarProfileConfigurationView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
<entry key="Artemis.UI/Screens/Sidebar/SidebarView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Artemis.UI/Screens/Sidebar/SidebarView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
@ -65,6 +66,7 @@
<entry key="Artemis.UI/Screens/VisualScripting/NodeScriptView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Artemis.UI/Screens/VisualScripting/NodeScriptView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
<entry key="Artemis.UI/Screens/VisualScripting/NodeScriptWindowView.axaml" value="Artemis.UI.Windows/Artemis.UI.Windows.csproj" /> <entry key="Artemis.UI/Screens/VisualScripting/NodeScriptWindowView.axaml" value="Artemis.UI.Windows/Artemis.UI.Windows.csproj" />
<entry key="Artemis.UI/Screens/VisualScripting/NodeView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Artemis.UI/Screens/VisualScripting/NodeView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
<entry key="Artemis.UI/Screens/Workshop/WorkshopView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
<entry key="Avalonia/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml" value="Avalonia/Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Avalonia/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml" value="Avalonia/Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
<entry key="Avalonia/Artemis.UI/Styles/Artemis.axaml" value="Avalonia/Artemis.UI.Linux/Artemis.UI.Linux.csproj" /> <entry key="Avalonia/Artemis.UI/Styles/Artemis.axaml" value="Avalonia/Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
</map> </map>

View File

@ -134,7 +134,7 @@ namespace Artemis.Core
/// Gets the data model condition that must evaluate to <see langword="true" /> for this profile to be activated /// Gets the data model condition that must evaluate to <see langword="true" /> for this profile to be activated
/// alongside any activation requirements of the <see cref="Module" />, if set /// alongside any activation requirements of the <see cref="Module" />, if set
/// </summary> /// </summary>
public NodeScript<bool> ActivationCondition { get; set; } public NodeScript<bool> ActivationCondition { get; }
/// <summary> /// <summary>
/// Gets or sets the module this profile uses /// Gets or sets the module this profile uses
@ -241,11 +241,7 @@ namespace Artemis.Core
Icon.Load(); Icon.Load();
ActivationCondition.Dispose(); ActivationCondition.LoadFromEntity(Entity.ActivationCondition);
ActivationCondition = Entity.ActivationCondition != null
? new NodeScript<bool>("Activate profile", "Whether or not the profile should be active", Entity.ActivationCondition, this)
: new NodeScript<bool>("Activate profile", "Whether or not the profile should be active", this);
EnableHotkey = Entity.EnableHotkey != null ? new Hotkey(Entity.EnableHotkey) : null; EnableHotkey = Entity.EnableHotkey != null ? new Hotkey(Entity.EnableHotkey) : null;
DisableHotkey = Entity.DisableHotkey != null ? new Hotkey(Entity.DisableHotkey) : null; DisableHotkey = Entity.DisableHotkey != null ? new Hotkey(Entity.DisableHotkey) : null;
} }
@ -265,8 +261,8 @@ namespace Artemis.Core
Icon.Save(); Icon.Save();
ActivationCondition?.Save(); ActivationCondition.Save();
Entity.ActivationCondition = ActivationCondition?.Entity; Entity.ActivationCondition = ActivationCondition.Entity;
EnableHotkey?.Save(); EnableHotkey?.Save();
Entity.EnableHotkey = EnableHotkey?.Entity; Entity.EnableHotkey = EnableHotkey?.Entity;

View File

@ -276,13 +276,8 @@ namespace Artemis.Core
{ {
Entity.Name = Name; Entity.Name = Name;
Entity.Description = Description; Entity.Description = Description;
Entity.Nodes.Clear(); Entity.Nodes.Clear();
// No need to save the exit node if that's all there is
if (Nodes.Count() == 1)
return;
foreach (INode node in Nodes) foreach (INode node in Nodes)
{ {
NodeEntity nodeEntity = new() NodeEntity nodeEntity = new()

View File

@ -36,7 +36,7 @@
</Style> </Style>
<Style Selector="Border.card"> <Style Selector="Border.card">
<Setter Property="Padding" Value="25" /> <Setter Property="Padding" Value="16" />
<Setter Property="Background" Value="{DynamicResource ControlFillColorDefaultBrush}" /> <Setter Property="Background" Value="{DynamicResource ControlFillColorDefaultBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource CardStrokeColorDefaultBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource CardStrokeColorDefaultBrush}" />
<Setter Property="BorderThickness" Value="1" /> <Setter Property="BorderThickness" Value="1" />
@ -44,7 +44,7 @@
</Style> </Style>
<Style Selector="Border.card-condensed"> <Style Selector="Border.card-condensed">
<Setter Property="Padding" Value="10" /> <Setter Property="Padding" Value="8" />
<Setter Property="Background" Value="{DynamicResource ControlFillColorDefaultBrush}" /> <Setter Property="Background" Value="{DynamicResource ControlFillColorDefaultBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource CardStrokeColorDefaultBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource CardStrokeColorDefaultBrush}" />
<Setter Property="BorderThickness" Value="1" /> <Setter Property="BorderThickness" Value="1" />

View File

@ -5,17 +5,17 @@
xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core" xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core"
xmlns:converters="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared" xmlns:converters="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:svg="clr-namespace:Avalonia.Svg.Skia;assembly=Avalonia.Svg.Skia"
xmlns:local="clr-namespace:Artemis.UI.Screens.Sidebar" xmlns:local="clr-namespace:Artemis.UI.Screens.Sidebar"
xmlns:controls1="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:controls1="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared" xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="850" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="850"
x:Class="Artemis.UI.Screens.Sidebar.ProfileConfigurationEditView" x:Class="Artemis.UI.Screens.Sidebar.ProfileConfigurationEditView"
Title="{Binding DisplayName}" x:DataType="local:ProfileConfigurationEditViewModel"
Title="{CompiledBinding DisplayName}"
Icon="/Assets/Images/Logo/application.ico" Icon="/Assets/Images/Logo/application.ico"
Width="800" Width="800"
MinWidth="420" MinWidth="420"
Height="850"> Height="975">
<Window.Resources> <Window.Resources>
<converters:EnumToBooleanConverter x:Key="EnumBoolConverter" /> <converters:EnumToBooleanConverter x:Key="EnumBoolConverter" />
</Window.Resources> </Window.Resources>
@ -37,16 +37,16 @@
</StackPanel.Styles> </StackPanel.Styles>
<Grid> <Grid>
<TextBlock Classes="h4" IsVisible="{Binding IsNew}">Add a new profile</TextBlock> <TextBlock Classes="h4" IsVisible="{CompiledBinding IsNew}">Add a new profile</TextBlock>
<TextBlock Classes="h4" IsVisible="{Binding !IsNew}" Text="{Binding ProfileConfiguration.Name}" /> <TextBlock Classes="h4" IsVisible="{CompiledBinding !IsNew}" Text="{CompiledBinding ProfileConfiguration.Name}" />
</Grid> </Grid>
<Border Classes="card" Margin="0 0 0 15"> <Border Classes="card" Margin="0 0 0 15">
<StackPanel> <StackPanel>
<TextBlock Classes="label">Profile name</TextBlock> <TextBlock Classes="label">Profile name</TextBlock>
<TextBox Watermark="Name" Text="{Binding ProfileName}" /> <TextBox Watermark="Name" Text="{CompiledBinding ProfileName}" />
<TextBlock Classes="label">Module</TextBlock> <TextBlock Classes="label">Module</TextBlock>
<ComboBox SelectedItem="{Binding SelectedModule}" IsEnabled="{Binding Modules.Count}" Items="{Binding Modules}" HorizontalAlignment="Stretch"> <ComboBox SelectedItem="{CompiledBinding SelectedModule}" IsEnabled="{CompiledBinding Modules.Count}" Items="{CompiledBinding Modules}" HorizontalAlignment="Stretch">
<ComboBox.ItemsPanel> <ComboBox.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<VirtualizingStackPanel /> <VirtualizingStackPanel />
@ -55,65 +55,64 @@
<ComboBox.ItemTemplate> <ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:ProfileModuleViewModel}"> <DataTemplate DataType="{x:Type local:ProfileModuleViewModel}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<shared:ArtemisIcon Icon="{Binding Icon}" Width="16" Height="16" Margin="0 0 5 0" /> <shared:ArtemisIcon Icon="{CompiledBinding Icon}" Width="16" Height="16" Margin="0 0 5 0" />
<TextBlock Text="{Binding Name}" /> <TextBlock Text="{CompiledBinding Name}" />
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
</ComboBox.ItemTemplate> </ComboBox.ItemTemplate>
</ComboBox> </ComboBox>
<Grid> <Grid>
<TextBlock Classes="subtitle" IsVisible="{Binding Modules.Count}">Optional and binds the profile to the selected module, making module data available</TextBlock> <TextBlock Classes="subtitle" IsVisible="{CompiledBinding Modules.Count}">Optional and binds the profile to the selected module, making module data available</TextBlock>
<TextBlock Classes="subtitle" IsVisible="{Binding !Modules.Count}">No available modules were found</TextBlock> <TextBlock Classes="subtitle" IsVisible="{CompiledBinding !Modules.Count}">No available modules were found</TextBlock>
</Grid> </Grid>
<TextBlock Classes="label">Icon type</TextBlock> <TextBlock Classes="label">Icon</TextBlock>
<WrapPanel Orientation="Horizontal"> <WrapPanel Orientation="Horizontal">
<RadioButton Content="Material Icon" <RadioButton Content="Material Icon"
IsChecked="{Binding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.MaterialIcon}}" /> IsChecked="{CompiledBinding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.MaterialIcon}}" />
<RadioButton Content="Bitmap image" <RadioButton Content="Bitmap image"
IsChecked="{Binding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.BitmapImage}}" /> IsChecked="{CompiledBinding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.BitmapImage}}" />
<RadioButton Content="SVG image" <RadioButton Content="SVG image"
IsChecked="{Binding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.SvgImage}}" /> IsChecked="{CompiledBinding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.SvgImage}}" />
</WrapPanel> </WrapPanel>
<TextBlock Classes="label">Icon</TextBlock>
<StackPanel Orientation="Horizontal" <StackPanel Orientation="Horizontal"
IsVisible="{Binding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.BitmapImage}}"> IsVisible="{CompiledBinding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.BitmapImage}}">
<Border Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="78" Height="78"> <Border Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="78" Height="78">
<Image Source="{Binding SelectedBitmapSource}" Margin="10" /> <Image Source="{CompiledBinding SelectedBitmapSource}" Margin="10" />
</Border> </Border>
<Button Command="{Binding BrowseBitmapFile}" <Button Command="{CompiledBinding BrowseBitmapFile}"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
Margin="10 0" Margin="10 0"
IsVisible="{Binding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.BitmapImage}}"> IsVisible="{CompiledBinding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.BitmapImage}}">
Browse bitmap file Browse bitmap file
</Button> </Button>
</StackPanel> </StackPanel>
<StackPanel Orientation="Horizontal" <StackPanel Orientation="Horizontal"
IsVisible="{Binding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.SvgImage}}"> IsVisible="{CompiledBinding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.SvgImage}}">
<Border Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="78" Height="78"> <Border Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="78" Height="78">
<Image Margin="10" Source="{Binding SelectedSvgSource}" /> <Image Margin="10" Source="{CompiledBinding SelectedSvgSource}" />
</Border> </Border>
<Button Command="{Binding BrowseSvgFile}" <Button Command="{CompiledBinding BrowseSvgFile}"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
Margin="10 0" Margin="10 0"
IsVisible="{Binding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.SvgImage}}"> IsVisible="{CompiledBinding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.SvgImage}}">
Browse SVG file Browse SVG file
</Button> </Button>
</StackPanel> </StackPanel>
<StackPanel Orientation="Horizontal" <StackPanel Orientation="Horizontal"
IsVisible="{Binding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.MaterialIcon}}"> IsVisible="{CompiledBinding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.MaterialIcon}}">
<Border Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="78" Height="78"> <Border Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="78" Height="78">
<avalonia:MaterialIcon Kind="{Binding SelectedMaterialIcon.Icon}" Width="45" Height="45" /> <avalonia:MaterialIcon Kind="{CompiledBinding SelectedMaterialIcon.Icon}" Width="45" Height="45" />
</Border> </Border>
<ComboBox Items="{Binding MaterialIcons}" <ComboBox Items="{CompiledBinding MaterialIcons}"
SelectedItem="{Binding SelectedMaterialIcon}" SelectedItem="{CompiledBinding SelectedMaterialIcon}"
VirtualizationMode="Simple" VirtualizationMode="Simple"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
IsTextSearchEnabled="True" IsTextSearchEnabled="True"
Margin="10 0" Margin="10 0"
Width="250" Width="250"
IsVisible="{Binding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.MaterialIcon}}"> IsVisible="{CompiledBinding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.MaterialIcon}}">
<ComboBox.ItemsPanel> <ComboBox.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<VirtualizingStackPanel /> <VirtualizingStackPanel />
@ -122,8 +121,8 @@
<ComboBox.ItemTemplate> <ComboBox.ItemTemplate>
<DataTemplate DataType="local:ProfileIconViewModel"> <DataTemplate DataType="local:ProfileIconViewModel">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<avalonia:MaterialIcon Kind="{Binding Icon}" Margin="0 0 5 0" /> <avalonia:MaterialIcon Kind="{CompiledBinding Icon}" Margin="0 0 5 0" />
<TextBlock Text="{Binding DisplayName}" /> <TextBlock Text="{CompiledBinding DisplayName}" />
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
</ComboBox.ItemTemplate> </ComboBox.ItemTemplate>
@ -141,25 +140,25 @@
<TextBlock>Hotkey mode</TextBlock> <TextBlock>Hotkey mode</TextBlock>
<WrapPanel Orientation="Horizontal"> <WrapPanel Orientation="Horizontal">
<RadioButton Content="None" <RadioButton Content="None"
IsChecked="{Binding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.None}}" /> IsChecked="{CompiledBinding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.None}}" />
<RadioButton Content="Toggle" <RadioButton Content="Toggle"
IsChecked="{Binding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.Toggle}}" /> IsChecked="{CompiledBinding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.Toggle}}" />
<RadioButton Content="Separate enable/disable" <RadioButton Content="Separate enable/disable"
IsChecked="{Binding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.EnableDisable}}" /> IsChecked="{CompiledBinding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.EnableDisable}}" />
</WrapPanel> </WrapPanel>
<shared:HotkeyBox Watermark="Toggle hotkey" <shared:HotkeyBox Watermark="Toggle hotkey"
Hotkey="{Binding EnableHotkey}" Hotkey="{CompiledBinding EnableHotkey}"
IsVisible="{Binding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.Toggle}}" IsVisible="{CompiledBinding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.Toggle}}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Width="200" Width="200"
Margin="0 5 0 0" /> Margin="0 5 0 0" />
<StackPanel Orientation="Horizontal" <StackPanel Orientation="Horizontal"
IsVisible="{Binding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.EnableDisable}}" IsVisible="{CompiledBinding HotkeyMode, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationHotkeyMode.EnableDisable}}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Margin="0 5 0 0"> Margin="0 5 0 0">
<shared:HotkeyBox Watermark="Enable hotkey" Hotkey="{Binding EnableHotkey}" Margin="0 0 4 0" Width="200"/> <shared:HotkeyBox Watermark="Enable hotkey" Hotkey="{CompiledBinding EnableHotkey}" Margin="0 0 4 0" Width="200" />
<shared:HotkeyBox Watermark="Disable hotkey" Hotkey="{Binding DisableHotkey}" Margin="4 0 0 0" Width="200"/> <shared:HotkeyBox Watermark="Disable hotkey" Hotkey="{CompiledBinding DisableHotkey}" Margin="4 0 0 0" Width="200" />
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
</Border> </Border>
@ -169,16 +168,30 @@
<TextBlock Classes="subtitle section-subtitle">Set up certain conditions under which the profile should be active</TextBlock> <TextBlock Classes="subtitle section-subtitle">Set up certain conditions under which the profile should be active</TextBlock>
</StackPanel> </StackPanel>
<Border Classes="card" Margin="0 5 0 15"> <Border Classes="card" Margin="0 5 0 15">
<TextBlock TextWrapping="Wrap">Here you'll find the node editor layer at some point, use your imagination for now.</TextBlock> <Grid>
<Border CornerRadius="5" ClipToBounds="True">
<ContentControl Content="{CompiledBinding VisualEditorViewModel}" Height="150" />
</Border>
<Border Background="Black" Opacity="0.5" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" CornerRadius="5"/>
<Button DockPanel.Dock="Bottom"
ToolTip.Tip="Open editor"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Command="{CompiledBinding OpenConditionEditor}">
Edit condition script
</Button>
</Grid>
</Border> </Border>
</StackPanel> </StackPanel>
</ScrollViewer> </ScrollViewer>
<Grid Grid.Row="1" ColumnDefinitions="Auto,Auto,Auto" HorizontalAlignment="Right"> <Grid Grid.Row="1" ColumnDefinitions="Auto,Auto,Auto" HorizontalAlignment="Right">
<Button Grid.Column="0" Classes="accent" Command="{Binding Confirm}">Confirm</Button> <Button Grid.Column="0" Classes="accent" Command="{CompiledBinding Confirm}">Confirm</Button>
<Button Grid.Column="1" Margin="5" Command="{Binding Import}" IsVisible="{Binding IsNew}">Import</Button> <Button Grid.Column="1" Margin="5" Command="{CompiledBinding Import}" IsVisible="{CompiledBinding IsNew}">Import</Button>
<Button Grid.Column="1" Margin="5" Command="{Binding Delete}" IsVisible="{Binding !IsNew}">Delete</Button> <Button Grid.Column="1" Margin="5" Command="{CompiledBinding Delete}" IsVisible="{CompiledBinding !IsNew}">Delete</Button>
<Button Grid.Column="2" Command="{Binding Cancel}">Cancel</Button> <Button Grid.Column="2" Command="{CompiledBinding Cancel}">Cancel</Button>
</Grid> </Grid>
</Grid> </Grid>

View File

@ -2,10 +2,13 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reactive;
using System.Threading.Tasks; using System.Threading.Tasks;
using Artemis.Core; using Artemis.Core;
using Artemis.Core.Modules; using Artemis.Core.Modules;
using Artemis.Core.Services; using Artemis.Core.Services;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.VisualScripting;
using Artemis.UI.Shared; using Artemis.UI.Shared;
using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor;
@ -43,7 +46,8 @@ namespace Artemis.UI.Screens.Sidebar
IWindowService windowService, IWindowService windowService,
IProfileService profileService, IProfileService profileService,
IProfileEditorService profileEditorService, IProfileEditorService profileEditorService,
IPluginManagementService pluginManagementService) IPluginManagementService pluginManagementService,
INodeVmFactory nodeVmFactory)
{ {
_profileCategory = profileCategory; _profileCategory = profileCategory;
_windowService = windowService; _windowService = windowService;
@ -63,8 +67,17 @@ namespace Artemis.UI.Screens.Sidebar
Modules = new ObservableCollection<ProfileModuleViewModel>( Modules = new ObservableCollection<ProfileModuleViewModel>(
pluginManagementService.GetFeaturesOfType<Module>().Where(m => !m.IsAlwaysAvailable).Select(m => new ProfileModuleViewModel(m)) pluginManagementService.GetFeaturesOfType<Module>().Where(m => !m.IsAlwaysAvailable).Select(m => new ProfileModuleViewModel(m))
); );
VisualEditorViewModel = nodeVmFactory.NodeScriptViewModel(_profileConfiguration.ActivationCondition, true);
Dispatcher.UIThread.Post(LoadIcon, DispatcherPriority.Background); Dispatcher.UIThread.Post(LoadIcon, DispatcherPriority.Background);
BrowseBitmapFile = ReactiveCommand.CreateFromTask(ExecuteBrowseBitmapFile);
BrowseSvgFile = ReactiveCommand.CreateFromTask(ExecuteBrowseSvgFile);
OpenConditionEditor = ReactiveCommand.CreateFromTask(ExecuteOpenConditionEditor);
Confirm = ReactiveCommand.CreateFromTask(ExecuteConfirm);
Import = ReactiveCommand.CreateFromTask(ExecuteImport);
Delete = ReactiveCommand.CreateFromTask(ExecuteDelete);
Cancel = ReactiveCommand.Create(ExecuteCancel);
} }
public bool IsNew { get; } public bool IsNew { get; }
@ -107,7 +120,17 @@ namespace Artemis.UI.Screens.Sidebar
set => RaiseAndSetIfChanged(ref _selectedModule, value); set => RaiseAndSetIfChanged(ref _selectedModule, value);
} }
public async Task Import() public NodeScriptViewModel VisualEditorViewModel { get; }
public ReactiveCommand<Unit, Unit> OpenConditionEditor { get; }
public ReactiveCommand<Unit, Unit> BrowseBitmapFile { get; }
public ReactiveCommand<Unit, Unit> BrowseSvgFile { get; }
public ReactiveCommand<Unit, Unit> Confirm { get; }
public ReactiveCommand<Unit, Unit> Import { get; }
public ReactiveCommand<Unit, Unit> Delete { get; }
public new ReactiveCommand<Unit, Unit> Cancel { get; }
private async Task ExecuteImport()
{ {
if (!IsNew) if (!IsNew)
return; return;
@ -144,7 +167,7 @@ namespace Artemis.UI.Screens.Sidebar
Close(_profileConfiguration); Close(_profileConfiguration);
} }
public async Task Delete() private async Task ExecuteDelete()
{ {
if (IsNew) if (IsNew)
return; return;
@ -157,7 +180,7 @@ namespace Artemis.UI.Screens.Sidebar
Close(_profileConfiguration); Close(_profileConfiguration);
} }
public async Task Confirm() private async Task ExecuteConfirm()
{ {
ProfileConfiguration.Name = ProfileName; ProfileConfiguration.Name = ProfileName;
ProfileConfiguration.Module = SelectedModule?.Module; ProfileConfiguration.Module = SelectedModule?.Module;
@ -172,7 +195,7 @@ namespace Artemis.UI.Screens.Sidebar
Close(ProfileConfiguration); Close(ProfileConfiguration);
} }
public void Cancel() private void ExecuteCancel()
{ {
if (IsNew) if (IsNew)
_profileService.RemoveProfileConfiguration(_profileConfiguration); _profileService.RemoveProfileConfiguration(_profileConfiguration);
@ -255,7 +278,7 @@ namespace Artemis.UI.Screens.Sidebar
} }
} }
public async Task BrowseBitmapFile() private async Task ExecuteBrowseBitmapFile()
{ {
string[]? result = await _windowService.CreateOpenFileDialog() string[]? result = await _windowService.CreateOpenFileDialog()
.HavingFilter(f => f.WithExtension("png").WithExtension("jpg").WithExtension("bmp").WithName("Bitmap image")) .HavingFilter(f => f.WithExtension("png").WithExtension("jpg").WithExtension("bmp").WithName("Bitmap image"))
@ -268,7 +291,7 @@ namespace Artemis.UI.Screens.Sidebar
_selectedIconPath = result[0]; _selectedIconPath = result[0];
} }
public async Task BrowseSvgFile() private async Task ExecuteBrowseSvgFile()
{ {
string[]? result = await _windowService.CreateOpenFileDialog() string[]? result = await _windowService.CreateOpenFileDialog()
.HavingFilter(f => f.WithExtension("svg").WithName("SVG image")) .HavingFilter(f => f.WithExtension("svg").WithName("SVG image"))
@ -284,6 +307,11 @@ namespace Artemis.UI.Screens.Sidebar
_selectedIconPath = result[0]; _selectedIconPath = result[0];
} }
private async Task ExecuteOpenConditionEditor()
{
await _windowService.ShowDialogAsync<NodeScriptWindowViewModel, bool>(("nodeScript", ProfileConfiguration.ActivationCondition));
}
#endregion #endregion
} }
} }

View File

@ -14,13 +14,6 @@
<Border Classes="router-container"> <Border Classes="router-container">
<ScrollViewer> <ScrollViewer>
<StackPanel Margin="12" Spacing="5"> <StackPanel Margin="12" Spacing="5">
<Border Classes="card">
<StackPanel Spacing="5">
<TextBlock Classes="h4">Nodes tests</TextBlock>
<!-- <dataModelPicker:DataModelPickerButton Placement="BottomEdgeAlignedLeft"/> -->
<ContentControl Content="{CompiledBinding VisualEditorViewModel}" HorizontalAlignment="Stretch" Height="800"></ContentControl>
</StackPanel>
</Border>
<Border Classes="card"> <Border Classes="card">
<StackPanel Spacing="5"> <StackPanel Spacing="5">
<TextBlock Classes="h4">Notification tests</TextBlock> <TextBlock Classes="h4">Notification tests</TextBlock>

View File

@ -1,29 +1,18 @@
using System; using System.Reactive;
using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq; using System.Reactive.Linq;
using Artemis.Core; using Artemis.Core;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.VisualScripting;
using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Builders; using Artemis.UI.Shared.Services.Builders;
using Artemis.VisualScripting.Nodes;
using Artemis.VisualScripting.Nodes.Operators;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Threading;
using ReactiveUI; using ReactiveUI;
using SkiaSharp; using SkiaSharp;
namespace Artemis.UI.Screens.Workshop namespace Artemis.UI.Screens.Workshop;
{
public class WorkshopViewModel : MainScreenViewModel public class WorkshopViewModel : MainScreenViewModel
{ {
private static NodeScript<bool>? _testScript = null;
private readonly INotificationService _notificationService;
private StandardCursorType _selectedCursor;
private readonly ObservableAsPropertyHelper<Cursor> _cursor; private readonly ObservableAsPropertyHelper<Cursor> _cursor;
private readonly INotificationService _notificationService;
private ColorGradient _colorGradient = new() private ColorGradient _colorGradient = new()
{ {
@ -32,41 +21,20 @@ namespace Artemis.UI.Screens.Workshop
new ColorGradientStop(new SKColor(0xFFEF1788), 0.4f), new ColorGradientStop(new SKColor(0xFFEF1788), 0.4f),
new ColorGradientStop(new SKColor(0xFFEF1788), 0.6f), new ColorGradientStop(new SKColor(0xFFEF1788), 0.6f),
new ColorGradientStop(new SKColor(0xFF00FCCC), 0.8f), new ColorGradientStop(new SKColor(0xFF00FCCC), 0.8f),
new ColorGradientStop(new SKColor(0xFF00FCCC), 1f), new ColorGradientStop(new SKColor(0xFF00FCCC), 1f)
}; };
public WorkshopViewModel(IScreen hostScreen, INotificationService notificationService, INodeVmFactory nodeVmFactory) : base(hostScreen, "workshop") private StandardCursorType _selectedCursor;
public WorkshopViewModel(IScreen hostScreen, INotificationService notificationService) : base(hostScreen, "workshop")
{ {
_notificationService = notificationService; _notificationService = notificationService;
_cursor = this.WhenAnyValue(vm => vm.SelectedCursor).Select(c => new Cursor(c)).ToProperty(this, vm => vm.Cursor); _cursor = this.WhenAnyValue(vm => vm.SelectedCursor).Select(c => new Cursor(c)).ToProperty(this, vm => vm.Cursor);
DisplayName = "Workshop"; DisplayName = "Workshop";
ShowNotification = ReactiveCommand.Create<NotificationSeverity>(ExecuteShowNotification); ShowNotification = ReactiveCommand.Create<NotificationSeverity>(ExecuteShowNotification);
if (_testScript == null)
{
_testScript = new NodeScript<bool>("Test script", "A test script");
INode exitNode = _testScript.Nodes.Last();
exitNode.X = 300;
exitNode.Y = 150;
OrNode orNode = new() {X = 100, Y = 100};
_testScript.AddNode(orNode);
orNode.Result.ConnectTo(exitNode.Pins.First());
} }
VisualEditorViewModel = nodeVmFactory.NodeScriptViewModel(_testScript, false);
this.WhenActivated(d =>
{
DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(20), DispatcherPriority.Normal, (_, _) => _testScript?.Run());
updateTimer.Start();
Disposable.Create(() => updateTimer.Stop()).DisposeWith(d);
});
}
public NodeScriptViewModel VisualEditorViewModel { get; }
public ReactiveCommand<NotificationSeverity, Unit> ShowNotification { get; set; } public ReactiveCommand<NotificationSeverity, Unit> ShowNotification { get; set; }
public StandardCursorType SelectedCursor public StandardCursorType SelectedCursor
@ -93,4 +61,3 @@ namespace Artemis.UI.Screens.Workshop
_notificationService.CreateNotification().WithTitle("Test title").WithMessage("Test message").WithSeverity(severity).Show(); _notificationService.CreateNotification().WithTitle("Test title").WithMessage("Test message").WithSeverity(severity).Show();
} }
} }
}