summaryrefslogtreecommitdiffstats
path: root/Scripts/Fold/Editor/KeyframeNodeView.cs
blob: c35b21508405015787778e69ec0fde6e8b77dee0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
using GraphProcessor;
using UnityEngine.UIElements;
using UnityEngine;
using System.Linq;

[NodeCustomEditor(typeof(KeyframeNode))]
public class KeyframeNodeView : BaseNodeView
{
  Button generateButton;
  const string ERROR_MSG_NO_GAMEOBJECT = "GameObject input has wrong type";
  const string ERROR_MSG_NO_RENDERER   = "GameObject must have a MeshRenderer component";

  public override void Enable()
  {
    var node = nodeTarget as KeyframeNode;

    generateButton = new Button(OnGenerateClick)
    {
      text = "Generate Keyframe"
    };
    controlsContainer.Add(generateButton);

    // Update validation on connectivity changes.
    onPortConnected += _ => Validate();
    onPortDisconnected += _ => Validate();

    // Check periodically in case the value in the GameObjectNode changes.
    // Best effort.
    schedule.Execute(Validate).Every(200);

    Validate();
  }

  void OnGenerateClick()
  {
    var go = GetConnectedGameObject();
    // The button should be disabled if invalid, but safety check:
    if (go == null || go.GetComponent<MeshRenderer>() == null) return;

    var foldNode = GetConnectedFoldNode();
    Debug.Log($"Generating Keyframe for '{go.name}' using Fold Data: {(foldNode != null ? foldNode.name : "None")}");
    // TODO
  }

  GameObject GetConnectedGameObject()
  {
    var portView = GetFirstPortViewFromFieldName(nameof(KeyframeNode.targetObject));
    if (portView == null || portView.GetEdges().Count == 0) return null;

    var edge = portView.GetEdges().First();
    var outputNode = (edge.output.node as BaseNodeView)?.nodeTarget;

    if (outputNode is GameObjectNode goNode) {
      return goNode.output;
    }
    return null;
  }

  BaseFoldNode GetConnectedFoldNode()
  {
    var portView = GetFirstPortViewFromFieldName(nameof(KeyframeNode.foldData));
    if (portView == null || portView.GetEdges().Count == 0) return null;

    var edge = portView.GetEdges().First();
    return (edge.output.node as BaseNodeView)?.nodeTarget as BaseFoldNode;
  }

  void Validate()
  {
    var go = GetConnectedGameObject();
    bool hasTargetConnection = GetFirstPortViewFromFieldName(nameof(KeyframeNode.targetObject))?.GetEdges().Count > 0;
    bool hasFoldConnection = GetFirstPortViewFromFieldName(nameof(KeyframeNode.foldData))?.GetEdges().Count > 0;

    // Clear previous error.
    RemoveMessageView(ERROR_MSG_NO_RENDERER);
    RemoveMessageView(ERROR_MSG_NO_GAMEOBJECT);

    bool isValid = false;
    if (hasTargetConnection) {
      if (go == null) {
        // Has connection but it's not a GameObject.
        AddMessageView(ERROR_MSG_NO_GAMEOBJECT, NodeMessageType.Error);
      } else if (go.GetComponent<MeshRenderer>() == null) {
        AddMessageView(ERROR_MSG_NO_RENDERER, NodeMessageType.Error);
      } else {
        isValid = true;
      }
    }

    generateButton.SetEnabled(isValid && hasFoldConnection);
  }
}