コード例 #1
0
        private void DoInspectorGroupingGUI(NodeGUI node)
        {
            if (node.groupingKeyword == null)
            {
                return;
            }

            EditorGUILayout.HelpBox("Grouping: Create group of assets.", MessageType.Info);
            UpdateNodeName(node);

            GUILayout.Space(10f);

            node.currentPlatform = UpdateCurrentPlatform(node.currentPlatform);

            using (new EditorGUILayout.VerticalScope(GUI.skin.box)) {
                var newGroupingKeyword = EditorGUILayout.TextField(
                    "Grouping Keyword",
                    SystemDataUtility.GetPlatformValue(
                        node.groupingKeyword.ReadonlyDict(),
                        node.currentPlatform
                        ).ToString()
                    );
                EditorGUILayout.HelpBox("Grouping Keyword requires \"*\" in itself. It assumes there is a pattern such as \"ID_0\" in incoming paths when configured as \"ID_*\" ", MessageType.Info);


                IntegratedGUIGrouping.ValidateGroupingKeyword(
                    newGroupingKeyword,
                    () => {
//						EditorGUILayout.HelpBox("groupingKeyword is empty.", MessageType.Error);
                },
                    () => {
//						EditorGUILayout.HelpBox("grouping keyword does not contain " + AssetBundleGraphSettings.KEYWORD_WILDCARD + " groupingKeyword:" + newGroupingKeyword, MessageType.Error);
                }
                    );

                if (newGroupingKeyword != SystemDataUtility.GetPlatformValue(
                        node.groupingKeyword.ReadonlyDict(),
                        node.currentPlatform
                        ).ToString()
                    )
                {
                    node.BeforeSave();
                    node.groupingKeyword.Add(SystemDataUtility.CreateKeyNameFromString(node.currentPlatform), newGroupingKeyword);
                    node.Save();
                }
            }

            UpdateDeleteSetting(node);
        }
コード例 #2
0
        private void DoInspectorPrefabricatorGUI(NodeGUI node)
        {
            EditorGUILayout.HelpBox("Prefabricator: Create prefab with given assets and script.", MessageType.Info);
            UpdateNodeName(node);

            using (new EditorGUILayout.HorizontalScope(GUI.skin.box)) {
                GUILayout.Label("Prefabricator Class");
                if (GUILayout.Button(node.scriptAttrNameOrClassName, "Popup"))
                {
                    /*
                     *      collect type name or "Name" attribute parameter from extended-PrefabricatorBase class.
                     */
                    var prefabricatorCandidateTypeNameOrAttrName = PrefabricatorBase.GetPrefabricatorAttrName_ClassNameDict();

                    // prepare for no class found.
                    if (!prefabricatorCandidateTypeNameOrAttrName.Any())
                    {
                        var menu = new GenericMenu();

                        menu.AddItem(
                            new GUIContent("Generate Example Prefabricator Script"),
                            false,
                            () => {
                            // generate sample.
                            AssetBundleGraphEditorWindow.GenerateScript(AssetBundleGraphEditorWindow.ScriptType.SCRIPT_PREFABRICATOR);
                        }
                            );

                        menu.ShowAsContext();
                        return;
                    }

                    /*
                     *      displays type name or attribute if exist.
                     */
                    NodeGUI.ShowTypeNamesMenu(
                        node.scriptAttrNameOrClassName,
                        prefabricatorCandidateTypeNameOrAttrName.Keys.ToList(),
                        (string selectedClassNameOrAttrName) => {
                        node.BeforeSave();
                        node.scriptAttrNameOrClassName = selectedClassNameOrAttrName;
                        node.Save();
                    }
                        );
                }
            }
        }
コード例 #3
0
        private void DoInspectorPrefabricatorGUI(NodeGUI node)
        {
            EditorGUILayout.HelpBox("Prefabricator: Create prefab with given assets and script.", MessageType.Info);
            UpdateNodeName(node);

            using (new EditorGUILayout.VerticalScope(GUI.skin.box)) {
                GUIStyle s = new GUIStyle("TextFieldDropDownText");

                /*
                 *      check prefabricator script-type string.
                 */
                if (string.IsNullOrEmpty(node.scriptClassName))
                {
                    s.fontStyle = FontStyle.Bold;
                    s.fontSize  = 12;
                }
                else
                {
                    var loadedType = System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(node.scriptClassName);

                    if (loadedType == null)
                    {
                        s.fontStyle = FontStyle.Bold;
                        s.fontSize  = 12;
                    }
                }

                GUILayout.Label("ここをドロップダウンにする。");
                var newScriptClass = EditorGUILayout.TextField("Classname", node.scriptClassName, s);

                if (newScriptClass != node.scriptClassName)
                {
                    node.BeforeSave();
                    node.scriptClassName = newScriptClass;
                    node.Save();
                }
            }
        }
コード例 #4
0
        private void UpdateNodeName(NodeGUI node)
        {
            var newName = EditorGUILayout.TextField("Node Name", node.name);

            if (NodeGUIUtility.allNodeNames != null)
            {
                var overlapping = NodeGUIUtility.allNodeNames.GroupBy(x => x)
                                  .Where(group => group.Count() > 1)
                                  .Select(group => group.Key);
                if (overlapping.Any() && overlapping.Contains(newName))
                {
                    EditorGUILayout.HelpBox("This node name already exist. Please put other name:" + newName, MessageType.Error);
                    AssetBundleGraphEditorWindow.AddNodeException(new NodeException("Node name " + newName + " already exist.", node.nodeId));
                }
            }

            if (newName != node.name)
            {
                node.BeforeSave();
                node.name = newName;
                node.UpdateNodeRect();
                node.Save();
            }
        }
コード例 #5
0
        private bool UpdateDeleteSetting(NodeGUI currentNode)
        {
            var currentNodePlatformPackageKey = SystemDataUtility.CreateKeyNameFromString(currentNode.currentPlatform);

            if (currentNodePlatformPackageKey == AssetBundleGraphSettings.PLATFORM_DEFAULT_NAME)
            {
                return(false);
            }

            var deleted = false;

            using (new EditorGUILayout.HorizontalScope()) {
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("Use Default Setting", GUILayout.Width(150)))
                {
                    currentNode.BeforeSave();
                    currentNode.DeleteCurrentPackagePlatformKey(currentNodePlatformPackageKey);
                    GUI.FocusControl(string.Empty);
                    currentNode.Save();
                    deleted = true;
                }
            }
            return(deleted);
        }
コード例 #6
0
        private void DoInspectorExporterGUI(NodeGUI node)
        {
            if (node.exportTo == null)
            {
                return;
            }

            EditorGUILayout.HelpBox("Exporter: Export given files to output directory.", MessageType.Info);
            UpdateNodeName(node);

            GUILayout.Space(10f);

            node.currentPlatform = UpdateCurrentPlatform(node.currentPlatform);

            using (new EditorGUILayout.VerticalScope(GUI.skin.box)) {
                EditorGUILayout.LabelField("Export Path:");
                var newExportPath = EditorGUILayout.TextField(
                    SystemDataUtility.GetProjectName(),
                    SystemDataUtility.GetPlatformValue(
                        node.exportTo.ReadonlyDict(),
                        node.currentPlatform
                        ).ToString()
                    );

                var exporterrNodePath = FileUtility.GetPathWithProjectPath(newExportPath);
                if (IntegratedGUIExporter.ValidateExportPath(
                        newExportPath,
                        exporterrNodePath,
                        () => {
                    // TODO Make text field bold
                },
                        () => {
                    using (new EditorGUILayout.HorizontalScope()) {
                        EditorGUILayout.LabelField(exporterrNodePath + " does not exist.");
                        if (GUILayout.Button("Create directory"))
                        {
                            Directory.CreateDirectory(exporterrNodePath);
                            node.Save();
                        }
                    }
                    EditorGUILayout.Space();

                    EditorGUILayout.LabelField("Available Directories:");
                    string[] dirs = Directory.GetDirectories(Path.GetDirectoryName(exporterrNodePath));
                    foreach (string s in dirs)
                    {
                        EditorGUILayout.LabelField(s);
                    }
                }
                        ))
                {
                    using (new EditorGUILayout.HorizontalScope()) {
                        GUILayout.FlexibleSpace();
                                                #if UNITY_EDITOR_OSX
                        string buttonName = "Reveal in Finder";
                                                #else
                        string buttonName = "Show in Explorer";
                                                #endif
                        if (GUILayout.Button(buttonName))
                        {
                            EditorUtility.RevealInFinder(exporterrNodePath);
                        }
                    }
                }


                if (newExportPath != SystemDataUtility.GetPlatformValue(
                        node.exportTo.ReadonlyDict(),
                        node.currentPlatform
                        ).ToString()
                    )
                {
                    node.BeforeSave();
                    node.exportTo.Add(SystemDataUtility.CreateKeyNameFromString(node.currentPlatform), newExportPath);
                    node.Save();
                }
            }

            UpdateDeleteSetting(node);
        }
コード例 #7
0
        private void DoInspectorBundleBuilderGUI(NodeGUI node)
        {
            if (node.enabledBundleOptions == null)
            {
                return;
            }

            EditorGUILayout.HelpBox("BundleBuilder: Build asset bundles with given asset bundle settings.", MessageType.Info);
            UpdateNodeName(node);

            GUILayout.Space(10f);

            node.currentPlatform = UpdateCurrentPlatform(node.currentPlatform);

            using (new EditorGUILayout.VerticalScope(GUI.skin.box)) {
                var bundleOptions = SystemDataUtility.GetPlatformValue(
                    node.enabledBundleOptions.ReadonlyDict(),
                    node.currentPlatform
                    );

                var plartform_pakcage_key = SystemDataUtility.CreateKeyNameFromString(node.currentPlatform);

                for (var i = 0; i < AssetBundleGraphSettings.DefaultBundleOptionSettings.Count; i++)
                {
                    var enablablekey = AssetBundleGraphSettings.DefaultBundleOptionSettings[i];

                    // contains keyword == enabled. if not, disabled.
                    var isEnabled = bundleOptions.Contains(enablablekey);

                    var result = EditorGUILayout.ToggleLeft(enablablekey, isEnabled);
                    if (result != isEnabled)
                    {
                        node.BeforeSave();

                        var resultsDict = node.enabledBundleOptions.ReadonlyDict();
                        var resultList  = new List <string>();
                        if (resultsDict.ContainsKey(plartform_pakcage_key))
                        {
                            resultList = resultsDict[plartform_pakcage_key];
                        }

                        if (result)
                        {
                            if (!resultList.Contains(enablablekey))
                            {
                                var currentEnableds = new List <string>();
                                if (resultsDict.ContainsKey(plartform_pakcage_key))
                                {
                                    currentEnableds = resultsDict[plartform_pakcage_key];
                                }
                                currentEnableds.Add(enablablekey);

                                node.enabledBundleOptions.Add(
                                    SystemDataUtility.CreateKeyNameFromString(node.currentPlatform),
                                    currentEnableds
                                    );
                            }
                        }

                        if (!result)
                        {
                            if (resultList.Contains(enablablekey))
                            {
                                var currentEnableds = new List <string>();
                                if (resultsDict.ContainsKey(plartform_pakcage_key))
                                {
                                    currentEnableds = resultsDict[plartform_pakcage_key];
                                }
                                currentEnableds.Remove(enablablekey);

                                node.enabledBundleOptions.Add(
                                    SystemDataUtility.CreateKeyNameFromString(node.currentPlatform),
                                    currentEnableds
                                    );
                            }
                        }

                        /*
                         *                              Cannot use options DisableWriteTypeTree and IgnoreTypeTreeChanges at the same time.
                         */
                        if (enablablekey == "Disable Write TypeTree" && result &&
                            node.enabledBundleOptions.ReadonlyDict()[SystemDataUtility.CreateKeyNameFromString(node.currentPlatform)].Contains("Ignore TypeTree Changes"))
                        {
                            var newEnableds = node.enabledBundleOptions.ReadonlyDict()[SystemDataUtility.CreateKeyNameFromString(node.currentPlatform)];
                            newEnableds.Remove("Ignore TypeTree Changes");

                            node.enabledBundleOptions.Add(
                                SystemDataUtility.CreateKeyNameFromString(node.currentPlatform),
                                newEnableds
                                );
                        }

                        if (enablablekey == "Ignore TypeTree Changes" && result &&
                            node.enabledBundleOptions.ReadonlyDict()[SystemDataUtility.CreateKeyNameFromString(node.currentPlatform)].Contains("Disable Write TypeTree"))
                        {
                            var newEnableds = node.enabledBundleOptions.ReadonlyDict()[SystemDataUtility.CreateKeyNameFromString(node.currentPlatform)];
                            newEnableds.Remove("Disable Write TypeTree");

                            node.enabledBundleOptions.Add(
                                SystemDataUtility.CreateKeyNameFromString(node.currentPlatform),
                                newEnableds
                                );
                        }

                        node.Save();
                        return;
                    }
                }
            }

            UpdateDeleteSetting(node);
        }
コード例 #8
0
        private void DoInspectorBundlizerGUI(NodeGUI node)
        {
            if (node.bundleNameTemplate == null)
            {
                return;
            }

            EditorGUILayout.HelpBox("Bundlizer: Create asset bundle settings with given group of assets.", MessageType.Info);
            UpdateNodeName(node);

            GUILayout.Space(10f);

            node.currentPlatform = UpdateCurrentPlatform(node.currentPlatform);

            using (new EditorGUILayout.VerticalScope(GUI.skin.box)) {
                var bundleNameTemplate = EditorGUILayout.TextField(
                    "Bundle Name Template",
                    SystemDataUtility.GetPlatformValue(
                        node.bundleNameTemplate.ReadonlyDict(),
                        node.currentPlatform
                        ).ToString()
                    ).ToLower();

                IntegratedGUIBundlizer.ValidateBundleNameTemplate(
                    bundleNameTemplate,
                    () => {
//						EditorGUILayout.HelpBox("No Bundle Name Template set.", MessageType.Error);
                }
                    );

                if (bundleNameTemplate != SystemDataUtility.GetPlatformValue(
                        node.bundleNameTemplate.ReadonlyDict(),
                        node.currentPlatform
                        ).ToString()
                    )
                {
                    node.BeforeSave();
                    node.bundleNameTemplate.Add(SystemDataUtility.CreateKeyNameFromString(node.currentPlatform), bundleNameTemplate);
                    node.Save();
                }

                GUILayout.Label("Variants:");
                for (int i = 0; i < node.variants.Keys.Count; ++i)
                {
                    var inputConnectionId = node.variants.Keys[i];

                    using (new GUILayout.HorizontalScope()) {
                        if (GUILayout.Button("-", GUILayout.Width(30)))
                        {
                            node.BeforeSave();
                            node.variants.Remove(inputConnectionId);
                            node.DeleteInputPoint(inputConnectionId);
                        }
                        else
                        {
                            var variantName = node.variants.Values[i];

                            GUIStyle s             = new GUIStyle((GUIStyle)"TextFieldDropDownText");
                            Action   makeStyleBold = () => {
                                s.fontStyle = FontStyle.Bold;
                                s.fontSize  = 12;
                            };

                            IntegratedGUIBundlizer.ValidateVariantName(variantName, node.variants.Values,
                                                                       makeStyleBold,
                                                                       makeStyleBold,
                                                                       makeStyleBold);

                            variantName = EditorGUILayout.TextField(variantName, s);

                            if (variantName != node.variants.Values[i])
                            {
                                node.BeforeSave();
                                node.variants.Values[i] = variantName;
                                node.RenameInputPoint(inputConnectionId, variantName);
                            }
                        }
                    }
                }

                if (GUILayout.Button("+"))
                {
                    node.BeforeSave();
                    var newid = Guid.NewGuid().ToString();
                    node.variants.Add(newid, AssetBundleGraphSettings.BUNDLIZER_VARIANTNAME_DEFAULT);
                    node.AddInputPoint(newid, AssetBundleGraphSettings.BUNDLIZER_VARIANTNAME_DEFAULT);
                }
            }

            UpdateDeleteSetting(node);
        }
コード例 #9
0
        private void DoInspectorModifierGUI(NodeGUI node)
        {
            EditorGUILayout.HelpBox("Modifier: Force apply asset settings to given assets.", MessageType.Info);
            UpdateNodeName(node);

            GUILayout.Space(10f);

            var currentModifierTargetType = IntegratedGUIModifier.ModifierOperationTargetTypeName(node.nodeId);

            using (new EditorGUILayout.VerticalScope(GUI.skin.box)) {
                // show incoming type of Assets and reset interface.
                {
                    var isOperationDataExist = false;
                    IntegratedGUIModifier.ValidateModifiyOperationData(
                        node.nodeId,
                        node.currentPlatform,
                        () => {
                        GUILayout.Label("No modifier data found, please Reload first.");
                    },
                        () => {
                        isOperationDataExist = true;
                    }
                        );

                    if (!isOperationDataExist)
                    {
                        return;
                    }

                    using (new EditorGUILayout.HorizontalScope()) {
                        GUILayout.Label("Target Type:");
                        GUILayout.Label(currentModifierTargetType);
                    }

                    /*
                     *      reset whole platform's data for this modifier.
                     */
                    if (GUILayout.Button("Reset Modifier"))
                    {
                        var modifierFolderPath = FileUtility.PathCombine(AssetBundleGraphSettings.MODIFIER_OPERATOR_DATAS_PLACE, node.nodeId);
                        FileUtility.RemakeDirectory(modifierFolderPath);
                        node.Save();
                        modifierOperatorInstance = null;
                        return;
                    }
                }

                GUILayout.Space(10f);

                var usingScriptMode = !string.IsNullOrEmpty(node.scriptClassName);

                // use modifier script manually.
                {
                    GUIStyle s = new GUIStyle("TextFieldDropDownText");

                    /*
                     *      check prefabricator script-type string.
                     */
                    if (string.IsNullOrEmpty(node.scriptClassName))
                    {
                        s.fontStyle = FontStyle.Bold;
                        s.fontSize  = 12;
                    }
                    else
                    {
                        var loadedType = System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(node.scriptClassName);

                        if (loadedType == null)
                        {
                            s.fontStyle = FontStyle.Bold;
                            s.fontSize  = 12;
                        }
                    }

                    var before = !string.IsNullOrEmpty(node.scriptClassName);
                    usingScriptMode = EditorGUILayout.ToggleLeft("Use ModifierOperator Script", !string.IsNullOrEmpty(node.scriptClassName));

                    // detect mode changed.
                    if (before != usingScriptMode)
                    {
                        // checked. initialize value of scriptClassName.
                        if (usingScriptMode)
                        {
                            node.BeforeSave();
                            node.scriptClassName = "MyModifier";
                            node.Save();
                        }

                        // unchecked.
                        if (!usingScriptMode)
                        {
                            node.BeforeSave();
                            node.scriptClassName = string.Empty;
                            node.Save();
                        }
                    }

                    if (!usingScriptMode)
                    {
                        EditorGUI.BeginDisabledGroup(true);
                    }
                    GUILayout.Label("ここをドロップダウンにする。2");
                    var newScriptClass = EditorGUILayout.TextField("Classname", node.scriptClassName, s);
                    if (newScriptClass != node.scriptClassName)
                    {
                        node.BeforeSave();
                        node.scriptClassName = newScriptClass;
                        node.Save();
                    }
                    if (!usingScriptMode)
                    {
                        EditorGUI.EndDisabledGroup();
                    }
                }

                GUILayout.Space(10f);

                if (usingScriptMode)
                {
                    EditorGUI.BeginDisabledGroup(true);
                }

                // show for each platform tab.

                var currentPlatform = node.currentPlatform;
                node.currentPlatform = UpdateCurrentPlatform(node.currentPlatform);

                /*
                 *      if platform tab is changed, renew modifierOperatorInstance for that tab.
                 */
                if (currentPlatform != node.currentPlatform)
                {
                    modifierOperatorInstance = null;
                }

                /*
                 *      reload modifierOperator instance from saved modifierOperator data.
                 */
                if (modifierOperatorInstance == null)
                {
                    var modifierOperatorDataPath = IntegratedGUIModifier.ModifierDataPathForeachPlatform(node.nodeId, node.currentPlatform);

                    // choose default modifierOperatorData if platform specified file is not exist.
                    if (!File.Exists(modifierOperatorDataPath))
                    {
                        modifierOperatorDataPath = IntegratedGUIModifier.ModifierDataPathForDefaultPlatform(node.nodeId);
                    }

                    var loadedModifierOperatorDataStr = string.Empty;
                    using (var sr = new StreamReader(modifierOperatorDataPath)) {
                        loadedModifierOperatorDataStr = sr.ReadToEnd();
                    }

                    var modifierOperatorType = TypeUtility.SupportedModifierOperatorDefinition[currentModifierTargetType];

                    /*
                     *      create instance from saved modifierOperator data.
                     */
                    modifierOperatorInstance = typeof(NodeGUIEditor)
                                               .GetMethod("FromJson")
                                               .MakeGenericMethod(modifierOperatorType) // set desired generic type here.
                                               .Invoke(this, new object[] { loadedModifierOperatorDataStr }) as ModifierOperators.OperatorBase;
                }

                /*
                 *      Show ModifierOperator Inspector.
                 */
                if (modifierOperatorInstance != null)
                {
                    Action changed = () => {
                        var data       = JsonUtility.ToJson(modifierOperatorInstance);
                        var prettified = AssetBundleGraphEditorWindow.PrettifyJson(data);

                        var modifierOperatorDataPath = IntegratedGUIModifier.ModifierDataPathForeachPlatform(node.nodeId, node.currentPlatform);

                        using (var sw = new StreamWriter(modifierOperatorDataPath)) {
                            sw.Write(prettified);
                        }

                        // reflect change of data.
                        AssetDatabase.Refresh();

                        modifierOperatorInstance = null;
                    };

                    GUILayout.Space(10f);

                    modifierOperatorInstance.DrawInspector(changed);
                }

                var deleted = UpdateDeleteSetting(node);
                if (deleted)
                {
                    // source platform depended data is deleted. reload instance for reloading instance from data.
                    modifierOperatorInstance = null;
                }

                if (usingScriptMode)
                {
                    EditorGUI.EndDisabledGroup();
                }
            }
        }
コード例 #10
0
        private void DoInspectorLoaderGUI(NodeGUI node)
        {
            if (node.loadPath == null)
            {
                return;
            }

            EditorGUILayout.HelpBox("Loader: Load assets in given directory path.", MessageType.Info);
            UpdateNodeName(node);

            GUILayout.Space(10f);

            /*
             *      platform & package
             */
            if (packageEditMode)
            {
                EditorGUI.BeginDisabledGroup(true);
            }

            // update platform & package.
            node.currentPlatform = UpdateCurrentPlatform(node.currentPlatform);

            using (new EditorGUILayout.VerticalScope(GUI.skin.box)) {
                EditorGUILayout.LabelField("Load Path:");
                var newLoadPath = EditorGUILayout.TextField(
                    SystemDataUtility.GetProjectName() + AssetBundleGraphSettings.ASSETS_PATH,
                    SystemDataUtility.GetPlatformValue(
                        node.loadPath.ReadonlyDict(),
                        node.currentPlatform
                        ).ToString()
                    );
                var loaderNodePath = FileUtility.GetPathWithAssetsPath(newLoadPath);
                IntegratedGUILoader.ValidateLoadPath(
                    newLoadPath,
                    loaderNodePath,
                    () => {
                    //EditorGUILayout.HelpBox("load path is empty.", MessageType.Error);
                },
                    () => {
                    //EditorGUILayout.HelpBox("Directory not found:" + loaderNodePath, MessageType.Error);
                }
                    );

                if (newLoadPath != SystemDataUtility.GetPlatformValue(
                        node.loadPath.ReadonlyDict(),
                        node.currentPlatform
                        ).ToString()
                    )
                {
                    node.BeforeSave();
                    node.loadPath.Add(SystemDataUtility.CreateKeyNameFromString(node.currentPlatform), newLoadPath);
                    node.Save();
                }
            }

            if (packageEditMode)
            {
                EditorGUI.EndDisabledGroup();
            }
            UpdateDeleteSetting(node);
        }
コード例 #11
0
        private void DoInspectorFilterGUI(NodeGUI node)
        {
            EditorGUILayout.HelpBox("Filter: Filter incoming assets by keywords and types. You can use regular expressions for keyword field.", MessageType.Info);
            UpdateNodeName(node);

            using (new EditorGUILayout.VerticalScope(GUI.skin.box)) {
                GUILayout.Label("Filter Settings:");
                for (int i = 0; i < node.filterContainsKeywords.Count; i++)
                {
                    Action messageAction = null;

                    using (new GUILayout.HorizontalScope()) {
                        if (GUILayout.Button("-", GUILayout.Width(30)))
                        {
                            node.BeforeSave();
                            node.filterContainsKeywords.RemoveAt(i);
                            node.filterContainsKeytypes.RemoveAt(i);
                            node.DeleteFilterOutputPoint(i);
                        }
                        else
                        {
                            var newContainsKeyword = node.filterContainsKeywords[i];

                            /*
                             *                                      generate keyword + keytype string for compare exists setting vs new modifying setting at once.
                             */
                            var currentKeywordsSource = new List <string>(node.filterContainsKeywords);
                            var currentKeytypesSource = new List <string>(node.filterContainsKeytypes);

                            var currentKeytype = currentKeytypesSource[i];

                            for (var j = 0; j < currentKeywordsSource.Count; j++)
                            {
                                currentKeywordsSource[j] = currentKeywordsSource[j] + currentKeytypesSource[j];
                            }

                            // remove current choosing one from compare target.
                            currentKeywordsSource.RemoveAt(i);
                            var currentKeywords = new List <string>(currentKeywordsSource);

                            GUIStyle s = new GUIStyle((GUIStyle)"TextFieldDropDownText");

                            IntegratedGUIFilter.ValidateFilter(
                                newContainsKeyword + currentKeytype,
                                currentKeywords,
                                () => {
                                s.fontStyle = FontStyle.Bold;
                                s.fontSize  = 12;
                            },
                                () => {
                                s.fontStyle = FontStyle.Bold;
                                s.fontSize  = 12;
                            }
                                );

                            using (new EditorGUILayout.HorizontalScope()) {
                                newContainsKeyword = EditorGUILayout.TextField(node.filterContainsKeywords[i], s, GUILayout.Width(120));
                                var currentIndex = i;
                                if (GUILayout.Button(node.filterContainsKeytypes[i], "Popup"))
                                {
                                    NodeGUI.ShowFilterKeyTypeMenu(
                                        node.filterContainsKeytypes[currentIndex],
                                        (string selectedTypeStr) => {
                                        node.BeforeSave();
                                        node.filterContainsKeytypes[currentIndex] = selectedTypeStr;
                                        node.Save();
                                    }
                                        );
                                }
                            }

                            if (newContainsKeyword != node.filterContainsKeywords[i])
                            {
                                node.BeforeSave();
                                node.filterContainsKeywords[i] = newContainsKeyword;
                                node.RenameFilterOutputPointLabel(i, node.filterContainsKeywords[i]);
                            }
                        }
                    }

                    if (messageAction != null)
                    {
                        using (new GUILayout.HorizontalScope()) {
                            messageAction.Invoke();
                        }
                    }
                }

                // add contains keyword interface.
                if (GUILayout.Button("+"))
                {
                    node.BeforeSave();
                    var addingIndex = node.filterContainsKeywords.Count;
                    var newKeyword  = AssetBundleGraphSettings.DEFAULT_FILTER_KEYWORD;

                    node.filterContainsKeywords.Add(newKeyword);
                    node.filterContainsKeytypes.Add(AssetBundleGraphSettings.DEFAULT_FILTER_KEYTYPE);

                    node.AddFilterOutputPoint(addingIndex, AssetBundleGraphSettings.DEFAULT_FILTER_KEYWORD);
                }
            }
        }