private void ResolveAddRemoveTextNodes() { if (RemoveTextNode.Count > 0) { foreach (var inst in RemoveTextNode) { inst.ParentNode.Children.Remove(inst.Node); } RemoveTextNode.Clear(); plugin.SaveConfiguration(); } if (AddTextNode.Count > 0) { foreach (var inst in AddTextNode) { if (inst.Index < 0) { inst.ParentNode.Children.Add(inst.Node); } else { inst.ParentNode.Children.Insert(inst.Index, inst.Node); } } AddTextNode.Clear(); plugin.SaveConfiguration(); } }
/// <summary> /// Walks a generated AST (Abstract Syntax Tree) and creates the elements of this UIScreen. /// </summary> /// <param name="State">A ParserState instance.</param> /// <param name="node">The root node of the AST.</param> private void WalkTree(UIParser.ParserState State, AstNode node, ref ParseResult Result) { NodeType NType = (NodeType)Enum.Parse(typeof(NodeType), node.ToString(), true); switch (NType) { case NodeType.DefineImage: //Defines an image and loads a texture for it. DefineImageNode ImgNode = (DefineImageNode)UINode.GetNode(node); UIImage Img = new UIImage(ImgNode, m_Screen); Result.Elements.Add(ImgNode.Name, Img); break; case NodeType.DefineString: //Defines a string with a name. DefineStringNode StrNode = (DefineStringNode)UINode.GetNode(node); Result.Strings.Add(StrNode.Name, StringManager.StrTable(State.CurrentStringTable)[StrNode.StrIndex]); break; case NodeType.AddButton: //Defines a button. AddButtonNode ButtonNode = (AddButtonNode)UINode.GetNode(node); UIButton Btn = new UIButton(ButtonNode, Result, m_Screen); Result.Elements.Add(ButtonNode.Name, Btn); break; case NodeType.AddText: AddTextNode TextNode = (AddTextNode)UINode.GetNode(node); UILabel Lbl = new UILabel(TextNode, Result, m_Screen); Result.Elements.Add(TextNode.Name, Lbl); break; case NodeType.AddTextEdit: AddTextEditNode TextEditNode = (AddTextEditNode)UINode.GetNode(node); UITextEdit2 Txt = new UITextEdit2(TextEditNode, State, m_Screen); Result.Elements.Add(TextEditNode.Name, Txt); break; case NodeType.AddSlider: AddSliderNode SliderNode = (AddSliderNode)UINode.GetNode(node); UISlider Slider = new UISlider(SliderNode, State, m_Screen); Result.Elements.Add(SliderNode.Name, Slider); break; case NodeType.SetSharedProperties: //Assigns a bunch of shared properties to declarations following the statement. State.InSharedPropertiesGroup = true; SetSharedPropsNode SharedPropsNode = (SetSharedPropsNode)UINode.GetNode(node); if (SharedPropsNode.StringTable != null) { State.CurrentStringTable = (int)SharedPropsNode.StringTable; } if (SharedPropsNode.ControlPosition != null) { State.Position[0] = SharedPropsNode.ControlPosition.Numbers[0]; State.Position[1] = SharedPropsNode.ControlPosition.Numbers[1]; break; } if (SharedPropsNode.Color != null) { State.Color = new Color(); State.Color.R = (byte)SharedPropsNode.Color.Numbers[0]; State.Color.G = (byte)SharedPropsNode.Color.Numbers[1]; State.Color.B = (byte)SharedPropsNode.Color.Numbers[2]; } if (SharedPropsNode.TextColor != null) { State.TextColor = new Color(); State.TextColor.R = (byte)SharedPropsNode.TextColor.Numbers[0]; State.TextColor.G = (byte)SharedPropsNode.TextColor.Numbers[1]; State.TextColor.B = (byte)SharedPropsNode.TextColor.Numbers[2]; } if (SharedPropsNode.TextColorSelected != null) { State.TextColorSelected = new Color(); State.TextColorSelected.R = (byte)SharedPropsNode.TextColorSelected.Numbers[0]; State.TextColorSelected.G = (byte)SharedPropsNode.TextColorSelected.Numbers[1]; State.TextColorSelected.B = (byte)SharedPropsNode.TextColorSelected.Numbers[2]; } if (SharedPropsNode.TextColorHighlighted != null) { State.TextColorHighlighted = new Color(); State.TextColorHighlighted.R = (byte)SharedPropsNode.TextColorHighlighted.Numbers[0]; State.TextColorHighlighted.G = (byte)SharedPropsNode.TextColorHighlighted.Numbers[1]; State.TextColorHighlighted.B = (byte)SharedPropsNode.TextColorHighlighted.Numbers[2]; } if (SharedPropsNode.TextColorDisabled != null) { State.TextColorDisabled = new Color(); State.TextColorDisabled.R = (byte)SharedPropsNode.TextColorDisabled.Numbers[0]; State.TextColorDisabled.G = (byte)SharedPropsNode.TextColorDisabled.Numbers[1]; State.TextColorDisabled.B = (byte)SharedPropsNode.TextColorDisabled.Numbers[2]; } if (SharedPropsNode.BackColor != null) { State.BackColor = new Color(); State.BackColor.R = (byte)SharedPropsNode.BackColor.Numbers[0]; State.BackColor.G = (byte)SharedPropsNode.BackColor.Numbers[1]; State.BackColor.B = (byte)SharedPropsNode.BackColor.Numbers[2]; } if (SharedPropsNode.CursorColor != null) { State.CursorColor = new Color(); State.CursorColor.R = (byte)SharedPropsNode.CursorColor.Numbers[0]; State.CursorColor.G = (byte)SharedPropsNode.CursorColor.Numbers[1]; State.CursorColor.B = (byte)SharedPropsNode.CursorColor.Numbers[2]; } if (SharedPropsNode.TextButton) { State.TextButton = true; } if (SharedPropsNode.Opaque != null) { State.IsOpaque = (SharedPropsNode.Opaque == 1) ? true : false; } if (SharedPropsNode.Transparent != null) { State.IsTransparent = (SharedPropsNode.Transparent == 1) ? true : false; } if (SharedPropsNode.Alignment != null) { State.Alignment = (int)SharedPropsNode.Alignment; } if (SharedPropsNode.Image != "") { State.Image = SharedPropsNode.Image; } if (SharedPropsNode.Tooltip != "") { State.Tooltip = SharedPropsNode.Tooltip; } if (SharedPropsNode.Text != "") { State.Caption = SharedPropsNode.Text; } if (SharedPropsNode.Size != null) { State.Size = new Vector2(SharedPropsNode.Size.Numbers[0], SharedPropsNode.Size.Numbers[1]); } if (SharedPropsNode.Orientation != null) { State.Orientation = (int)SharedPropsNode.Orientation; } if (SharedPropsNode.Font != null) { State.Font = (int)SharedPropsNode.Font; } if (SharedPropsNode.Opaque != null) { State.Opaque = (int)SharedPropsNode.Opaque; } break; case NodeType.SetControlProperties: //Sets a bunch of properties to a specified control. SetControlPropsNode ControlPropsNode = (SetControlPropsNode)UINode.GetNode(node); UIControl Ctrl = new UIControl(ControlPropsNode, m_Screen, State); Result.Controls.Add(ControlPropsNode.Control, Ctrl); if (State.InSharedPropertiesGroup) { UIElement Test = new UIElement(m_Screen, null); //Script implicitly created an object... :\ if (!Result.Elements.TryGetValue(ControlPropsNode.Control, out Test)) { Result.Elements.Add(ControlPropsNode.Control, new UIElement(m_Screen, null)); if (Ctrl.Image != null) { Result.Elements[ControlPropsNode.Control].Image = new UIImage(Ctrl.Image); } Result.Elements[ControlPropsNode.Control].Position = Ctrl.Position; } } break; case NodeType.End: State.InSharedPropertiesGroup = false; State.Image = ""; //Reset State.TextButton = false; //Reset State.Color = new Color(); State.Caption = ""; State.Size = new Vector2(0, 0); State.Alignment = 0; State.Font = 0; //TODO: Reset more? break; } foreach (AstNode child in node.ChildNodes) { WalkTree(State, child, ref Result); } }
private void TextNodeDragDrop(ITextNode node) { if (node != plugin.Configuration.RootFolder && ImGui.BeginDragDropSource()) { DraggedNode = node; ImGui.Text(node.Name); ImGui.SetDragDropPayload("TextNodePayload", IntPtr.Zero, 0); ImGui.EndDragDropSource(); } if (ImGui.BeginDragDropTarget()) { var payload = ImGui.AcceptDragDropPayload("TextNodePayload"); bool nullPtr; unsafe { nullPtr = payload.NativePtr == null; } var targetNode = node; if (!nullPtr && payload.IsDelivery() && DraggedNode != null) { if (plugin.Configuration.TryFindParent(DraggedNode, out var draggedNodeParent)) { if (targetNode is TextFolderNode targetFolderNode) { AddTextNode.Add(new AddTextNodeOperation { Node = DraggedNode, ParentNode = targetFolderNode, Index = -1 }); RemoveTextNode.Add(new RemoveTextNodeOperation { Node = DraggedNode, ParentNode = draggedNodeParent }); } else { if (plugin.Configuration.TryFindParent(targetNode, out var targetNodeParent)) { var targetNodeIndex = targetNodeParent.Children.IndexOf(targetNode); if (targetNodeParent == draggedNodeParent) { var draggedNodeIndex = targetNodeParent.Children.IndexOf(DraggedNode); if (draggedNodeIndex < targetNodeIndex) { targetNodeIndex -= 1; } } AddTextNode.Add(new AddTextNodeOperation { Node = DraggedNode, ParentNode = targetNodeParent, Index = targetNodeIndex }); RemoveTextNode.Add(new RemoveTextNodeOperation { Node = DraggedNode, ParentNode = draggedNodeParent }); } else { throw new Exception($"Could not find parent of node \"{targetNode.Name}\""); } } } else { throw new Exception($"Could not find parent of node \"{DraggedNode.Name}\""); } DraggedNode = null; } ImGui.EndDragDropTarget(); } }
private void TextNodePopup(ITextNode node) { var style = ImGui.GetStyle(); var newItemSpacing = new Vector2(style.ItemSpacing.X / 2, style.ItemSpacing.Y); if (ImGui.BeginPopup($"{node.GetHashCode()}-popup")) { if (node is TextEntryNode entryNode) { ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, newItemSpacing); var enabled = entryNode.Enabled; if (ImGui.Checkbox("Enabled", ref enabled)) { entryNode.Enabled = enabled; plugin.SaveConfiguration(); } ImGui.SameLine(ImGui.GetContentRegionMax().X - ImGuiEx.GetIconButtonWidth(FontAwesomeIcon.TrashAlt)); if (ImGuiEx.IconButton(FontAwesomeIcon.TrashAlt, "Delete")) { if (plugin.Configuration.TryFindParent(node, out var parentNode)) { RemoveTextNode.Add(new RemoveTextNodeOperation { Node = node, ParentNode = parentNode }); } } var matchText = entryNode.Text; if (ImGui.InputText($"##{node.Name}-matchText", ref matchText, 100, ImGuiInputTextFlags.AutoSelectAll | ImGuiInputTextFlags.EnterReturnsTrue)) { entryNode.Text = matchText; plugin.SaveConfiguration(); } var zoneRestricted = entryNode.ZoneRestricted; if (ImGui.Checkbox("Zone Restricted", ref zoneRestricted)) { entryNode.ZoneRestricted = zoneRestricted; plugin.SaveConfiguration(); } var searchWidth = ImGuiEx.GetIconButtonWidth(FontAwesomeIcon.Search); var searchPlusWidth = ImGuiEx.GetIconButtonWidth(FontAwesomeIcon.SearchPlus); ImGui.SameLine(ImGui.GetContentRegionMax().X - searchWidth); if (ImGuiEx.IconButton(FontAwesomeIcon.Search, "Zone List")) { IsImguiZoneListOpen = true; } ImGui.SameLine(ImGui.GetContentRegionMax().X - searchWidth - searchPlusWidth - newItemSpacing.X); if (ImGuiEx.IconButton(FontAwesomeIcon.SearchPlus, "Fill with current zone")) { var currentID = plugin.Interface.ClientState.TerritoryType; if (plugin.TerritoryNames.TryGetValue(currentID, out var zoneName)) { entryNode.ZoneText = zoneName; } else { entryNode.ZoneText = "Could not find name"; } } ImGui.PopStyleVar(); // ItemSpacing var zoneText = entryNode.ZoneText; if (ImGui.InputText($"##{node.Name}-zoneText", ref zoneText, 100, ImGuiInputTextFlags.AutoSelectAll | ImGuiInputTextFlags.EnterReturnsTrue)) { entryNode.ZoneText = zoneText; plugin.SaveConfiguration(); } } if (node is TextFolderNode folderNode) { ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, newItemSpacing); if (ImGuiEx.IconButton(FontAwesomeIcon.Plus, "Add entry")) { var newNode = new TextEntryNode { Enabled = false, Text = "Your text goes here" }; AddTextNode.Add(new AddTextNodeOperation { Node = newNode, ParentNode = folderNode, Index = -1 }); } ImGui.SameLine(); if (ImGuiEx.IconButton(FontAwesomeIcon.SearchPlus, "Add last seen as new entry")) { var newNode = new TextEntryNode() { Enabled = true, Text = plugin.LastSeenDialogText }; AddTextNode.Add(new AddTextNodeOperation { Node = newNode, ParentNode = folderNode, Index = -1 }); } ImGui.SameLine(); if (ImGuiEx.IconButton(FontAwesomeIcon.FolderPlus, "Add folder")) { var newNode = new TextFolderNode { Name = "Untitled folder" }; AddTextNode.Add(new AddTextNodeOperation { Node = newNode, ParentNode = folderNode, Index = -1 }); } var trashWidth = ImGuiEx.GetIconButtonWidth(FontAwesomeIcon.TrashAlt); ImGui.SameLine(ImGui.GetContentRegionMax().X - trashWidth); if (ImGuiEx.IconButton(FontAwesomeIcon.TrashAlt, "Delete")) { if (plugin.Configuration.TryFindParent(node, out var parentNode)) { RemoveTextNode.Add(new RemoveTextNodeOperation { Node = node, ParentNode = parentNode }); } } ImGui.PopStyleVar(); // ItemSpacing var folderName = folderNode.Name; if (ImGui.InputText($"##{node.Name}-rename", ref folderName, 100, ImGuiInputTextFlags.AutoSelectAll | ImGuiInputTextFlags.EnterReturnsTrue)) { folderNode.Name = folderName; plugin.SaveConfiguration(); } } ImGui.EndPopup(); } }
private void UiBuilder_TextNodeButtons() { var style = ImGui.GetStyle(); var newStyle = new Vector2(style.ItemSpacing.X / 2, style.ItemSpacing.Y); ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, newStyle); if (ImGuiEx.IconButton(FontAwesomeIcon.Plus, "Add new entry")) { var newNode = new TextEntryNode { Enabled = false, Text = "Your text goes here" }; AddTextNode.Add(new AddTextNodeOperation { Node = newNode, ParentNode = plugin.Configuration.RootFolder, Index = -1 }); } ImGui.SameLine(); if (ImGuiEx.IconButton(FontAwesomeIcon.SearchPlus, "Add last seen as new entry")) { var newNode = new TextEntryNode { Enabled = true, Text = plugin.LastSeenDialogText }; AddTextNode.Add(new AddTextNodeOperation { Node = newNode, ParentNode = plugin.Configuration.RootFolder, Index = -1 }); } ImGui.SameLine(); if (ImGuiEx.IconButton(FontAwesomeIcon.FolderPlus, "Add folder")) { var newNode = new TextFolderNode { Name = "Untitled folder" }; AddTextNode.Add(new AddTextNodeOperation { Node = newNode, ParentNode = plugin.Configuration.RootFolder, Index = -1 }); } var sb = new StringBuilder(); sb.AppendLine("Enter into the input all or part of the text inside a dialog."); sb.AppendLine("For example: \"Teleport to \" for the teleport dialog."); sb.AppendLine(); sb.AppendLine("Alternatively, wrap your text in forward slashes to use as a regex."); sb.AppendLine("As such: \"/Teleport to .*? for \\d+ gil\\?/\""); sb.AppendLine(); sb.AppendLine("If it matches, the yes button (and checkbox if present) will be clicked."); sb.AppendLine(); sb.AppendLine("Right click a line to view options."); sb.AppendLine("Double click an entry for quick enable/disable."); sb.AppendLine("Ctrl-Shift right click a line to delete it and any children."); sb.AppendLine(); sb.AppendLine("Currently supported text addons:"); sb.AppendLine(" - SelectYesNo"); sb.AppendLine(); sb.AppendLine("Non-text addons are each listed separately in the lower config section."); ImGui.SameLine(); ImGuiEx.IconButton(FontAwesomeIcon.QuestionCircle, sb.ToString()); ImGui.PopStyleVar(); // ItemSpacing }
public UILabel(AddTextNode Node, ParseResult Result, UIScreen Screen) : base(Screen) { Name = Node.Name; m_ID = Node.ID; Position = new Vector2(Node.TextPosition.Numbers[0], Node.TextPosition.Numbers[1]) + Screen.Position; if (Node.Size != null) { m_Size = new Vector2(Node.Size.Numbers[0], Node.Size.Numbers[1]); } else { m_Size = Result.State.Size; } if (Node.Color != null) { m_TextColor = new Color(); m_TextColor.A = 255; //Ignore opacity, The Sims Online doesn't support transparent text. m_TextColor.R = (byte)Node.Color.Numbers[0]; m_TextColor.G = (byte)Node.Color.Numbers[1]; m_TextColor.B = (byte)Node.Color.Numbers[2]; } else { m_TextColor = Result.State.Color; m_TextColor.A = 255; //Ignore opacity, The Sims Online doesn't support transparent text. } if (Node.Alignment != 0) { m_Alignment = Node.Alignment; } else { m_Alignment = (TextAlignment)Result.State.Alignment; } int Font = 0; if (Node.Font != null) { if (Node.Font != 0) { Font = (int)Node.Font; } } else { Font = Result.State.Font; } switch (Font) { case 7: m_Font = Screen.Font9px; //TODO: Fixme. break; case 9: m_Font = Screen.Font9px; break; case 10: m_Font = Screen.Font10px; break; case 11: m_Font = Screen.Font11px; break; case 12: m_Font = Screen.Font12px; break; case 14: m_Font = Screen.Font14px; break; case 16: m_Font = Screen.Font16px; break; } if (Node.Text != "") { Caption = Result.Strings[Node.Text]; } else { if (Result.State.Caption != "") { //Sometimes labels will not have pre-defined text, as they will hold text //generated in-game. Caption = Result.Strings[Result.State.Caption]; } } AlignText(); }