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

Nodes - Added help URL and help button

This commit is contained in:
Robert 2022-10-04 23:31:20 +02:00 committed by RobertBeekman
parent ba45bdd99d
commit 7ada77f5e3
6 changed files with 68 additions and 10 deletions

View File

@ -75,8 +75,9 @@ internal class NodeService : INodeService
string name = nodeAttribute?.Name ?? nodeType.Name; string name = nodeAttribute?.Name ?? nodeType.Name;
string description = nodeAttribute?.Description ?? string.Empty; string description = nodeAttribute?.Description ?? string.Empty;
string category = nodeAttribute?.Category ?? string.Empty; string category = nodeAttribute?.Category ?? string.Empty;
string helpUrl = nodeAttribute?.HelpUrl ?? string.Empty;
NodeData nodeData = new(plugin, nodeType, name, description, category, nodeAttribute?.InputType, nodeAttribute?.OutputType, (s, e) => CreateNode(s, e, nodeType));
NodeData nodeData = new(plugin, nodeType, name, description, category, helpUrl, nodeAttribute?.InputType, nodeAttribute?.OutputType, (s, e) => CreateNode(s, e, nodeType));
return NodeTypeStore.Add(nodeData); return NodeTypeStore.Add(nodeData);
} }

View File

@ -18,12 +18,12 @@ public interface INode : INotifyPropertyChanged, IBreakableModel
/// <summary> /// <summary>
/// Gets the name of the node /// Gets the name of the node
/// </summary> /// </summary>
string Name { get; } string Name { get; set; }
/// <summary> /// <summary>
/// Gets the description of the node /// Gets the description of the node
/// </summary> /// </summary>
string Description { get; } string Description { get; set; }
/// <summary> /// <summary>
/// Gets a boolean indicating whether the node is the exit node of the script /// Gets a boolean indicating whether the node is the exit node of the script
@ -44,6 +44,11 @@ public interface INode : INotifyPropertyChanged, IBreakableModel
/// Gets or sets the Y-position of the node /// Gets or sets the Y-position of the node
/// </summary> /// </summary>
public double Y { get; set; } public double Y { get; set; }
/// <summary>
/// Gets or sets the help URL of the node
/// </summary>
string HelpUrl { get; set; }
/// <summary> /// <summary>
/// Gets a read-only collection of the pins on this node /// Gets a read-only collection of the pins on this node

View File

@ -24,6 +24,11 @@ public class NodeAttribute : Attribute
/// </summary> /// </summary>
public string Category { get; } = string.Empty; public string Category { get; } = string.Empty;
/// <summary>
/// Gets the help URL of the node
/// </summary>
public string HelpUrl { get; init; } = string.Empty;
/// <summary> /// <summary>
/// Gets the primary input type of the node /// Gets the primary input type of the node
/// </summary> /// </summary>
@ -65,5 +70,16 @@ public class NodeAttribute : Attribute
Category = category; Category = category;
} }
/// <summary>
/// Creates a new instance of the <see cref="NodeAttribute" /> class
/// </summary>
public NodeAttribute(string name, string description, string category, string helpUrl)
{
Name = name;
Description = description;
Category = category;
HelpUrl = helpUrl;
}
#endregion #endregion
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using Artemis.Storage.Entities.Profile.Nodes; using Artemis.Storage.Entities.Profile.Nodes;
using Castle.Core.Internal;
namespace Artemis.Core; namespace Artemis.Core;
@ -10,13 +11,14 @@ public class NodeData
{ {
#region Constructors #region Constructors
internal NodeData(Plugin plugin, Type type, string name, string description, string category, Type? inputType, Type? outputType, Func<INodeScript, NodeEntity?, INode> create) internal NodeData(Plugin plugin, Type type, string name, string description, string category, string helpUrl, Type? inputType, Type? outputType, Func<INodeScript, NodeEntity?, INode> create)
{ {
Plugin = plugin; Plugin = plugin;
Type = type; Type = type;
Name = name; Name = name;
Description = description; Description = description;
Category = category; Category = category;
HelpUrl = helpUrl;
InputType = inputType; InputType = inputType;
OutputType = outputType; OutputType = outputType;
_create = create; _create = create;
@ -34,7 +36,15 @@ public class NodeData
/// <returns>The returning node of type <see cref="Type" /></returns> /// <returns>The returning node of type <see cref="Type" /></returns>
public INode CreateNode(INodeScript script, NodeEntity? entity) public INode CreateNode(INodeScript script, NodeEntity? entity)
{ {
return _create(script, entity); INode node = _create(script, entity);
if (string.IsNullOrWhiteSpace(node.Name))
node.Name = Name;
if (string.IsNullOrWhiteSpace(node.Description))
node.Description = Description;
if (string.IsNullOrWhiteSpace(node.HelpUrl))
node.HelpUrl = HelpUrl;
return node;
} }
#endregion #endregion
@ -101,6 +111,11 @@ public class NodeData
/// </summary> /// </summary>
public string Category { get; } public string Category { get; }
/// <summary>
/// Gets the help URL of the node this data represents
/// </summary>
public string HelpUrl { get; }
/// <summary> /// <summary>
/// Gets the primary input type of the node this data represents /// Gets the primary input type of the node this data represents
/// </summary> /// </summary>

View File

@ -46,7 +46,7 @@ public abstract class Node : BreakableModel, INode
public string Name public string Name
{ {
get => _name; get => _name;
protected set => SetAndNotify(ref _name, value); set => SetAndNotify(ref _name, value);
} }
private string _description; private string _description;
@ -55,7 +55,7 @@ public abstract class Node : BreakableModel, INode
public string Description public string Description
{ {
get => _description; get => _description;
protected set => SetAndNotify(ref _description, value); set => SetAndNotify(ref _description, value);
} }
private double _x; private double _x;
@ -76,6 +76,13 @@ public abstract class Node : BreakableModel, INode
set => SetAndNotify(ref _y, value); set => SetAndNotify(ref _y, value);
} }
/// <inheritdoc />
public string HelpUrl
{
get => _helpUrl;
set => SetAndNotify(ref _helpUrl, value);
}
/// <inheritdoc /> /// <inheritdoc />
public virtual bool IsExitNode => false; public virtual bool IsExitNode => false;
@ -88,6 +95,7 @@ public abstract class Node : BreakableModel, INode
public IReadOnlyCollection<IPin> Pins => new ReadOnlyCollection<IPin>(_pins); public IReadOnlyCollection<IPin> Pins => new ReadOnlyCollection<IPin>(_pins);
private readonly List<IPinCollection> _pinCollections = new(); private readonly List<IPinCollection> _pinCollections = new();
private string _helpUrl;
/// <inheritdoc /> /// <inheritdoc />
public IReadOnlyCollection<IPinCollection> PinCollections => new ReadOnlyCollection<IPinCollection>(_pinCollections); public IReadOnlyCollection<IPinCollection> PinCollections => new ReadOnlyCollection<IPinCollection>(_pinCollections);
@ -106,6 +114,7 @@ public abstract class Node : BreakableModel, INode
{ {
_name = string.Empty; _name = string.Empty;
_description = string.Empty; _description = string.Empty;
_helpUrl = string.Empty;
_id = Guid.NewGuid(); _id = Guid.NewGuid();
} }
@ -116,6 +125,7 @@ public abstract class Node : BreakableModel, INode
{ {
_name = name; _name = name;
_description = description; _description = description;
_helpUrl = string.Empty;
_id = Guid.NewGuid(); _id = Guid.NewGuid();
} }

View File

@ -4,6 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:visualScripting="clr-namespace:Artemis.UI.Screens.VisualScripting" xmlns:visualScripting="clr-namespace:Artemis.UI.Screens.VisualScripting"
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
mc:Ignorable="d" d:DesignWidth="250" d:DesignHeight="150" mc:Ignorable="d" d:DesignWidth="250" d:DesignHeight="150"
x:Class="Artemis.UI.Screens.VisualScripting.NodeView" x:Class="Artemis.UI.Screens.VisualScripting.NodeView"
x:DataType="visualScripting:NodeViewModel"> x:DataType="visualScripting:NodeViewModel">
@ -37,7 +38,7 @@
ClipToBounds="True" ClipToBounds="True"
Background="{DynamicResource ContentDialogBackground}"> Background="{DynamicResource ContentDialogBackground}">
<Border Background="{DynamicResource TaskDialogHeaderBackground}"> <Border Background="{DynamicResource TaskDialogHeaderBackground}">
<Grid Classes="node-header" VerticalAlignment="Top" ColumnDefinitions="Auto,*,Auto"> <Grid Classes="node-header" VerticalAlignment="Top" ColumnDefinitions="Auto,*,Auto,Auto">
<Button Grid.Column="0" <Button Grid.Column="0"
VerticalAlignment="Center" VerticalAlignment="Center"
IsVisible="{CompiledBinding Node.BrokenState, Converter={x:Static ObjectConverters.IsNotNull}}" IsVisible="{CompiledBinding Node.BrokenState, Converter={x:Static ObjectConverters.IsNotNull}}"
@ -53,7 +54,17 @@
<TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="10 0 0 0" Text="{CompiledBinding Node.Name}" ToolTip.Tip="{CompiledBinding Node.Description}" /> <TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="10 0 0 0" Text="{CompiledBinding Node.Name}" ToolTip.Tip="{CompiledBinding Node.Description}" />
<Button Grid.Column="2" VerticalAlignment="Center" Classes="icon-button icon-button-small" Margin="5" Command="{CompiledBinding DeleteNode}">
<controls:HyperlinkButton Grid.Column="2"
IsVisible="{CompiledBinding Node.HelpUrl, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
VerticalAlignment="Center"
Classes="icon-button icon-button-small"
Margin="5 5 -3 5"
ToolTip.Tip="View node help"
NavigateUri="{CompiledBinding Node.HelpUrl}">
<avalonia:MaterialIcon Kind="Help" />
</controls:HyperlinkButton>
<Button Grid.Column="3" VerticalAlignment="Center" Classes="icon-button icon-button-small" Margin="5" Command="{CompiledBinding DeleteNode}">
<avalonia:MaterialIcon Kind="Close"></avalonia:MaterialIcon> <avalonia:MaterialIcon Kind="Close"></avalonia:MaterialIcon>
</Button> </Button>
</Grid> </Grid>