วันอังคารที่ 14 เมษายน พ.ศ. 2563

การสร้าง Dynamo Dropdown Node

Dropdown  Node ของ Dynamo ทำให้ผู้ใช้งาน ง่ายขึ้นในการเลือก Option ต่างๆ แต่การสร้าง ต้องทำเป็น Class คนละวิธีกับ การสร้าง Function Node ข้อแนะนำควรจะใช้ Dynamo Engine 2 และจำเป็นต้องวาง packages และ bin ใน Folder Default ของ Dynamo เท่านั้น ไม่นั้น จะไม่ทำงาน

จะมี องค์ประกอบ ได้แก่ Class ที่ต้อง Inherite จาก
DSDropDownBase
และมีองค์ประกอบ
PopulateItemsCore เพื่อใส่ค่าใน Item
และผลตัวเลือก
BuildOutputAst

ตัวอย่าง ที่ Fix bug แล้วจาก SampleDropdownUi ของ Dynamo


using System.Collections.Generic;
using CoreNodeModels;
using Dynamo.Graph.Nodes;
using Dynamo.Utilities;
using ProtoCore.AST.AssociativeAST;
using Newtonsoft.Json;

namespace SampleLibraryUI.Examples
{
    [NodeName("Drop Down Example")]
    [NodeDescription("Fixed An example drop down node.")]
    [IsDesignScriptCompatible]
    public class DropDownExample : DSDropDownBase
    {
        public DropDownExample() : base("itemA"){
              }

        // Starting with Dynamo v2.0 you must add Json constructors for all nodeModel
        // dervived nodes to support the move from an Xml to Json file format.  Failing to
        // do so will result in incorrect ports being generated upon serialization/deserialization.
        // This constructor is called when opening a Json graph. We must also pass the deserialized 
        // ports with the json constructor and then call the base class passing the ports as parameters.
        [JsonConstructor]
        public DropDownExample(IEnumerable<PortModel> inPorts, IEnumerable<PortModel> outPorts) : base("itemA", inPorts, outPorts) { }

        protected override SelectionState PopulateItemsCore(string currentSelection)
        {
            // The Items collection contains the elements
            // that appear in the list. For this example, we
            // clear the list before adding new items, but you
            // can also use the PopulateItems method to add items
            // to the list.

            Items.Clear();

            // Create a number of DynamoDropDownItem objects 
            // to store the items that we want to appear in our list.

            var newItems = new List<DynamoDropDownItem>()
            {
                new DynamoDropDownItem("Item 0", 0),
                new DynamoDropDownItem("Item 1", 1),
                new DynamoDropDownItem("Item 2",2)
            };

            Items.AddRange(newItems);

            // Set the selected index to something other
            // than -1, the default, so that your list
            // has a pre-selection.

            SelectedIndex = 0;
            return SelectionState.Restore;
        }

        public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes)
        {
            // Build an AST node for the type of object contained in your Items collection.
            if (Items.Count == 0 ||  SelectedIndex <0 || SelectedIndex >= Items.Count) // Bug fixed!
            {
                return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildNullNode()) };
            }

            var intNode = AstFactory.BuildIntNode((int)Items[SelectedIndex].Item);
            var assign = AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), intNode);
            return new List<AssociativeNode> { assign };

        }
    }
}