public void BindField(LineTextField field)
        {
            if (serializedObject is null)
            {
                serializedObject    = new SerializedObject(this);
                fieldValuesProperty = serializedObject.FindProperty(nameof(fieldValues));
            }

            if (!fields.Contains(field))
            {
                fields.Add(field);
                fieldValues.Add(field.value);
                field.RegisterValueChangedCallback(HandleValueChanged);
            }
            else
            {
                var index = fields.IndexOf(field);
                fieldValues[index] = field.value;
            }

            if (!updateSerializedObjectPending) // For better performance on editor init.
            {
                EditorApplication.delayCall  += UpdateSerializedObjectDelayed;
                updateSerializedObjectPending = true;
            }
            void UpdateSerializedObjectDelayed()
            {
                serializedObject.UpdateIfRequiredOrScript();
                updateSerializedObjectPending = false;
            }
        }
Example #2
0
 public GenericTextLineView(int lineIndex, string lineText, VisualElement container)
     : base(lineIndex, container)
 {
     valueField           = new LineTextField(value: lineText);
     valueField.multiline = true;
     Content.Add(valueField);
 }
        public LabelLineView(int lineIndex, string lineText, VisualElement container)
            : base(lineIndex, container)
        {
            var value = lineText.GetAfterFirst(LabelScriptLine.IdentifierLiteral)?.TrimFull();

            ValueField = new LineTextField(LabelScriptLine.IdentifierLiteral, value);
            Content.Add(ValueField);
        }
Example #4
0
        public LabelLineView(int lineIndex, string lineText, VisualElement container)
            : base(lineIndex, container)
        {
            var value = lineText.GetAfterFirst(Lexing.Constants.LabelLineId)?.TrimFull();

            ValueField = new LineTextField(Lexing.Constants.LabelLineId, value);
            Content.Add(ValueField);
        }
Example #5
0
 public DefineLineView(DefineScriptLine scriptLine, VisualElement container)
     : base(scriptLine, container)
 {
     valueField = new LineTextField("Define", scriptLine.DefineValue);
     keyField   = new LineTextField("as", scriptLine.DefineKey);
     Content.Add(valueField);
     Content.Add(keyField);
 }
        public CommentLineView(int lineIndex, string lineText, VisualElement container)
            : base(lineIndex, container)
        {
            var value = lineText.GetAfterFirst(CommentScriptLine.IdentifierLiteral)?.TrimFull();

            valueField           = new LineTextField(CommentScriptLine.IdentifierLiteral, value);
            valueField.multiline = true;
            Content.Add(valueField);
        }
Example #7
0
        public CommentLineView(int lineIndex, string lineText, VisualElement container)
            : base(lineIndex, container)
        {
            var value = lineText.GetAfterFirst(Lexing.Constants.CommentLineId)?.TrimFull();

            valueField           = new LineTextField(Lexing.Constants.CommentLineId, value);
            valueField.multiline = true;
            Content.Add(valueField);
        }
Example #8
0
 private void AddParameterField (ParameterFieldData data)
 {
     var textField = new LineTextField(data.Id, data.Value ?? string.Empty);
     if (data.Nameless) textField.tooltip = data.Name;
     else textField.AddToClassList("NamedParameterLabel");
     parameterFields.Add(textField);
     // Show the un-assigned named parameters only when hovered or focused.
     if (data.Nameless || !hideParameters || !string.IsNullOrEmpty(data.Value))
         Content.Add(textField);
 }
Example #9
0
 public ErrorLineView(int lineIndex, string lineText, VisualElement container, string commandId, string error = default)
     : base(lineIndex, container)
 {
     CommandId  = commandId;
     valueField = new LineTextField(value: lineText);
     Content.Add(valueField);
     if (!string.IsNullOrEmpty(error))
     {
         tooltip = "Error: " + error;
     }
 }
Example #10
0
 public ErrorLineView(CommandScriptLine scriptLine, VisualElement container, string error = default)
     : base(scriptLine, container)
 {
     CommandId  = scriptLine.CommandName.ToLowerInvariant();
     valueField = new LineTextField(value: scriptLine.Text);
     Content.Add(valueField);
     if (error != default)
     {
         tooltip = "Error: " + error;
     }
 }
Example #11
0
        public void GenerateForScript(string scriptText, Script scriptAsset, bool forceRebuild = false)
        {
            this.scriptAsset = scriptAsset;
            ScriptModified   = false;

            // Prevent re-generating the editor after saving the script (applying the changes done in the editor).
            if (!forceRebuild && lastGeneratedTextHash == scriptText.GetHashCode())
            {
                // Hightlight played line if we're here after a hot-reload.
                if (Engine.Initialized && Engine.Behaviour is RuntimeBehaviour)
                {
                    HighlightPlayedCommand(Engine.GetService <IScriptPlayer>()?.PlayedCommand);
                }
                return;
            }

            // Otherwise the script will generate twice when entering playmode.
            if (EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPlaying)
            {
                return;
            }

            // Otherwise nullref could happen when recompiling with a script asset selected.
            EditorApplication.delayCall += GenerateDelayed;

            void GenerateDelayed()
            {
                var editorLocked = !config.HotReloadScripts && EditorApplication.isPlayingOrWillChangePlaymode;

                linesContainer.SetEnabled(!editorLocked);
                infoLabel.style.display = editorLocked ? DisplayStyle.None : DisplayStyle.Flex;

                LineTextField.ResetPerScriptStaticData();
                Lines.Clear();
                linesContainer.Clear();
                var textLines = Script.SplitScriptText(scriptText);

                for (int i = 0; i < textLines.Length; i++)
                {
                    if (textLines.Length > showLoadAt && (i % showLoadAt) == 0) // Update bar for each n processed items.
                    {
                        if (EditorUtility.DisplayCancelableProgressBar("Generating Visual Editor", "Processing naninovel script...", i / (float)textLines.Length))
                        {
                            infoLabel.style.display = DisplayStyle.None;
                            linesContainer.Clear();
                            EditorUtility.ClearProgressBar();
                            Add(new IMGUIContainer(() => EditorGUILayout.HelpBox("Visual editor generation has been canceled.", MessageType.Error)));
                            return;
                        }
                    }
                    var textLine = textLines[i];
                    if (string.IsNullOrEmpty(textLine))
                    {
                        Lines.Add(null); // Skip empty lines.
                        continue;
                    }
                    var lineView = CreateLineView(i, textLine);
                    Lines.Add(lineView);
                    if (ViewRange.Contains(i))
                    {
                        linesContainer.Add(lineView);
                    }
                }

                EditorUtility.ClearProgressBar();

                if (Lines.Count > config.EditorPageLength)
                {
                    paginationView.style.display = DisplayStyle.Flex;
                    UpdatePaginationLabel();
                }
                else
                {
                    paginationView.style.display = DisplayStyle.None;
                }

                Engine.OnInitializationFinished -= HandleEngineInitialized;
                if (Engine.Initialized)
                {
                    HandleEngineInitialized();
                }
                else
                {
                    Engine.OnInitializationFinished += HandleEngineInitialized;
                }

                if (textLines.Length > showLoadAt)
                {
                    EditorUtility.DisplayProgressBar("Generating Visual Editor", "Building layout...", .5f);
                }
                EditorApplication.delayCall += EditorUtility.ClearProgressBar;

                var hotKeyInfo   = config.InsertLineKey == KeyCode.None ? string.Empty : $" or {config.InsertLineKey}";
                var modifierInfo = (config.InsertLineKey == KeyCode.None || config.InsertLineModifier == EventModifiers.None) ? string.Empty : $"{config.InsertLineModifier}+";

                if (!string.IsNullOrEmpty(modifierInfo))
                {
                    hotKeyInfo = hotKeyInfo.Insert(4, modifierInfo);
                }
                infoLabel.text    = $"Right-click{hotKeyInfo} to insert a new line";
                infoLabel.tooltip = "Hotkeys can be changed in the script configuration menu (Naninovel -> Configuration -> Script).";
            }
        }
 public GenericTextLineView(GenericTextScriptLine scriptLine, VisualElement container)
     : base(scriptLine, container)
 {
     valueField = new LineTextField(value: scriptLine.Text);
     Content.Add(valueField);
 }
Example #13
0
        public static ScriptLineView CreateOrError(CommandScriptLine scriptLine, VisualElement container, bool hideParameters, bool @default = false)
        {
            ErrorLineView Error(string error) => new ErrorLineView(scriptLine, container, error);

            if (!scriptLine.Valid)
            {
                return(Error("Incorrect syntax."));
            }

            var commandType = Command.FindCommandType(scriptLine.CommandName);

            if (commandType is null)
            {
                return(Error($"Unknown command `{scriptLine.CommandName}`."));
            }

            var commandLineView = new CommandLineView(scriptLine, container);

            commandLineView.hideParameters = hideParameters;
            commandLineView.CommandId      = scriptLine.CommandName;
            var nameLabel = new Label(scriptLine.CommandName);

            nameLabel.name = "InputLabel";
            nameLabel.AddToClassList("Inlined");
            commandLineView.Content.Add(nameLabel);

            var paramaterFieldInfos = commandType.GetProperties()
                                      .Where(property => property.IsDefined(typeof(Command.CommandParameterAttribute), false)).ToList();
            var parameterAttributes = paramaterFieldInfos
                                      .Select(f => f.GetCustomAttributes(typeof(Command.CommandParameterAttribute), false).First() as Command.CommandParameterAttribute).ToList();

            Debug.Assert(paramaterFieldInfos.Count == parameterAttributes.Count);

            for (int i = 0; i < paramaterFieldInfos.Count; i++)
            {
                var paramFieldInfo = paramaterFieldInfos[i];
                var paramAttribute = parameterAttributes[i];

                var paramName = paramAttribute.Alias != null && scriptLine.CommandParameters.ContainsKey(paramAttribute.Alias) ? paramAttribute.Alias : paramFieldInfo.Name;
                if (!scriptLine.CommandParameters.ContainsKey(paramName) && !paramAttribute.Optional && !@default)
                {
                    return(Error($"Missing `{paramName}` parameter."));
                }

                scriptLine.CommandParameters.TryGetValue(paramName, out var paramValue);
                var textField = new LineTextField(paramAttribute.Alias ?? char.ToLowerInvariant(paramName[0]) + paramName.Substring(1), paramValue);
                // Show parameter ID of the nameless parameters via tooltip.
                if (string.IsNullOrEmpty(textField.label))
                {
                    textField.tooltip = paramFieldInfo.Name;
                }
                else
                {
                    textField.AddToClassList("NamedParameterLabel");
                }
                commandLineView.parameterFields.Add(textField);
                // Show the un-assigned named parameters only when hovered or focused.
                if (string.IsNullOrEmpty(textField.label) || !hideParameters || !string.IsNullOrEmpty(textField.value))
                {
                    commandLineView.Content.Add(textField);
                }
            }

            foreach (var paramId in scriptLine.CommandParameters.Keys)
            {
                if (parameterAttributes.Exists(a => a.Alias?.EqualsFastIgnoreCase(paramId) ?? false))
                {
                    continue;
                }
                if (paramaterFieldInfos.Exists(f => f.Name.EqualsFastIgnoreCase(paramId)))
                {
                    continue;
                }
                return(Error($"Unsupported `{paramId}` parameter."));
            }

            return(commandLineView);
        }
Example #14
0
 public CommentLineView(CommentScriptLine scriptLine, VisualElement container)
     : base(scriptLine, container)
 {
     valueField = new LineTextField(CommentScriptLine.IdentifierLiteral, scriptLine.CommentText);
     Content.Add(valueField);
 }
Example #15
0
 public LabelLineView(LabelScriptLine scriptLine, VisualElement container)
     : base(scriptLine, container)
 {
     valueField = new LineTextField(LabelScriptLine.IdentifierLiteral, scriptLine.LabelText);
     Content.Add(valueField);
 }