private async Task TestCodeActionAsync(string markup, string title, string newText, string abbreviation, params string[] relativePaths) { MarkupUtils.GetNamedSpans(markup, out var code, out var spans); // get main analysis and add mock modules var analysis = await GetAnalysisAsync(code); foreach (var relativePath in relativePaths) { await GetAnalysisAsync("", analysis.ExpressionEvaluator.Services, modulePath : TestData.GetTestSpecificPath(relativePath)); } // calculate actions var diagnosticSpan = spans["diagnostic"].First().ToSourceSpan(analysis.Ast); var diagnostics = GetDiagnostics(analysis, diagnosticSpan, MissingImportCodeActionProvider.Instance.FixableDiagnostics); var codeActions = await new QuickFixCodeActionSource(analysis.ExpressionEvaluator.Services).GetCodeActionsAsync(analysis, CodeActionSettings.Default, diagnostics, TestCancellationToken); // verify results var codeAction = codeActions.Single(c => c.title == title); codeAction.edit.changes.Should().HaveCount(1); var edits = codeAction.edit.changes[analysis.Document.Uri]; edits.Should().HaveCount(2); var invocationEdit = edits.Single(e => e.newText == abbreviation); invocationEdit.range.Should().Be(diagnosticSpan); var insertEdit = edits.Single(e => e.newText == newText); insertEdit.range.Should().Be(spans["insertionSpan"].First().ToSourceSpan(analysis.Ast)); }
public async Task Disabled() { var markup = @"from os import path [|socket|]()"; MarkupUtils.GetSpan(markup, out var code, out var span); var analysis = await GetAnalysisAsync(code); var diagnostics = GetDiagnostics(analysis, span.ToSourceSpan(analysis.Ast), MissingImportCodeActionProvider.Instance.FixableDiagnostics); diagnostics.Should().NotBeEmpty(); var codeActions = await new QuickFixCodeActionSource(analysis.ExpressionEvaluator.Services).GetCodeActionsAsync(analysis, CodeActionSettings.Default, diagnostics, TestCancellationToken); codeActions.Should().NotBeEmpty(); var emptyActions = await new QuickFixCodeActionSource(analysis.ExpressionEvaluator.Services).GetCodeActionsAsync( analysis, new CodeActionSettings(null, new Dictionary <string, object>() { { "addimports", false } }), diagnostics, TestCancellationToken); emptyActions.Should().BeEmpty(); }
private async Task <(IDocumentAnalysis analysis, CodeAction[] diagnostics, SourceSpan insertionSpan)> GetAnalysisAndCodeActionsAndSpanAsync( string markup, IEnumerable <string> codes, bool enableIndexManager = false) { MarkupUtils.GetNamedSpans(markup, out var code, out var spans); var analysis = await GetAnalysisAsync(code); if (enableIndexManager) { var serviceManager = (IServiceManager)analysis.ExpressionEvaluator.Services; var indexManager = new IndexManager( serviceManager.GetService <IFileSystem>(), analysis.Document.Interpreter.LanguageVersion, rootPath: null, Array.Empty <string>(), Array.Empty <string>(), serviceManager.GetService <IIdleTimeService>()); // make sure index is done await indexManager.IndexSnapshot(analysis.Document.Interpreter.ModuleResolution.CurrentPathResolver); serviceManager.AddService(indexManager); } var insertionSpan = spans["insertionSpan"].First().ToSourceSpan(analysis.Ast); var diagnostics = GetDiagnostics(analysis, spans["diagnostic"].First().ToSourceSpan(analysis.Ast), codes); var codeActions = await new QuickFixCodeActionSource(analysis.ExpressionEvaluator.Services).GetCodeActionsAsync(analysis, CodeActionSettings.Default, diagnostics, TestCancellationToken); return(analysis, codeActions.ToArray(), insertionSpan); }
public async Task SymbolOrdering3() { var markup = @"{|insertionSpan:|}{|diagnostic:pd|}"; MarkupUtils.GetNamedSpans(markup, out var code, out var spans); // get main analysis and add mock modules var analysis = await GetAnalysisAsync(code); await GetAnalysisAsync("", analysis.ExpressionEvaluator.Services, modulePath : TestData.GetTestSpecificPath("pandas.py")); await GetAnalysisAsync("", analysis.ExpressionEvaluator.Services, modulePath : TestData.GetTestSpecificPath("pd.py")); // calculate actions var diagnosticSpan = spans["diagnostic"].First().ToSourceSpan(analysis.Ast); var diagnostics = GetDiagnostics(analysis, diagnosticSpan, MissingImportCodeActionProvider.Instance.FixableDiagnostics); var codeActions = await new QuickFixCodeActionSource(analysis.ExpressionEvaluator.Services).GetCodeActionsAsync(analysis, CodeActionSettings.Default, diagnostics, TestCancellationToken); var list = codeActions.Select(c => c.title).ToList(); var zipList = Enumerable.Range(0, list.Count).Zip(list); var pandasIndex = zipList.First(t => t.Second == "import pandas as pd").First; var pdIndex = zipList.First(t => t.Second == "import pd").First; pandasIndex.Should().BeLessThan(pdIndex); }
public async Task NoConflict() { MarkupUtils.GetPosition(@"$$", out var code, out int position); var analysis = await GetAnalysisAsync(code); Test(analysis, position, "name", "name"); Test(analysis, "name", "name"); }
public async Task Conflict_TopLevel() { MarkupUtils.GetPosition(@"$$ name = 1", out var code, out int position); var analysis = await GetAnalysisAsync(code); Test(analysis, position, "name", "name1"); Test(analysis, "name", "name1"); }
/// <summary> /// Create "stack" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "stack"; #endif string attrValue; float amount; var align = OneAxisAlignment.Center; var padding = 0f; var stack = widget.gameObject.AddComponent <StackLayout> (); attrValue = node.GetAttribute(HashedAlign); if (!string.IsNullOrEmpty(attrValue)) { switch (attrValue) { case "start": align = OneAxisAlignment.Start; break; case "end": align = OneAxisAlignment.End; break; } } attrValue = node.GetAttribute(HashedPadding); if (!string.IsNullOrEmpty(attrValue)) { if (float.TryParse(attrValue, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out amount)) { padding = amount; } } attrValue = node.GetAttribute(HashedVertical); var isVertical = string.CompareOrdinal(attrValue, "true") == 0; attrValue = node.GetAttribute(HashedReverse); var isReverse = string.CompareOrdinal(attrValue, "true") == 0; stack.Padding = padding; stack.ChildAlignment = align; stack.IsVertical = isVertical; stack.IsReverse = isReverse; MarkupUtils.SetSize(widget, node); MarkupUtils.SetRotation(widget, node); MarkupUtils.SetOffset(widget, node); MarkupUtils.SetHidden(widget, node); return(widget); }
public async Task Conflict_Function2() { MarkupUtils.GetPosition(@"def Test(): name = 1 $$ pass", out var code, out int position); var analysis = await GetAnalysisAsync(code); Test(analysis, position, "name", "name1"); Test(analysis, "name", "name1"); }
/// <summary> /// Create "grid" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "grid"; #endif var grid = widget.gameObject.AddComponent <GridLayoutGroup> (); grid.childAlignment = TextAnchor.MiddleCenter; var flipX = false; var flipY = false; var cellSize = Vector2.zero; var attrValue = node.GetAttribute(HashedFlip); if (!string.IsNullOrEmpty(attrValue)) { var parts = MarkupUtils.SplitAttrValue(attrValue); flipX = parts.Length > 0 && string.CompareOrdinal(parts[0], "true") == 0; flipY = parts.Length > 1 && string.CompareOrdinal(parts[1], "true") == 0; } float amount; attrValue = node.GetAttribute(HashedCellSize); if (!string.IsNullOrEmpty(attrValue)) { var parts = MarkupUtils.SplitAttrValue(attrValue); if (parts.Length > 0 && !string.IsNullOrEmpty(parts[0])) { if (float.TryParse(parts[0], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out amount)) { cellSize.x = amount; } } if (parts.Length > 1 && !string.IsNullOrEmpty(parts[1])) { if (float.TryParse(parts[1], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out amount)) { cellSize.y = amount; } } } grid.cellSize = cellSize; grid.startCorner = (GridLayoutGroup.Corner)((flipX ? 1 : 0) | (flipY ? 2 : 0)); MarkupUtils.SetSize(widget, node); MarkupUtils.SetRotation(widget, node); MarkupUtils.SetOffset(widget, node); MarkupUtils.SetHidden(widget, node); return(widget); }
public async Task Missing() { MarkupUtils.GetSpan(@"[|missingModule|]", out var code, out var span); var analysis = await GetAnalysisAsync(code); var diagnostics = GetDiagnostics(analysis, span.ToSourceSpan(analysis.Ast), MissingImportCodeActionProvider.Instance.FixableDiagnostics); diagnostics.Should().NotBeEmpty(); var codeActions = await new QuickFixCodeActionSource(analysis.ExpressionEvaluator.Services).GetCodeActionsAsync(analysis, CodeActionSettings.Default, diagnostics, TestCancellationToken); codeActions.Should().BeEmpty(); }
/// <summary> /// Create "align" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "align"; #endif var rt = widget.GetComponent <RectTransform> (); var deltaSize = Vector2.zero; var anchorMin = Vector2.zero; var anchorMax = Vector2.one; var attrValue = node.GetAttribute(HashedSide); if (!string.IsNullOrEmpty(attrValue)) { var parts = MarkupUtils.SplitAttrValue(attrValue); for (var i = 0; i < parts.Length; i++) { switch (parts[i]) { case "left": anchorMax.x = 0f; deltaSize.x = 1f; break; case "right": anchorMin.x = 1f; deltaSize.x = 1f; break; case "top": anchorMin.y = 1f; deltaSize.y = 1f; break; case "bottom": anchorMax.y = 0f; deltaSize.y = 1f; break; } } } rt.anchorMin = anchorMin; rt.anchorMax = anchorMax; rt.sizeDelta = deltaSize; MarkupUtils.SetHidden(widget, node); return(widget); }
static Scrollbar CreateScrollbar(RectTransform widget, MarkupTheme theme, bool isHorizontal) { Image img; var width = theme.GetScrollbarWidth(); // background. var rt = MarkupUtils.CreateUiObject(null, widget); var sb = rt.gameObject.AddComponent <Scrollbar> (); img = rt.gameObject.AddComponent <Image> (); img.sprite = theme.GetScrollbarSprite(MarkupTheme.ScrollbarState.Background); img.color = theme.GetScrollbarColor(MarkupTheme.ScrollbarState.Background); img.type = Image.Type.Sliced; if (isHorizontal) { rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.right; rt.pivot = Vector2.zero; rt.sizeDelta = new Vector2(0f, width); } else { rt.anchorMin = Vector2.right; rt.anchorMax = Vector2.one; rt.pivot = Vector2.one; rt.sizeDelta = new Vector2(width, 0f); } // handle. rt = MarkupUtils.CreateUiObject(null, rt); img = rt.gameObject.AddComponent <Image> (); img.sprite = theme.GetScrollbarSprite(MarkupTheme.ScrollbarState.Handle); img.color = theme.GetScrollbarColor(MarkupTheme.ScrollbarState.Handle); img.type = Image.Type.Sliced; img.raycastTarget = false; rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; rt.offsetMin = Vector2.zero; rt.offsetMax = Vector2.zero; sb.direction = isHorizontal ? Scrollbar.Direction.LeftToRight : Scrollbar.Direction.BottomToTop; sb.handleRect = rt; sb.transition = Selectable.Transition.None; return(sb); }
/// <summary> /// Create "box" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "box"; #endif MarkupUtils.SetSize(widget, node); MarkupUtils.SetRotation(widget, node); MarkupUtils.SetOffset(widget, node); MarkupUtils.SetHidden(widget, node); if (MarkupUtils.ValidateInteractive(widget, node, container.DragTreshold)) { widget.gameObject.AddComponent <NonVisualWidget> (); } return(widget); }
/// <summary> /// Create "fixedTable" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "fixedTable"; #endif var table = widget.gameObject.AddComponent <FixedTableLayout> (); var itemsInRow = 1; var cellSize = Vector2.zero; var attrValue = node.GetAttribute(HashedItemsInRow); if (!string.IsNullOrEmpty(attrValue)) { int.TryParse(attrValue, out itemsInRow); } float amount; attrValue = node.GetAttribute(HashedCellSize); if (!string.IsNullOrEmpty(attrValue)) { var parts = MarkupUtils.SplitAttrValue(attrValue); if (parts.Length > 0 && !string.IsNullOrEmpty(parts[0])) { if (float.TryParse(parts[0], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out amount)) { cellSize.x = amount; } } if (parts.Length > 1 && !string.IsNullOrEmpty(parts[1])) { if (float.TryParse(parts[1], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out amount)) { cellSize.y = amount; } } } table.ItemsInRow = itemsInRow; table.CellSize = cellSize; MarkupUtils.SetSize(widget, node); MarkupUtils.SetRotation(widget, node); MarkupUtils.SetOffset(widget, node); MarkupUtils.SetHidden(widget, node); return(widget); }
// Methods :: Public public void Load(Album album) { cover_image.Song = (Song)album.Songs [0]; name_label.Text = album.Name; MarkupUtils.LabelSetMarkup(name_label, 0, StringUtils.GetByteLength(album.Name), true, true, false); year_label.Text = album.Year; // Insert tracks foreach (Song song in album.Songs) { InsertTrack(song); } }
/// <summary> /// Create "toggleGroup" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "toggleGroup"; #endif var checkGroup = widget.gameObject.AddComponent <ToggleGroup> (); var attrValue = node.GetAttribute(HashedEmptyCheck); if (string.CompareOrdinal(attrValue, "true") == 0) { checkGroup.allowSwitchOff = true; } MarkupUtils.SetSize(widget, node); MarkupUtils.SetRotation(widget, node); MarkupUtils.SetOffset(widget, node); MarkupUtils.SetHidden(widget, node); return(widget); }
public async Task MultipleConflicts() { MarkupUtils.GetPosition(@" name1 = 1 class name3: name2 = 1 def Test(): name = 1 def name4(): pass $$", out var code, out int position); var analysis = await GetAnalysisAsync(code); Test(analysis, position, "name", "name"); Test(analysis, "name", "name5"); }
public async Task CodeActionOrdering() { MarkupUtils.GetSpan(@"def TestMethod(): [|test|]", out var code, out var span); var analysis = await GetAnalysisAsync(code); var diagnostics = GetDiagnostics(analysis, span.ToSourceSpan(analysis.Ast), MissingImportCodeActionProvider.Instance.FixableDiagnostics); diagnostics.Should().NotBeEmpty(); var codeActions = await new QuickFixCodeActionSource(analysis.ExpressionEvaluator.Services).GetCodeActionsAsync(analysis, CodeActionSettings.Default, diagnostics, TestCancellationToken); var list = codeActions.Select(c => c.title).ToList(); var zipList = Enumerable.Range(0, list.Count).Zip(list); var locallyImportedPrefix = Resources.ImportLocally.Substring(0, Resources.ImportLocally.IndexOf("'")); var maxIndexOfTopAddImports = zipList.Where(t => !t.Second.StartsWith(locallyImportedPrefix)).Max(t => t.First); var minIndexOfLocalAddImports = zipList.Where(t => t.Second.StartsWith(locallyImportedPrefix)).Min(t => t.First); maxIndexOfTopAddImports.Should().BeLessThan(minIndexOfLocalAddImports); }
/// <summary> /// Create "ui" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "ui"; #endif var go = widget.gameObject; var canvas = go.AddComponent <Canvas> (); Camera uiCamera = null; if (Application.isPlaying) { canvas.renderMode = RenderMode.ScreenSpaceCamera; uiCamera = MarkupUtils.GetUiCamera(); canvas.worldCamera = uiCamera; } else { canvas.renderMode = RenderMode.ScreenSpaceOverlay; } canvas.planeDistance = 0f; canvas.pixelPerfect = false; var pixelSize = 1f; var dragTreshold = 5; var scaler = go.AddComponent <CanvasScaler> (); var attrValue = node.GetAttribute(HashedBase); if (attrValue != null) { var refWidth = 1024; var refHeight = 768; var refBalance = 1f; try { var parts = MarkupUtils.SplitAttrValue(attrValue); var w = int.Parse(parts[0]); var h = int.Parse(parts[1]); var b = Mathf.Clamp01(float.Parse(parts[2], NumberFormatInfo.InvariantInfo)); refWidth = w; refHeight = h; refBalance = b; } catch { } scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; scaler.referenceResolution = new Vector2(refWidth, refHeight); scaler.matchWidthOrHeight = refBalance; if (Application.isPlaying) { if (refBalance < 1f) { Debug.LogWarning("Only height-based balance supported"); } uiCamera.orthographicSize = refHeight * 0.5f; pixelSize = MathFast.Lerp(Screen.width / (float)refWidth, Screen.height / (float)refHeight, refBalance); } else { pixelSize = 1f; } } attrValue = node.GetAttribute(HashedDragTreshold); if (attrValue != null) { if (int.TryParse(attrValue, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out dragTreshold)) { dragTreshold = Mathf.Max(1, dragTreshold); } } attrValue = node.GetAttribute(MarkupUtils.HashedNav); var disableNav = string.CompareOrdinal(attrValue, "false") == 0; container.PixelSize = pixelSize; container.DragTreshold = dragTreshold * pixelSize; container.UseNavigation = !disableNav; go.AddComponent <GraphicRaycaster> (); if (Application.isPlaying) { var es = Object.FindObjectOfType <EventSystem> (); if ((object)es == null) { es = new GameObject("EventSystem").AddComponent <EventSystem> (); es.gameObject.AddComponent <StandaloneInputModule> (); } } return(widget); }
/// <summary> /// Create "input" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "input"; #endif var input = widget.gameObject.AddComponent <InputField> (); string attrValue; string font = null; var align = TextAnchor.MiddleLeft; var style = FontStyle.Normal; var size = 24; var isInteractive = false; var theme = MarkupUtils.GetTheme(node, container); var img = widget.gameObject.AddComponent <Image> (); img.type = Image.Type.Sliced; img.sprite = theme.GetInputSprite(); img.color = theme.GetInputColor(MarkupTheme.InputState.Background); var ph = MarkupUtils.CreateUiObject(null, widget); var phText = ph.gameObject.AddComponent <Text> (); phText.fontStyle = FontStyle.Italic; var txt = MarkupUtils.CreateUiObject(null, widget); var inText = txt.gameObject.AddComponent <Text> (); inText.supportRichText = false; attrValue = node.GetAttribute(HashedFontName); if (!string.IsNullOrEmpty(attrValue)) { font = attrValue; } attrValue = node.GetAttribute(HashedFontSize); if (!string.IsNullOrEmpty(attrValue)) { int.TryParse(attrValue, out size); } attrValue = node.GetAttribute(HashedFontStyle); if (!string.IsNullOrEmpty(attrValue)) { var parts = MarkupUtils.SplitAttrValue(attrValue); for (var i = 0; i < parts.Length; i++) { switch (parts[i]) { case "bold": style |= FontStyle.Bold; break; case "italic": style |= FontStyle.Italic; break; } } } attrValue = node.GetAttribute(HashedAlign); if (!string.IsNullOrEmpty(attrValue)) { var parts = MarkupUtils.SplitAttrValue(attrValue); var alignHor = 1; var alignVer = 3; for (var i = 0; i < parts.Length; i++) { switch (parts[i]) { case "left": alignHor = 0; break; case "right": alignHor = 2; break; case "top": alignVer = 0; break; case "bottom": alignVer = 6; break; } } align = (TextAnchor)(alignHor + alignVer); } attrValue = node.GetAttribute(HashedLocalize); if (!string.IsNullOrEmpty(attrValue)) { phText.gameObject.AddComponent <TextLocalization> ().SetToken(attrValue); } else { phText.text = node.Value; } var margin = theme.GetInputMargin(); var marginMin = new Vector2(margin, margin); var marginMax = -marginMin; ph.anchorMin = Vector2.zero; ph.anchorMax = Vector2.one; ph.offsetMin = marginMin; ph.offsetMax = marginMax; txt.anchorMin = Vector2.zero; txt.anchorMax = Vector2.one; txt.offsetMin = marginMin; txt.offsetMax = marginMax; phText.raycastTarget = false; inText.raycastTarget = false; phText.alignment = align; inText.alignment = align; phText.font = container.GetFont(font); inText.font = phText.font; phText.color = theme.GetInputColor(MarkupTheme.InputState.Placeholder); if (!MarkupUtils.SetColor(inText, node)) { inText.color = Color.black; } phText.fontStyle = theme.GetInputPlaceholderStyle(); inText.fontStyle = style; phText.fontSize = size; inText.fontSize = size; input.targetGraphic = img; input.transition = Selectable.Transition.None; input.placeholder = phText; input.textComponent = inText; input.selectionColor = theme.GetInputColor(MarkupTheme.InputState.Selection); MarkupUtils.SetSize(widget, node); MarkupUtils.SetRotation(widget, node); MarkupUtils.SetOffset(widget, node); MarkupUtils.SetHidden(widget, node); MarkupUtils.SetNav(input, node, container.UseNavigation); attrValue = node.GetAttribute(HashedOnChange); if (!string.IsNullOrEmpty(attrValue)) { widget.gameObject.AddComponent <UiInputAction> ().SetGroup(attrValue); isInteractive = true; } input.interactable = isInteractive; return(widget); }
/// <summary> /// Create "scrollView" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "scrollView"; #endif float amount; string attrValue; Scrollbar horScroll = null; Scrollbar verScroll = null; var anchorMin = Vector2.zero; var anchorMax = Vector2.one; var offsetMin = Vector3.zero; var offsetMax = Vector3.zero; var needHorScroll = true; var needVerScroll = true; var theme = MarkupUtils.GetTheme(node, container); var scrollView = widget.gameObject.AddComponent <ScrollRect> (); // viewport. var viewport = MarkupUtils.CreateUiObject(ViewportName, widget); viewport.gameObject.AddComponent <RectMask2D> (); viewport.gameObject.AddComponent <NonVisualWidget> ().raycastTarget = false; viewport.anchorMin = Vector2.zero; viewport.anchorMax = Vector2.one; viewport.sizeDelta = Vector2.zero; viewport.pivot = Vector2.up; // content. var content = MarkupUtils.CreateUiObject(ContentName, viewport); attrValue = node.GetAttribute(HashedContentSize); if (!string.IsNullOrEmpty(attrValue)) { var parts = MarkupUtils.SplitAttrValue(attrValue); if (parts.Length > 0 && !string.IsNullOrEmpty(parts[0])) { if (float.TryParse(parts[0], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out amount)) { amount *= 0.5f; offsetMin.x = -amount; offsetMax.x = amount; anchorMin.x = 0.5f; anchorMax.x = 0.5f; } } if (parts.Length > 1 && !string.IsNullOrEmpty(parts[1])) { if (float.TryParse(parts[1], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out amount)) { amount *= 0.5f; offsetMin.y = -amount; offsetMax.y = amount; anchorMin.y = 0.5f; anchorMax.y = 0.5f; } } } content.anchorMin = anchorMin; content.anchorMax = anchorMax; content.offsetMin = offsetMin; content.offsetMax = offsetMax; attrValue = node.GetAttribute(HashedClamp); if (string.CompareOrdinal(attrValue, "true") == 0) { scrollView.movementType = ScrollRect.MovementType.Clamped; } attrValue = node.GetAttribute(HashedDrag); if (!string.IsNullOrEmpty(attrValue)) { var parts = MarkupUtils.SplitAttrValue(attrValue); if (parts.Length > 0 && string.CompareOrdinal(parts[0], "false") == 0) { scrollView.horizontal = false; } if (parts.Length > 1 && string.CompareOrdinal(parts[1], "false") == 0) { scrollView.vertical = false; } } attrValue = node.GetAttribute(HashedBar); if (!string.IsNullOrEmpty(attrValue)) { var parts = MarkupUtils.SplitAttrValue(attrValue); if (parts.Length > 0 && string.CompareOrdinal(parts[0], "false") == 0) { needHorScroll = false; } if (parts.Length > 1 && string.CompareOrdinal(parts[1], "false") == 0) { needVerScroll = false; } } if (needHorScroll) { horScroll = CreateScrollbar(widget, theme, true); MarkupUtils.SetNav(horScroll, node, container.UseNavigation); } if (needVerScroll) { verScroll = CreateScrollbar(widget, theme, false); MarkupUtils.SetNav(verScroll, node, container.UseNavigation); } attrValue = node.GetAttribute(HashedOnChange); if (!string.IsNullOrEmpty(attrValue)) { widget.gameObject.AddComponent <NonVisualWidget> (); widget.gameObject.AddComponent <UiScrollViewAction> ().SetGroup(attrValue); } scrollView.content = content; scrollView.viewport = viewport; scrollView.horizontalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport; scrollView.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport; scrollView.horizontalScrollbar = horScroll; scrollView.verticalScrollbar = verScroll; scrollView.decelerationRate = 0.01f; MarkupUtils.SetSize(widget, node); MarkupUtils.SetRotation(widget, node); MarkupUtils.SetOffset(widget, node); MarkupUtils.SetHidden(widget, node); scrollView.normalizedPosition = Vector2.up; return(content); }
/// <summary> /// Create "toggle" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "toggle"; #endif var tr = widget.transform; Image img; RectTransform rt; Vector2 size; string attrValue; var toggle = widget.gameObject.AddComponent <Toggle> (); var theme = MarkupUtils.GetTheme(node, container); var isInteractive = false; // background. rt = MarkupUtils.CreateUiObject(BackgroundImageName, tr); img = rt.gameObject.AddComponent <Image> (); img.sprite = theme.GetToggleSprite(MarkupTheme.ToggleState.Background); img.type = Image.Type.Sliced; img.raycastTarget = false; size = theme.GetToggleSize(MarkupTheme.ToggleState.Background); rt.anchorMin = new Vector2(0f, 0.5f); rt.anchorMax = new Vector2(0f, 0.5f); rt.offsetMin = new Vector2(0f, -size.y * 0.5f); rt.offsetMax = new Vector2(size.x, size.y * 0.5f); toggle.targetGraphic = img; // foreground. rt = MarkupUtils.CreateUiObject(ForegroundImageName, rt); img = rt.gameObject.AddComponent <Image> (); rt.anchorMin = new Vector2(0.5f, 0.5f); rt.anchorMax = new Vector2(0.5f, 0.5f); rt.sizeDelta = theme.GetToggleSize(MarkupTheme.ToggleState.Foreground); img.sprite = theme.GetToggleSprite(MarkupTheme.ToggleState.Foreground); img.type = Image.Type.Sliced; img.raycastTarget = false; toggle.graphic = img; // content. rt = MarkupUtils.CreateUiObject(ContentName, tr); rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; rt.offsetMin = Vector2.right * size.x; rt.offsetMax = Vector2.zero; attrValue = node.GetAttribute(HashedGroup); if (!string.IsNullOrEmpty(attrValue)) { var groupGo = container.GetNamedNode(attrValue); if ((object)groupGo != null) { toggle.group = groupGo.GetComponent <ToggleGroup> (); } } attrValue = node.GetAttribute(HashedCheck); if (string.CompareOrdinal(attrValue, "true") == 0) { toggle.isOn = true; } attrValue = node.GetAttribute(HashedOnChange); if (!string.IsNullOrEmpty(attrValue)) { widget.gameObject.AddComponent <NonVisualWidget> (); widget.gameObject.AddComponent <UiToggleAction> ().SetGroup(attrValue); isInteractive = true; } toggle.transition = Selectable.Transition.None; toggle.interactable = isInteractive; MarkupUtils.SetSize(widget, node); MarkupUtils.SetRotation(widget, node); MarkupUtils.SetOffset(widget, node); MarkupUtils.SetHidden(widget, node); MarkupUtils.SetNav(toggle, node, container.UseNavigation); return(rt); }
/// <summary> /// Create "text" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "text"; #endif var txt = widget.gameObject.AddComponent <Text> (); string attrValue; string font = null; var align = TextAnchor.MiddleCenter; var style = FontStyle.Normal; var size = 24; attrValue = node.GetAttribute(HashedFontName); if (!string.IsNullOrEmpty(attrValue)) { font = attrValue; } attrValue = node.GetAttribute(HashedFontSize); if (!string.IsNullOrEmpty(attrValue)) { int.TryParse(attrValue, out size); } attrValue = node.GetAttribute(HashedFontStyle); if (!string.IsNullOrEmpty(attrValue)) { var parts = MarkupUtils.SplitAttrValue(attrValue); for (var i = 0; i < parts.Length; i++) { switch (parts[i]) { case "bold": style |= FontStyle.Bold; break; case "italic": style |= FontStyle.Italic; break; } } } attrValue = node.GetAttribute(HashedAlign); if (!string.IsNullOrEmpty(attrValue)) { var parts = MarkupUtils.SplitAttrValue(attrValue); var alignHor = 1; var alignVer = 3; for (var i = 0; i < parts.Length; i++) { switch (parts[i]) { case "left": alignHor = 0; break; case "right": alignHor = 2; break; case "top": alignVer = 0; break; case "bottom": alignVer = 6; break; } } align = (TextAnchor)(alignHor + alignVer); } attrValue = node.GetAttribute(HashedLocalize); if (!string.IsNullOrEmpty(attrValue)) { widget.gameObject.AddComponent <TextLocalization> ().SetToken(attrValue); } else { txt.text = node.Value; } txt.alignment = align; txt.font = container.GetFont(font); txt.fontStyle = style; txt.fontSize = size; if (!MarkupUtils.SetColor(txt, node)) { txt.color = Color.black; } MarkupUtils.SetSize(widget, node); MarkupUtils.SetRotation(widget, node); MarkupUtils.SetOffset(widget, node); MarkupUtils.SetHidden(widget, node); txt.raycastTarget = MarkupUtils.ValidateInteractive(widget, node, container.DragTreshold); return(widget); }
/// <summary> /// Create "image" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "image"; #endif Image img = null; RawImage tex = null; string attrValue; var useImg = true; var ignoreSize = false; var fillCenter = true; attrValue = node.GetAttribute(HashedRaw); if (string.CompareOrdinal(attrValue, "true") == 0) { useImg = false; tex = widget.gameObject.AddComponent <RawImage> (); } else { img = widget.gameObject.AddComponent <Image> (); img.type = Image.Type.Sliced; } attrValue = node.GetAttribute(HashedPath); if (!string.IsNullOrEmpty(attrValue)) { if (useImg) { // Image. var parts = MarkupUtils.SplitAttrValue(attrValue); if (parts.Length == 2) { var atlas = container.GetAtlas(parts[0]); if ((object)atlas != null) { img.sprite = atlas.Get(parts[1]); } } } else { // RawImage. tex.texture = Resources.Load <Texture2D> (attrValue); } } if (useImg) { attrValue = node.GetAttribute(HashedNativeSize); ignoreSize = (object)img.sprite != null && string.CompareOrdinal(attrValue, "true") == 0; } if (useImg && ignoreSize) { img.SetNativeSize(); } else { MarkupUtils.SetSize(widget, node); } attrValue = node.GetAttribute(HashedMask); if (string.CompareOrdinal(attrValue, "true") == 0) { widget.gameObject.AddComponent <Mask> (); } if (useImg) { attrValue = node.GetAttribute(HashedFillCenter); if (string.CompareOrdinal(attrValue, "false") == 0) { fillCenter = false; } img.fillCenter = fillCenter; } if (useImg && !MarkupUtils.SetColor(img, node)) { img.color = Color.white; } MarkupUtils.SetRotation(widget, node); MarkupUtils.SetOffset(widget, node); MarkupUtils.SetHidden(widget, node); var isInteractive = MarkupUtils.ValidateInteractive(widget, node, container.DragTreshold); if (useImg) { img.raycastTarget = isInteractive; } else { tex.raycastTarget = isInteractive; } return(widget); }
/// <summary> /// Create "ui" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "ui"; #endif var go = widget.gameObject; var canvas = go.AddComponent <Canvas> (); canvas.renderMode = RenderMode.ScreenSpaceOverlay; canvas.pixelPerfect = false; var pixelSize = 1f; var dragTreshold = 5; var scaler = go.AddComponent <CanvasScaler> (); var attrValue = node.GetAttribute(HashedBase); if (attrValue != null) { var refWidth = 1024; var refHeight = 768; var refBalance = 1f; try { var parts = MarkupUtils.SplitAttrValue(attrValue); var w = int.Parse(parts[0]); var h = int.Parse(parts[1]); var b = Mathf.Clamp01(float.Parse(parts[2], NumberFormatInfo.InvariantInfo)); refWidth = w; refHeight = h; refBalance = b; } catch { } scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; scaler.referenceResolution = new Vector2(refWidth, refHeight); scaler.matchWidthOrHeight = refBalance; if (Application.isPlaying) { pixelSize = Mathf.Lerp(Screen.width / (float)refWidth, Screen.height / (float)refHeight, refBalance); } else { pixelSize = 1f; } } attrValue = node.GetAttribute(HashedDragTreshold); if (attrValue != null) { if (int.TryParse(attrValue, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out dragTreshold)) { dragTreshold = Mathf.Max(1, dragTreshold); } } container.PixelSize = pixelSize; container.DragTreshold = dragTreshold * pixelSize; go.AddComponent <GraphicRaycaster> (); if (Application.isPlaying) { var es = Object.FindObjectOfType <EventSystem> (); if ((object)es == null) { es = new GameObject("EventSystem").AddComponent <EventSystem> (); es.gameObject.AddComponent <StandaloneInputModule> (); } } return(widget); }
/// <summary> /// Create "button" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "button"; #endif var btn = widget.gameObject.AddComponent <Button> (); var img = widget.gameObject.AddComponent <Image> (); string attrValue; var transition = Selectable.Transition.ColorTint; attrValue = node.GetAttribute(HashedBlend); switch (attrValue) { case "sprites": transition = Selectable.Transition.SpriteSwap; break; case "none": transition = Selectable.Transition.None; break; } var theme = MarkupUtils.GetTheme(node, container); switch (transition) { case Selectable.Transition.ColorTint: var colors = btn.colors; colors.normalColor = theme.GetButtonColor(MarkupTheme.ButtonState.Normal); colors.pressedColor = theme.GetButtonColor(MarkupTheme.ButtonState.Pressed); colors.highlightedColor = theme.GetButtonColor(MarkupTheme.ButtonState.Highlighted); colors.disabledColor = theme.GetButtonColor(MarkupTheme.ButtonState.Disabled); btn.colors = colors; break; case Selectable.Transition.SpriteSwap: var sprites = btn.spriteState; sprites.pressedSprite = theme.GetButtonSprite(MarkupTheme.ButtonState.Pressed); sprites.highlightedSprite = theme.GetButtonSprite(MarkupTheme.ButtonState.Highlighted); sprites.disabledSprite = theme.GetButtonSprite(MarkupTheme.ButtonState.Disabled); btn.spriteState = sprites; break; } img.sprite = theme.GetButtonSprite(MarkupTheme.ButtonState.Normal); img.type = Image.Type.Sliced; btn.targetGraphic = img; btn.transition = transition; MarkupUtils.SetSize(widget, node); MarkupUtils.SetRotation(widget, node); MarkupUtils.SetOffset(widget, node); MarkupUtils.SetHidden(widget, node); MarkupUtils.SetNav(btn, node, container.UseNavigation); attrValue = node.GetAttribute(HashedDisabled); var disabled = string.CompareOrdinal(attrValue, "true") == 0; btn.interactable = !disabled && MarkupUtils.ValidateInteractive(widget, node, container.DragTreshold); return(widget); }
/// <summary> /// Create "slider" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "slider"; #endif var slider = widget.gameObject.AddComponent <Slider> (); var theme = MarkupUtils.GetTheme(node, container); Image img; RectTransform rt; var direction = Slider.Direction.LeftToRight; var minValue = 0f; var maxValue = 1f; var useInts = false; var dataValue = 0f; var isInteractive = false; // background. rt = MarkupUtils.CreateUiObject(BackgroundImageName, widget); img = rt.gameObject.AddComponent <Image> (); img.sprite = theme.GetSliderSprite(MarkupTheme.SliderState.Background); img.color = theme.GetSliderColor(MarkupTheme.SliderState.Background); img.type = Image.Type.Sliced; rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; rt.sizeDelta = Vector2.zero; // foreground. rt = MarkupUtils.CreateUiObject(ForegroundImageName, widget); img = rt.gameObject.AddComponent <Image> (); img.sprite = theme.GetSliderSprite(MarkupTheme.SliderState.Foreground); img.color = theme.GetSliderColor(MarkupTheme.SliderState.Foreground); img.type = Image.Type.Sliced; img.raycastTarget = false; rt.sizeDelta = Vector2.zero; slider.fillRect = rt; string attrValue; attrValue = node.GetAttribute(HashedHandle); var useHandle = string.CompareOrdinal(attrValue, "true") == 0; if (useHandle) { var handle = MarkupUtils.CreateUiObject(null, widget); slider.handleRect = handle; rt = MarkupUtils.CreateUiObject(HandleImageName, handle); img = rt.gameObject.AddComponent <Image> (); img.raycastTarget = false; img.sprite = theme.GetSliderSprite(MarkupTheme.SliderState.Handle); img.color = theme.GetSliderColor(MarkupTheme.SliderState.Handle); img.type = Image.Type.Sliced; img.SetNativeSize(); handle.sizeDelta = img.rectTransform.sizeDelta; } attrValue = node.GetAttribute(HashedRtl); if (string.CompareOrdinal(attrValue, "true") == 0) { direction = Slider.Direction.RightToLeft; } float amount; attrValue = node.GetAttribute(HashedRange); if (!string.IsNullOrEmpty(attrValue)) { var parts = MarkupUtils.SplitAttrValue(attrValue); if (parts.Length > 0 && !string.IsNullOrEmpty(parts[0])) { if (float.TryParse(parts[0], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out amount)) { minValue = amount; } } if (parts.Length > 1 && !string.IsNullOrEmpty(parts[1])) { if (float.TryParse(parts[1], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out amount)) { maxValue = amount; } } if (parts.Length > 2 && string.CompareOrdinal(parts[2], "true") == 0) { useInts = true; } } attrValue = node.GetAttribute(HashedValue); if (!string.IsNullOrEmpty(attrValue)) { if (float.TryParse(attrValue, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out amount)) { dataValue = amount; } } attrValue = node.GetAttribute(HashedOnChange); if (!string.IsNullOrEmpty(attrValue)) { widget.gameObject.AddComponent <UiSliderAction> ().SetGroup(attrValue); isInteractive = true; } slider.minValue = minValue; slider.maxValue = maxValue; slider.wholeNumbers = useInts; slider.value = dataValue; slider.direction = direction; slider.transition = Selectable.Transition.None; MarkupUtils.SetSize(widget, node); MarkupUtils.SetRotation(widget, node); MarkupUtils.SetOffset(widget, node); MarkupUtils.SetHidden(widget, node); MarkupUtils.SetNav(slider, node, container.UseNavigation); slider.interactable = useHandle && isInteractive; return(widget); }