public override void Initialize()
 {
     base.Initialize();
     _eventNamePopup = this.GetProgramPopup(UdonNodeExtensions.ProgramPopupType.Events, _eventNamePopup);
 }
Ejemplo n.º 2
0
        // 0 = Value, 1 = name, 2 = public, 3 = synced, 4 = syncType
        public UdonParameterProperty(UdonGraph graphView, UdonNodeDefinition definition, UdonNodeData nodeData)
        {
            this.graph      = graphView;
            this.definition = definition;
            this.nodeData   = nodeData;

            // Make sure the incoming nodeData has the right number of nodeValues (super old graphs didn't have sync info)
            if (this.nodeData.nodeValues.Length != 5)
            {
                this.nodeData.nodeValues = GetDefaultNodeValues();
                for (int i = 0; i < nodeData.nodeValues.Length; i++)
                {
                    this.nodeData.nodeValues[i] = nodeData.nodeValues[i];
                }
            }

            // Public Toggle
            isPublic = new Toggle
            {
                text  = "public",
                value = (bool)GetValue(ValueIndices.isPublic)
            };
#if UNITY_2019_3_OR_NEWER
            isPublic.RegisterValueChangedCallback(
#else
            isPublic.OnValueChanged(
#endif
                e => { SetNewValue(e.newValue, ValueIndices.isPublic); });
            Add(isPublic);

            // Is Synced Field
            isSynced = new Toggle
            {
                text  = "synced",
                value = (bool)GetValue(ValueIndices.isSynced),
            };

#if UNITY_2019_3_OR_NEWER
            isSynced.RegisterValueChangedCallback(
#else
            isSynced.OnValueChanged(
#endif
                e =>
            {
                SetNewValue(e.newValue, ValueIndices.isSynced);
                syncField.visible = e.newValue;
            });
            Add(isSynced);

            // Sync Field, add to isSynced
            List <string> choices = new List <string>()
            {
                "none", "linear", "smooth"
            };
            syncField = new EditorUI.PopupField <string>(choices, 0)
            {
                visible = isSynced.value
            };
#if UNITY_2019_3_OR_NEWER
            syncField.RegisterValueChangedCallback(
#else
            syncField.OnValueChanged(
#endif
                e => { SetNewValue(e.newValue, ValueIndices.syncType); });
            isSynced.Add(syncField);

            // Container to show/edit Default Value
            var friendlyName      = UdonGraphExtensions.FriendlyTypeName(definition.type).FriendlyNameify();
            defaultValueContainer = new VisualElement();
            defaultValueContainer.Add(
                new Label("default value")
            {
                name = "default-value-label"
            });

            // Generate Default Value Field
            var value   = TryGetValueObject(out object result);
            _inputField = UdonFieldFactory.CreateField(
                definition.type,
                result,
                newValue => SetNewValue(newValue, ValueIndices.value)
                );
            if (_inputField != null)
            {
                defaultValueContainer.Add(_inputField);
                Add(defaultValueContainer);
            }
        }
        public static EditorUI.PopupField <string> GetProgramPopup(this UdonNode node, ProgramPopupType popupType, EditorUI.PopupField <string> _eventNamePopup)
        {
            string PLACEHOLDER = "----";
            string MISSING     = "MISSING! Was";

            List <string> _options = new List <string>()
            {
                PLACEHOLDER
            };
            var data = node.data;

            bool unavailable = true;

            if (data.nodeUIDs.Length < 1 || string.IsNullOrEmpty(data.nodeUIDs[0]))
            {
                switch (popupType)
                {
                case ProgramPopupType.Events:
                    _options = GetCustomEventsFromAsset(node.Graph.graphProgramAsset.SerializedProgramAsset);
                    break;

                case ProgramPopupType.Variables:
                    node.Graph.RefreshVariables(false);
                    _options = new List <string>(node.Graph.GetVariableNames).Where(x => !x.StartsWithCached(VariableChangedEvent.OLD_VALUE_PREFIX)).ToList();
                    break;
                }
                unavailable = _options.Count == 0;
                _options.Insert(0, PLACEHOLDER);
            }
            else if (data.InputNodeAtIndex(0)?.fullName == "Get_Variable")
            {
                // So much work to get the underlying node referenced by a variable. Would be nice to have a method for this.
                var parts = data.nodeUIDs[0].Split('|');
                if (parts.Length < 1)
                {
                    return(null);
                }

                string targetId = parts[0];

                var variableGetterNode = node.Graph.graphData.FindNode(targetId);
                if (variableGetterNode == null || variableGetterNode.nodeValues.Length < 1)
                {
                    return(null);
                }

                string variableId = variableGetterNode.nodeValues[0].Deserialize() as string;
                if (string.IsNullOrWhiteSpace(variableId))
                {
                    return(null);
                }

                string variableName = node.Graph.GetVariableName(variableId);
                if (string.IsNullOrWhiteSpace(variableName))
                {
                    return(null);
                }

                if (node.Graph.udonBehaviour != null && node.Graph.udonBehaviour.publicVariables.TryGetVariableValue(variableName, out UdonBehaviour ub))
                {
                    if (ub != null)
                    {
                        switch (popupType)
                        {
                        case ProgramPopupType.Events:
                            _options = GetCustomEventsFromAsset(ub.programSource.SerializedProgramAsset);
                            break;

                        case ProgramPopupType.Variables:
                            _options = ub.programSource?.SerializedProgramAsset?.RetrieveProgram()?.SymbolTable
                                       .GetSymbols().Where(s => !s.StartsWithCached(UdonGraphCompiler.INTERNAL_VARIABLE_PREFIX) && !s.StartsWithCached(VariableChangedEvent.OLD_VALUE_PREFIX)).ToList();
                            break;
                        }
                        _options.Insert(0, PLACEHOLDER);
                        unavailable = false;
                    }
                }
            }


            int    currentIndex         = 0;
            int    targetNodeValueIndex = node.data.fullName.Contains("SendCustomNetworkEvent") ? 2 : 1;
            string targetVarName        = data.nodeValues[targetNodeValueIndex].Deserialize() as string;

            if (targetVarName != null && targetVarName.StartsWithCached(MISSING))
            {
                targetVarName = null;
            }

            // If we have a target variable name:
            if (!string.IsNullOrWhiteSpace(targetVarName))
            {
                if (_options.Contains(targetVarName))
                {
                    currentIndex = _options.IndexOf(targetVarName);
                }
                else
                {
                    _options[0] = unavailable ? targetVarName : $"{MISSING} {targetVarName}";
                }
            }

            if (_eventNamePopup == null)
            {
                _eventNamePopup      = new EditorUI.PopupField <string>(_options, currentIndex);
                _eventNamePopup.name = popupType == ProgramPopupType.Events ? "EventNamePopup" : "VariablePopup";
                var eventNamePort = node.inputContainer.Q(null, popupType == ProgramPopupType.Events ? "eventName" : "symbolName");
                eventNamePort?.Add(_eventNamePopup);
                if (unavailable)
                {
                    _eventNamePopup.SetEnabled(false);
                }
            }
            else
            {
                // Remaking it - remove the old one, at the new one at its previous location
                int index = node.inputContainer.IndexOf(_eventNamePopup);
                _eventNamePopup.RemoveFromHierarchy();
                _eventNamePopup = new EditorUI.PopupField <string>(_options, currentIndex);
                node.inputContainer.Insert(index, _eventNamePopup);
            }
#if UNITY_2019_3_OR_NEWER
            _eventNamePopup.RegisterValueChangedCallback(
#else
            _eventNamePopup.OnValueChanged(
#endif
                (e) =>
            {
                node.SetNewValue(e.newValue.CompareTo(PLACEHOLDER) == 0 ? "" : e.newValue.ToString(), targetNodeValueIndex);
                // Todo: update text field directly and save instead of calling Reload
                node.Reload();
            });

            return(_eventNamePopup);
        }
 public override void Initialize()
 {
     base.Initialize();
     _programVariablePopup =
         this.GetProgramPopup(UdonNodeExtensions.ProgramPopupType.Variables, _programVariablePopup);
 }
        // 0 = Value, 1 = name, 2 = public, 3 = synced, 4 = syncType
        public UdonParameterProperty(UdonGraph graphView, UdonNodeDefinition definition, UdonNodeData nodeData)
        {
            this.graph      = graphView;
            this.definition = definition;
            this.nodeData   = nodeData;

            string friendlyName = UdonGraphExtensions.FriendlyTypeName(definition.type).FriendlyNameify();

            // Public Toggle
            isPublic = new Toggle
            {
                text  = "public",
                value = (bool)GetValue(ValueIndices.isPublic)
            };
#if UNITY_2019_3_OR_NEWER
            isPublic.RegisterValueChangedCallback(
#else
            isPublic.OnValueChanged(
#endif
                e => { SetNewValue(e.newValue, ValueIndices.isPublic); });
            Add(isPublic);

            if (UdonNetworkTypes.CanSync(definition.type))
            {
                // Is Synced Field
                isSynced = new Toggle
                {
                    text  = "synced",
                    value = (bool)GetValue(ValueIndices.isSynced),
                    name  = "syncToggle",
                };

#if UNITY_2019_3_OR_NEWER
                isSynced.RegisterValueChangedCallback(
#else
                isSynced.OnValueChanged(
#endif
                    e =>
                {
                    SetNewValue(e.newValue, ValueIndices.isSynced);
                    syncField.visible = e.newValue;
                });

                // Sync Field, add to isSynced
                List <string> choices = new List <string>()
                {
                    "none"
                };

                if (UdonNetworkTypes.CanSyncLinear(definition.type))
                {
                    choices.Add("linear");
                }

                if (UdonNetworkTypes.CanSyncSmooth(definition.type))
                {
                    choices.Add("smooth");
                }

                syncField = new EditorUI.PopupField <string>(choices, 0)
                {
                    visible = isSynced.value,
                };
                syncField.Insert(0, new Label("smooth:"));

#if UNITY_2019_3_OR_NEWER
                syncField.RegisterValueChangedCallback(
#else
                syncField.OnValueChanged(
#endif
                    e =>
                {
                    SetNewValue(e.newValue, ValueIndices.syncType);
                });

                // Only show sync smoothing dropdown if there are choices to be made
                if (choices.Count > 1)
                {
                    isSynced.Add(syncField);
                }

                Add(isSynced);
            }
            else
            {
                // Cannot Sync
                SetNewValue(false, ValueIndices.isSynced);
                Add(new Label($"{friendlyName} cannot be synced."));
            }

            // Container to show/edit Default Value
            defaultValueContainer = new VisualElement();
            defaultValueContainer.Add(
                new Label("default value")
            {
                name = "default-value-label"
            });

            // Generate Default Value Field
            var value   = TryGetValueObject(out object result);
            _inputField = UdonFieldFactory.CreateField(
                definition.type,
                result,
                newValue => SetNewValue(newValue, ValueIndices.value)
                );
            if (_inputField != null)
            {
                defaultValueContainer.Add(_inputField);
                Add(defaultValueContainer);
            }
        }