コード例 #1
0
        public static void CreateFromTemplateAndStyle(VisualElement container, string templateName)
        {
            VisualTreeAsset template = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(templatePath + templateName + ".uxml");

            template.CloneTree(container);
            container.styleSheets.Add(AssetDatabase.LoadAssetAtPath <StyleSheet>(templatePath + templateName + ".uss"));
            container.ClearClassList();
            container.AddToClassList(templateName);
        }
コード例 #2
0
        public GroupNode()
        {
            m_ContentItem = new GroupNodeDropArea();
            m_ContentItem.ClearClassList();
            m_ContentItem.AddToClassList("content");

            var visualTree = EditorGUIUtility.Load("UXML/GraphView/GroupNode.uxml") as VisualTreeAsset;

            m_MainContainer = visualTree.CloneTree(null);
            m_MainContainer.AddToClassList("mainContainer");

            m_HeaderItem = m_MainContainer.Q(name: "header");
            m_HeaderItem.AddToClassList("header");

            m_TitleItem = m_MainContainer.Q <Label>(name: "titleLabel");
            m_TitleItem.AddToClassList("label");

            m_TitleEditor = m_MainContainer.Q(name: "titleField") as TextField;

            m_TitleEditor.AddToClassList("textfield");
            m_TitleEditor.visible = false;

            m_TitleEditor.RegisterCallback <FocusOutEvent>(e => { OnEditTitleFinished(); });
            m_TitleEditor.RegisterCallback <KeyDownEvent>(OnKeyPressed);

            VisualElement contentPlaceholder = m_MainContainer.Q(name: "contentPlaceholder");

            contentPlaceholder.Add(m_ContentItem);

            Add(m_MainContainer);

            ClearClassList();
            AddToClassList("groupNode");

            clippingOptions = ClippingOptions.ClipAndCacheContents;
            capabilities   |= Capabilities.Selectable | Capabilities.Movable | Capabilities.Deletable;

            m_HeaderItem.RegisterCallback <PostLayoutEvent>(OnHeaderSizeChanged);
            RegisterCallback <PostLayoutEvent>(e => { MoveElements(); });
            RegisterCallback <MouseDownEvent>(OnMouseUpEvent);

            this.schedule.Execute(e => {
                if (visible && (m_Initialized == false))
                {
                    m_Initialized = true;

                    UpdateGeometryFromContent();
                }
            });
        }
コード例 #3
0
        void DoSearch()
        {
            EditorPrefs.SetString(searchEditorPrefsKey, searchString);

            if (string.IsNullOrEmpty(searchString))
            {
                searchRoot.Clear();
                searchRoot.visible = false;
                return;
            }

            string searchStringLower = searchString.ToLower();

            //Cache current page
            string currentPageStateNameCached = currentPageStateName;

            //Clear the previous search
            searchRoot.Clear();
            searchRoot.visible = true;

            //searchRootTemp is an un-parented root to append to so we can search content.
            VisualElement searchRootTemp = new VisualElement();
            Dictionary <IDocumentationPage <T>, List <string> > searchResults = new Dictionary <IDocumentationPage <T>, List <string> >();

            StringBuilder stringBuilder = new StringBuilder();

            foreach (IDocumentationPage <T> page in pages.Values)
            {
                if (!searchStringsCache.TryGetValue(page, out var searchStrings))
                {
                    searchStrings = new List <string>();
                    searchStringsCache.Add(page, searchStrings);

                    //Load the page under searchRootTemp
                    LoadPage(page, searchRootTemp);

                    //Get all the paragraph element's text (combined together)
                    searchRootTemp.Query(null, "paragraph-container").ForEach(paragraph =>
                    {
                        stringBuilder.Clear();
                        paragraph.Query <TextElement>().Build().ForEach(tE => stringBuilder.Append(tE.text));
                        searchStrings.Add(stringBuilder.ToString());
                        paragraph.Clear();
                    });
                    //Get all the text from the Text elements under searchRootTemp
                    searchRootTemp.Query <TextElement>().ForEach(element => searchStrings.Add(element.text));
                }

                foreach (string searchStringLocal in searchStrings)
                {
                    string searchStringLocalLower = searchStringLocal.ToLower();
                    if (searchStringLocalLower.Contains(searchStringLower))
                    {
                        if (!searchResults.TryGetValue(page, out var resultStrings))
                        {
                            searchResults.Add(page, resultStrings = new List <string>());
                        }
                        resultStrings.Add(searchStringLocal);
                    }
                }
            }

            List <string> matches = new List <string>(maxMatchCount);

            foreach (var result in searchResults)
            {
                //Result Container
                VisualElement resultContainer = new VisualElement();
                resultContainer.ClearClassList();
                resultContainer.AddToClassList("result-container");
                resultContainer.userData = result.Key;
                searchRoot.Add(resultContainer);

                //Result Button
                Button searchResultButton = window.AddFullWidthButton(result.Key.GetType(), resultContainer);
                searchResultButton.AddToClassList("result");
                Label resultLabel = RichTextUtility.AddInlineText(searchResultButton.text, searchResultButton);
                resultLabel.style.color = searchResultButton.style.color;
                searchResultButton.text = null;
                Label resultCountLabel = RichTextUtility.AddInlineText($" ({result.Value.Count} Results)", searchResultButton);
                resultCountLabel.style.color = new Color(1, 1, 1, 0.35f);
                searchResultButton.RegisterCallback <MouseUpEvent>(evt => searchRoot.visible = false);

                //Results (the string matches)
                VisualElement resultMatchesContainer = new VisualElement();
                resultMatchesContainer.ClearClassList();
                resultMatchesContainer.AddToClassList("result-matches-container");
                resultContainer.Add(resultMatchesContainer);

                //Create a hashset of all the matched words.
                matches.Clear();
                foreach (string m in result.Value)
                {
                    string match = Regex.Match(m, $@"\w*{searchStringLower}\w*", RegexOptions.IgnoreCase).Value;
                    if (matches.Contains(match))
                    {
                        continue;
                    }
                    matches.Add(match);
                    if (matches.Count > maxMatchCount)
                    {
                        break;
                    }
                }

                //Add a max of maxMatchCount inline text to the resultMatchesContainer
                int l = Mathf.Min(maxMatchCount, matches.Count);
                for (int i = 0; i < l; i++)
                {
                    //Create group for matched coloured text.
                    VisualElement inlineTextGroup = new VisualElement();
                    inlineTextGroup.ClearClassList();
                    inlineTextGroup.AddToClassList("inline-text-group");
                    inlineTextGroup.AddToClassList("result");
                    resultMatchesContainer.Add(inlineTextGroup);

                    int indexOf = matches[i].IndexOf(searchStringLower, StringComparison.OrdinalIgnoreCase);

                    Label matchContent;
                    if (matches[i].Length == searchStringLower.Length)
                    {
                        matchContent = RichTextUtility.AddInlineText(matches[i], inlineTextGroup);
                    }
                    else if (indexOf == 0)
                    {
                        matchContent = RichTextUtility.AddInlineText(matches[i].Substring(indexOf, searchStringLower.Length), inlineTextGroup);
                        RichTextUtility.AddInlineText(matches[i].Substring(searchStringLower.Length), inlineTextGroup);
                    }
                    else if (indexOf == matches[i].Length - searchStringLower.Length)
                    {
                        RichTextUtility.AddInlineText(matches[i].Substring(0, indexOf), inlineTextGroup);
                        matchContent = RichTextUtility.AddInlineText(matches[i].Substring(indexOf), inlineTextGroup);
                    }
                    else
                    {
                        RichTextUtility.AddInlineText(matches[i].Substring(0, indexOf), inlineTextGroup);
                        matchContent = RichTextUtility.AddInlineText(matches[i].Substring(indexOf, searchStringLower.Length), inlineTextGroup);
                        RichTextUtility.AddInlineText(matches[i].Substring(indexOf + searchStringLower.Length), inlineTextGroup);
                    }

                    matchContent.style.color = new Color(1, 0.5f, 0);
                }

                if (l != matches.Count)
                {
                    RichTextUtility.AddInlineText("...", resultMatchesContainer);
                }
            }

            searchRoot.Sort((a, b) => searchResults[(IDocumentationPage <T>)b.userData].Count.CompareTo(searchResults[(IDocumentationPage <T>)a.userData].Count));

            //Reset page
            currentPageStateName = currentPageStateNameCached;
        }
コード例 #4
0
        public DocumentationContent(VisualElement root, T window, string stateEditorPrefsKey = null)
        {
            this.window = window;
            this.stateEditorPrefsKey = stateEditorPrefsKey;

            searchEditorPrefsKey = $"{stateEditorPrefsKey}_Search";
            if (EditorPrefs.HasKey(searchEditorPrefsKey))
            {
                searchString = EditorPrefs.GetString(searchEditorPrefsKey);
            }
            searchFieldName = $"SearchField_{window.GetType().FullName}";

                        #if !UIELEMENT_BROWSER_BAR
            IMGUIContainer browserBar = new IMGUIContainer(BrowserBar)
            {
                style =
                {
                    height = 18
                }
            };
            root.Add(browserBar);
                        #else
            BrowserBar(root);
                        #endif

            /*	The content root contains the styles.
             * It also contains the scroll view and search root, with the scroll view containing the user-generated content */
            VisualElement content = new VisualElement
            {
                style =
                {
                    flexGrow = 1
                }
            };
            root.Add(content);
            StyleSheet docsStyleSheet = LoadAssetOfType <StyleSheet>("nDocumentationStyles", SearchFilter.Packages);
            content.styleSheets.Add(docsStyleSheet);

            StyleSheet codeStyleSheet = LoadAssetOfType <StyleSheet>("CsharpHighlightingStyles", SearchFilter.Packages);
            content.styleSheets.Add(codeStyleSheet);

            ScrollView scrollView = new ScrollView
            {
                name           = "Scroll View",
                showHorizontal = false,
                showVertical   = true
            };
            scrollView.AddToClassList("scroll-view");
            scrollView.contentContainer.AddToClassList("scroll-view-content");
            contentRoot = scrollView.contentContainer;
            content.Add(scrollView);

            searchRoot = new VisualElement();
            searchRoot.ClearClassList();
            searchRoot.AddToClassList("search-container");
            content.Add(searchRoot);
            searchRoot.StretchToParentSize();
            searchRoot.visible = false;

            SetCurrentDefaultRoot(contentRoot);
        }
コード例 #5
0
ファイル: RichTextUtility.cs プロジェクト: Hengle/NUtilities
        public static List <VisualElement> AddRichText(string text, IButtonRegistry buttonRegistry, VisualElement root, bool isInsideCodeBlock)
        {
            List <VisualElement>   results   = new List <VisualElement>();
            IEnumerable <RichText> richTexts = ParseRichText(text, isInsideCodeBlock);
            //Parse rich texts to create paragraphs.
            List <List <RichText> > paragraphs = new List <List <RichText> > {
                new List <RichText>()
            };

            foreach (RichText richText in richTexts)
            {
                if (richText.richTextTag.tag == RichTextTag.Tag.button || richText.richTextTag.tag == RichTextTag.Tag.code)
                {
                    paragraphs[paragraphs.Count - 1].Add(richText);
                    continue;
                }

                string[] strings = richText.associatedText.Split('\n');
                for (int i = 0; i < strings.Length; i++)
                {
                    if (i != 0)
                    {
                        paragraphs.Add(new List <RichText>());
                    }
                    //Split paragraph content (already split by tag) into individual words
                    string[] wordSplit = Regex.Split(strings[i], @"(?<=[ -])");                     //Split but keep delimiters attached.
                    foreach (var word in wordSplit)
                    {
                        if (!string.IsNullOrEmpty(word))
                        {
                            paragraphs[paragraphs.Count - 1].Add(new RichText(richText.richTextTag, word));
                        }
                    }
                }
            }

            foreach (List <RichText> paragraph in paragraphs)
            {
                //Add all the paragraphs
                VisualElement rootTemp = root;
                root = AddParagraphContainer(root);
                for (int i = 0; i < paragraph.Count; i++)
                {
                    RichText word = paragraph[i];
                    if (i < paragraph.Count - 1)
                    {
                        //If there are more words
                        RichText nextWord = paragraph[i + 1];
                        string   nextText = nextWord.associatedText;
                        if (Regex.IsMatch(nextText, "^[^a-zA-Z] ?"))
                        {
                            VisualElement inlineGroup = new VisualElement();
                            root.Add(inlineGroup);
                            inlineGroup.AddToClassList("inline-text-group");
                            AddRichTextInternal(word, inlineGroup);
                            AddRichTextInternal(nextWord, inlineGroup);
                            ++i;
                            continue;
                        }
                    }

                    AddRichTextInternal(word, root);

                    //Add all the words and style them.
                    void AddRichTextInternal(RichText richText, VisualElement rootToAddTo)
                    {
                        RichTextTag tag        = richText.richTextTag;
                        TextElement inlineText = null;

                        switch (tag.tag)
                        {
                        case RichTextTag.Tag.none:
                            inlineText = AddInlineText(richText.associatedText, rootToAddTo);
                            break;

                        case RichTextTag.Tag.button:
                            if (buttonRegistry == null)
                            {
                                Debug.LogWarning("There was no ButtonRegistry provided to AddRichText. Button tags will not function.");
                                inlineText = AddInlineButton(() => Debug.LogWarning("There was no ButtonRegistry provided to AddRichText. Button tags will not function."), richText.associatedText, rootToAddTo);
                                break;
                            }
                            if (!buttonRegistry.GetRegisteredButtonAction(tag.stringVariables, out Action action))
                            {
                                return;
                            }
                            inlineText = AddInlineButton(action, richText.associatedText, rootToAddTo);
                            break;

                        case RichTextTag.Tag.code:
                            //Scroll
                            ScrollView    codeScroll       = new ScrollView(ScrollViewMode.Horizontal);
                            VisualElement contentContainer = codeScroll.contentContainer;
                            codeScroll.contentViewport.style.flexDirection = FlexDirection.Column;
                            codeScroll.contentViewport.style.alignItems    = Align.Stretch;
                            codeScroll.AddToClassList("code-scroll");
                            root.Add(codeScroll);

                            contentContainer.ClearClassList();
                            contentContainer.AddToClassList("code-container");
                            VisualElement codeContainer = contentContainer;

                            CSharpHighlighter highlighter = new CSharpHighlighter
                            {
                                AddStyleDefinition = false
                            };
                            // To add code, we first use the CSharpHighlighter to construct rich text for us.
                            string highlit = highlighter.Highlight(richText.associatedText);
                            // After constructing new rich text we pass the text back recursively through this function with the new parent.
                            AddRichText(highlit, buttonRegistry, codeContainer, true);                                     // only parse spans because this is all the CSharpHighlighter parses.
                            //Finalise content container
                            foreach (VisualElement child in codeContainer.Children())
                            {
                                if (child.ClassListContains(paragraphContainerClass))
                                {
                                    child.AddToClassList("code");
                                    if (child.childCount == 1)
                                    {
                                        AddInlineText("", child);                                                //This seems to be required to get layout to function properly.
                                    }
                                }
                            }

                            //Begin Hack
                            FieldInfo m_inheritedStyle = typeof(VisualElement).GetField("inheritedStyle", BindingFlags.NonPublic | BindingFlags.Instance);
                            if (m_inheritedStyle == null)
                            {
                                m_inheritedStyle = typeof(VisualElement).GetField("m_InheritedStylesData", BindingFlags.NonPublic | BindingFlags.Instance);
                            }
                            Type      inheritedStylesData = Type.GetType("UnityEngine.UIElements.StyleSheets.InheritedStylesData,UnityEngine");
                            FieldInfo font     = inheritedStylesData.GetField("font", BindingFlags.Public | BindingFlags.Instance);
                            FieldInfo fontSize = inheritedStylesData.GetField("fontSize", BindingFlags.Public | BindingFlags.Instance);
                            Font      consola  = (Font)EditorGUIUtility.Load("consola");

                            contentContainer.Query <Label>().ForEach(l =>
                            {
                                l.AddToClassList("code");


                                //Hack to regenerate the font size as Rich Text tags are removed from the original calculation.
                                object value      = m_inheritedStyle.GetValue(l);
                                StyleFont fontVar = (StyleFont)font.GetValue(value);
                                fontVar.value     = consola;
                                font.SetValue(value, fontVar);
                                StyleLength fontSizeVar = 12;                                        // = (StyleLength) fontSize.GetValue(value); //This doesn't seem to work properly, hard coded for now.
                                fontSize.SetValue(value, fontSizeVar);
                                m_inheritedStyle.SetValue(l, value);
                                Vector2 measuredTextSize = l.MeasureTextSize(l.text.Replace('>', ' '), 0, VisualElement.MeasureMode.Undefined, 0, VisualElement.MeasureMode.Undefined);
                                l.style.width            = measuredTextSize.x;
                                l.style.height           = measuredTextSize.y;
                            });

                            //Button
                            Button codeCopyButtonButtonContainer = new Button(() =>
                            {
                                EditorGUIUtility.systemCopyBuffer = richText.associatedText;
                                Debug.Log("Copied Code to Clipboard");
                            });
                            codeCopyButtonButtonContainer.ClearClassList();
                            codeCopyButtonButtonContainer.AddToClassList("code-button");
                            codeCopyButtonButtonContainer.StretchToParentSize();
                            codeContainer.Add(codeCopyButtonButtonContainer);

                            break;

                        case RichTextTag.Tag.span:
                            Label spanLabel = new Label
                            {
                                text = richText.associatedText
                            };
                            spanLabel.AddToClassList(tag.stringVariables);
                            rootToAddTo.Add(spanLabel);
                            break;

                        case RichTextTag.Tag.image:
                            throw new NotImplementedException();

                        default:
                            throw new ArgumentOutOfRangeException();
                        }

                        if (inlineText != null)
                        {
                            inlineText.style.unityFontStyleAndWeight = tag.fontStyle;
                            if (tag.size > 0)
                            {
                                inlineText.style.fontSize = tag.size;
                            }
                            if (tag.color != Color.clear)
                            {
                                inlineText.style.color = tag.color;
                            }
                            results.Add(inlineText);
                        }
                    }
                }

                root = rootTemp;
            }

            return(results);

            /*void RichTextDebug(string richText) => Debug.Log(GetRichTextCapableText(richText));
             * string GetRichTextCapableText(string richText) => text.Replace("<", "<<b></b>");*/
        }