/// <summary> /// Creates basic UI elements, but lefts bundle list empty. To fill it, call <see cref="CreateBundlesList"/> /// </summary> public BundlePickerWidget(BundlePicker bundlePicker) { this.bundlePicker = bundlePicker; Layout = new VBoxLayout { Spacing = 6 }; MaxWidth = 250f; checkboxes = new Dictionary <string, ThemedCheckBox>(); lines = new Dictionary <string, Widget>(); scrollView = new ThemedScrollView(); scrollView.CompoundPostPresenter.Add(new WidgetBoundsPresenter(Lime.Theme.Colors.ControlBorder)); scrollView.Content.Layout = new VBoxLayout { Spacing = 6 }; scrollView.Content.Padding = new Thickness(6); scrollView.CompoundPresenter.Add(new WidgetFlatFillPresenter(Color4.White)); selectButton = new ThemedButton { Text = "Select all", Clicked = SelectButtonClickHandler }; refreshButton = new ThemedButton { Text = "Refresh", Clicked = Refresh, }; filter = new ThemedEditBox(); filter.Tasks.Add(FilterBundlesTask); infoText = new ThemedSimpleText("Selected action uses all bundles.") { Color = Theme.Colors.BlackText, MinMaxHeight = Theme.Metrics.DefaultEditBoxSize.Y, Visible = false, VAlignment = VAlignment.Center, }; AddNode(filter); AddNode(infoText); AddNode(scrollView); var buttonLine = new Widget { Layout = new HBoxLayout { Spacing = 6 } }; AddNode(buttonLine); buttonLine.AddNode(new Widget { LayoutCell = new LayoutCell { StretchX = float.MaxValue }, MaxHeight = 0 }); buttonLine.AddNode(refreshButton); buttonLine.AddNode(selectButton); selectButton.Tasks.Add(UpdateTextOfSelectButtonTask()); }
private void ApplyFilter(string filter) { filter = filter.ToLower(); scrollView.ScrollPosition = 0; var isShowingAll = string.IsNullOrEmpty(filter); foreach (var group in scrollView.Content.Nodes) { var header = group.Nodes[0]; var expandButton = header.Nodes[0] as ThemedExpandButton; var wrapper = group.Nodes[1]; var expanded = false; foreach (var node in wrapper.Nodes) { var trigger = (node.Nodes[0] as ThemedSimpleText).Text.ToLower(); node.AsWidget.Visible = trigger.Contains(filter) || isShowingAll; if (!isShowingAll && node.AsWidget.Visible && !expanded) { expanded = true; expandButton.Expanded = true; wrapper.AsWidget.Visible = true; } } } }
public HierarchyPanel(Widget rootWidget) { DocumentHierarchyTreeView view; EditBox searchStringEditor; panelWidget = rootWidget; this.rootWidget = new Frame { Id = "SearchPanel", Padding = new Thickness(5), Layout = new VBoxLayout { Spacing = 5 }, Nodes = { (searchStringEditor = new ThemedEditBox()) } }; rootWidget.TabTravesable = new TabTraversable(); var treeView = new DocumentHierarchyTreeView(this.rootWidget, Document.Current.RootNode); var searchTreeView = new DocumentHierarchyTreeView(this.rootWidget, Document.Current.RootNode); searchStringEditor.AddChangeWatcher(() => searchStringEditor.Text, t => { if (!string.IsNullOrEmpty(t)) { if (treeView.IsAttached()) { treeView.Detach(); searchTreeView.Attach(); view = searchTreeView; } searchTreeView.Filter(t.ToLower()); } else { if (!searchTreeView.IsAttached()) { return; } searchTreeView.Detach(); treeView.Attach(); view = treeView; } }); treeView.Attach(); view = treeView; this.rootWidget.LateTasks.Add(new KeyRepeatHandler((input, key) => { if (!keyActionMap.ContainsKey(key)) { return; } input.ConsumeKey(key); keyActionMap[key](view); view.EnsureSelectionVisible(); Window.Current.Invalidate(); })); }
private ThemedEditBox CreateFilter() { filter = new ThemedEditBox { LayoutCell = new LayoutCell(Alignment.Center) }; filter.AddChangeWatcher( () => filter.Text, _ => ApplyFilter(_) ); return(filter); }
private void CreateEditor() { Nodes.Add(editor = new ThemedEditBox()); editor.LayoutCell = new LayoutCell(Alignment.LeftCenter); editor.Updating += (float delta) => { if (editor.Input.WasKeyPressed(Key.Enter)) { var adjustedText = AdjustPath(editor.Text); if (openPath(adjustedText)) { FlipState(); } else { editor.Text = filesystemModel.CurrentPath; } } }; }
private Widget CreateSearchBox() { searchBox = new ThemedEditBox(); searchBox.AddChangeWatcher( () => searchBox.Text, _ => ApplyColorSearch() ); return(new Widget { Layout = new HBoxLayout(), LayoutCell = new LayoutCell { StretchX = 2 }, Nodes = { new ThemedSimpleText("Search: ") { LayoutCell = new LayoutCell(Alignment.LeftCenter) }, searchBox } }); }
public ZoomWidget() { MinMaxHeight = FrameHeight; LayoutCell = new LayoutCell(new Alignment { X = HAlignment.Center, Y = VAlignment.Bottom }, 1, 0); Layout = new HBoxLayout { Spacing = 8 }; Padding = new Thickness(10, 0); Anchors = Anchors.LeftRight | Anchors.Bottom; HitTestTarget = true; slider = new ThemedSlider { MinMaxSize = new Vector2(100, 2), Size = new Vector2(100, 2), Y = FrameHeight / 2, LayoutCell = new LayoutCell(Alignment.RightCenter, 1), Anchors = Anchors.Right, RangeMin = 0, RangeMax = zoomTable.Count - 1, Step = 1 }; slider.CompoundPresenter.Add(new SliderCenterPresenter(FindNearest(1f, 0, zoomTable.Count), zoomTable.Count)); var zoomInButton = new ToolbarButton { MinMaxSize = new Vector2(FrameHeight), Size = new Vector2(FrameHeight), LayoutCell = new LayoutCell(Alignment.RightCenter), Anchors = Anchors.Right, Clicked = () => { if (CurrentSliderValue <= SceneView.Scene.Scale.X) { slider.Value = (slider.Value + slider.Step).Clamp(slider.RangeMin, slider.RangeMax); } Zoom(CurrentSliderValue); }, Texture = IconPool.GetTexture("SceneView.ZoomIn"), }; var zoomOutButton = new ToolbarButton { MinMaxSize = new Vector2(FrameHeight), Size = new Vector2(FrameHeight), LayoutCell = new LayoutCell(Alignment.RightCenter), Anchors = Anchors.Right, Clicked = () => { if (CurrentSliderValue >= SceneView.Scene.Scale.X) { slider.Value = (slider.Value - slider.Step).Clamp(slider.RangeMin, slider.RangeMax); } Zoom(CurrentSliderValue); }, Texture = IconPool.GetTexture("SceneView.ZoomOut"), }; var zoomEditor = new ThemedEditBox { LayoutCell = new LayoutCell(Alignment.RightCenter), Anchors = Anchors.Right, MinMaxWidth = 50 }; zoomEditor.Submitted += value => { var success = float.TryParse(value.TrimEnd('%'), out var zoom) && zoomTable.Count > 0; if (success) { Zoom(Mathf.Clamp(zoom / 100, zoomTable[0], zoomTable[zoomTable.Count - 1])); } }; this.AddChangeWatcher(() => SceneView.Scene.Scale.X, value => { var index = FindNearest(value, 0, zoomTable.Count); slider.Value = index; zoomEditor.Text = $"{value * 100f}%"; }); slider.Changed += () => Zoom(CurrentSliderValue); AddNode(new Widget { LayoutCell = new LayoutCell(Alignment.LeftCenter, 1) }); AddNode(zoomEditor); AddNode(zoomOutButton); AddNode(slider); AddNode(zoomInButton); }
private Widget CreateKeyboardPane() { var hotkeyEditor = new HotkeyEditor(); var pane = new Widget { Layout = new VBoxLayout { Spacing = 10 }, Padding = contentPadding }; pane.Awoke += node => hotkeyEditor.SetFocus(); var profileLabel = new ThemedSimpleText("Profile: ") { VAlignment = VAlignment.Center, HAlignment = HAlignment.Right, LayoutCell = new LayoutCell(Alignment.RightCenter, 0) }; var profilePicker = new ThemedDropDownList(); profilePicker.TextWidget.Padding = new Thickness(3, 0); var exportButton = new ThemedButton("Export..."); exportButton.Clicked = () => { var dlg = new FileDialog { Mode = FileDialogMode.Save, InitialFileName = currentProfile.Name }; if (dlg.RunModal()) { currentProfile.Save(dlg.FileName); } }; var importButton = new ThemedButton("Import..."); importButton.Clicked = () => { var dlg = new FileDialog { Mode = FileDialogMode.Open }; if (dlg.RunModal()) { string name = Path.GetFileName(dlg.FileName); if (HotkeyRegistry.Profiles.Any(i => i.Name == name)) { if (new AlertDialog($"Profile with name \"{name}\" already exists. Do you want to rewrite it?", "Yes", "Cancel").Show() != 0) { return; } else { profilePicker.Items.Remove(profilePicker.Items.First(i => i.Text == name)); } } var profile = HotkeyRegistry.CreateProfile(Path.GetFileName(dlg.FileName)); profile.Load(dlg.FileName); profile.Save(); HotkeyRegistry.Profiles.Add(profile); profilePicker.Items.Add(new CommonDropDownList.Item(profile.Name, profile)); profilePicker.Value = profile; } }; var deleteButton = new ThemedButton("Delete"); deleteButton.Clicked = () => { if (new AlertDialog($"Are you sure you want to delete profile \"{currentProfile.Name}\"?", "Yes", "Cancel").Show() == 0) { currentProfile.Delete(); profilePicker.Items.Remove(profilePicker.Items.First(i => i.Value == currentProfile)); profilePicker.Index = 0; HotkeyRegistry.CurrentProfile = profilePicker.Value as HotkeyProfile; foreach (var command in HotkeyRegistry.CurrentProfile.Commands) { command.Command.Shortcut = new Shortcut(Key.Unknown); } } }; var categoryLabel = new ThemedSimpleText("Commands: ") { VAlignment = VAlignment.Center, HAlignment = HAlignment.Right, LayoutCell = new LayoutCell(Alignment.RightCenter, 0) }; var categoryPicker = new ThemedDropDownList(); categoryPicker.TextWidget.Padding = new Thickness(3, 0); var allShortcutsView = new ThemedScrollView(); allShortcutsView.Content.Padding = contentPadding; allShortcutsView.Content.Layout = new VBoxLayout { Spacing = 8 }; var selectedShortcutsView = new ThemedScrollView(); selectedShortcutsView.Content.Padding = contentPadding; selectedShortcutsView.Content.Layout = new VBoxLayout { Spacing = 4 }; hotkeyEditor.SelectedShortcutChanged = () => { selectedShortcutsView.Content.Nodes.Clear(); var commands = hotkeyEditor.SelectedCommands.ToLookup(i => i.CategoryInfo); foreach (var category in commands) { selectedShortcutsView.Content.AddNode(new ThemedSimpleText { Text = category.Key.Title, VAlignment = VAlignment.Center, Color = Theme.Colors.GrayText }); foreach (var command in category) { var shortcut = new ThemedSimpleText { Text = command.Shortcut.ToString(), VAlignment = VAlignment.Center, LayoutCell = new LayoutCell(Alignment.LeftCenter, 1) }; var name = new ThemedSimpleText { Text = command.Title, VAlignment = VAlignment.Center, LayoutCell = new LayoutCell(Alignment.LeftCenter, 2) }; var deleteShortcutButton = new ThemedTabCloseButton { LayoutCell = new LayoutCell(Alignment.LeftCenter, 0), Clicked = () => { command.Shortcut = new Shortcut(); hotkeyEditor.UpdateButtonCommands(); hotkeyEditor.UpdateShortcuts(); } }; selectedShortcutsView.Content.AddNode(new Widget { Layout = new TableLayout { Spacing = 4, RowCount = 1, ColumnCount = 3 }, Nodes = { shortcut, name, deleteShortcutButton }, Padding = new Thickness(15, 0) }); } } selectedShortcutsView.ScrollPosition = allShortcutsView.MinScrollPosition; }; var filterBox = new ThemedEditBox { MaxWidth = 200 }; filterBox.AddChangeWatcher(() => filterBox.Text, text => { UpdateAllShortcutsView(allShortcutsView, selectedShortcutsView, hotkeyEditor, text.ToLower()); allShortcutsView.ScrollPosition = allShortcutsView.MinScrollPosition; }); categoryPicker.Changed += args => { hotkeyEditor.Category = (args.Value as CommandCategoryInfo); hotkeyEditor.SetFocus(); int index = -1; foreach (var node in allShortcutsView.Content.Nodes.SelectMany(i => i.Nodes)) { var button = node as ThemedExpandButton; if (button == null) { continue; } index++; if (index == args.Index) { if (!button.Expanded) { button.Clicked?.Invoke(); } allShortcutsView.ScrollPosition = button.ParentWidget.Position.Y; break; } } }; profilePicker.Changed += args => { var profile = args.Value as HotkeyProfile; if (profile != null) { hotkeyEditor.Profile = profile; filterBox.Text = null; UpdateAllShortcutsView(allShortcutsView, selectedShortcutsView, hotkeyEditor, filterBox.Text); deleteButton.Enabled = profile.Name != HotkeyRegistry.DefaultProfileName && profilePicker.Items.Count > 1; categoryPicker.Items.Clear(); foreach (var category in profile.Categories) { categoryPicker.Items.Add(new CommonDropDownList.Item(category.Title, category)); } categoryPicker.Value = null; categoryPicker.Value = profile.Categories.First(); currentProfile = profile; } }; UpdateProfiles(profilePicker); HotkeyRegistry.Reseted = () => UpdateProfiles(profilePicker); pane.AddNode(new Widget { Layout = new TableLayout { Spacing = 4, RowCount = 2, ColumnCount = 3 }, Nodes = { profileLabel, profilePicker, new Widget { Layout = new HBoxLayout { Spacing = 4 }, Nodes = { exportButton,importButton, deleteButton } }, categoryLabel, categoryPicker }, LayoutCell = new LayoutCell { StretchY = 0 } }); pane.AddNode(hotkeyEditor); pane.AddNode(new Widget { Layout = new HBoxLayout { Spacing = 12 }, Nodes = { new Widget { Layout = new VBoxLayout{ Spacing = 4 }, Nodes = { new Widget { Layout = new HBoxLayout{ Spacing = 8 }, Nodes = { new ThemedSimpleText("Search: ") { VAlignment = VAlignment.Center, LayoutCell = new LayoutCell(Alignment.LeftCenter, 0) }, filterBox }, LayoutCell = new LayoutCell{ StretchY = 0 } }, new ThemedFrame { Nodes = { allShortcutsView }, Layout = new VBoxLayout() } } }, new Widget { Layout = new VBoxLayout{ Spacing = 4 }, Nodes = { new ThemedSimpleText("Selected commands:") { LayoutCell = new LayoutCell{ StretchY = 0 } }, new ThemedFrame { Nodes = { selectedShortcutsView }, Layout = new VBoxLayout() } } } } }); return(pane); }
public Result Show(Marker marker, bool canDelete) { Widget buttonsPanel; Button deleteButton; Button okButton; Button cancelButton; DropDownList actionSelector; EditBox markerIdEditor; ThemedDropDownList jumpToSelector; Result result; var window = new Window(new WindowOptions { FixedSize = true, Title = "Marker properties", Visible = false, Style = WindowStyle.Dialog }); jumpToSelector = new ThemedDropDownList(); foreach (var m in Document.Current.Container.Markers) { jumpToSelector.Items.Add(new ThemedDropDownList.Item(m.Id, m)); } jumpToSelector.Text = marker.JumpTo; var rootWidget = new ThemedInvalidableWindowWidget(window) { LayoutBasedWindowSize = true, Padding = new Thickness(8), Layout = new VBoxLayout { Spacing = 16 }, Nodes = { new Widget { Layout = new TableLayout{ ColCount = 2, RowCount = 3, Spacing = 8, ColDefaults = { new LayoutCell(Alignment.RightCenter, 0.5f, 0), new LayoutCell(Alignment.LeftCenter, 1, 0) } }, Nodes = { new ThemedSimpleText("Marker Id"), (markerIdEditor = new ThemedEditBox{ Text = marker.Id, MinSize= Theme.Metrics.DefaultEditBoxSize * new Vector2(2, 1) }), new ThemedSimpleText("Action"), (actionSelector = new ThemedDropDownList{ Items = { new DropDownList.Item("Play", MarkerAction.Play), new DropDownList.Item("Jump", MarkerAction.Jump), new DropDownList.Item("Stop", MarkerAction.Stop), new DropDownList.Item("Destroy", MarkerAction.Destroy), }, Value = marker.Action }), new ThemedSimpleText("Jump to"), jumpToSelector, } }, (buttonsPanel = new Widget{ Layout = new HBoxLayout{ Spacing = 8 }, LayoutCell = new LayoutCell(Alignment.RightCenter), Nodes = { (okButton = new ThemedButton("Ok")), (cancelButton = new ThemedButton("Cancel")), } }) } }; if (canDelete) { deleteButton = new ThemedButton("Delete"); buttonsPanel.AddNode(deleteButton); deleteButton.Clicked += () => { result = Result.Delete; window.Close(); }; } rootWidget.FocusScope = new KeyboardFocusScope(rootWidget); rootWidget.LateTasks.Add(new KeyPressHandler(Key.Escape, (input, key) => { input.ConsumeKey(key); window.Close(); })); okButton.Clicked += () => { result = Result.Ok; window.Close(); }; cancelButton.Clicked += window.Close; okButton.SetFocus(); result = Result.Cancel; window.ShowModal(); if (result == Result.Ok) { marker.Id = markerIdEditor.Text; marker.Action = (MarkerAction)actionSelector.Value; marker.JumpTo = jumpToSelector.Text; } return(result); }
public SaveRulerDialog(Ruler ruler) { ThemedButton cancelButton; ThemedButton okButton; CheckBox checkBox; EditBox editBox; window = new Window(new WindowOptions { Title = "Save Ruler", Visible = false, Style = WindowStyle.Dialog, }); WindowWidget rootWidget = new ThemedInvalidableWindowWidget(window) { LayoutBasedWindowSize = true, Padding = new Thickness(8), Layout = new VBoxLayout { Spacing = 16 }, Nodes = { new Widget { Layout = new TableLayout{ ColumnCount = 2, RowCount = 2, Spacing = 8, ColumnDefaults = { new DefaultLayoutCell(Alignment.RightCenter, 0.5f, 0), new DefaultLayoutCell(Alignment.LeftCenter, 1, 0) } }, Nodes = { new ThemedSimpleText("Ruler name"), (editBox = new ThemedEditBox{ MinWidth = 150 }), new ThemedSimpleText("Anchor to root"), (checkBox = new ThemedCheckBox()) } }, new Widget { Layout = new HBoxLayout{ Spacing = 8 }, LayoutCell = new LayoutCell(Alignment.RightCenter), Nodes = { (okButton = new ThemedButton("Ok")), (cancelButton = new ThemedButton("Cancel")), } } } }; cancelButton.Clicked += window.Close; okButton.AddChangeWatcher(() => editBox.Text, (text) => okButton.Enabled = !string.IsNullOrEmpty(text)); okButton.Clicked += () => { ruler.Name = editBox.Text; ruler.AnchorToRoot = checkBox.Checked; result = true; window.Close(); }; rootWidget.FocusScope = new KeyboardFocusScope(rootWidget); editBox.SetFocus(); }
private void CreateOverridesWidgets(CookingRulesCollection crc, string key, Target target, Meta.Item yi, CookingRules rules, Widget overridesWidget) { Widget innerContainer; var sourceFilenameText = string.IsNullOrEmpty(rules.SourceFilename) ? "Default" : rules.SourceFilename.Substring(The.Workspace.AssetsDirectory.Length); var targetName = target == null ? "" : $" ({target.Name})"; var container = new Widget { Padding = new Thickness { Right = 30 }, Nodes = { (innerContainer = new Widget { Layout = new HBoxLayout(), }), new ThemedSimpleText(sourceFilenameText + targetName) { FontHeight = 16, ForceUncutText = false, OverflowMode = TextOverflowMode.Ellipsis, HAlignment = HAlignment.Right, VAlignment = VAlignment.Center, MinSize = new Vector2(100, RowHeight), MaxSize = new Vector2(500, RowHeight) }, (new ToolbarButton { Texture = IconPool.GetTexture("Filesystem.ArrowRight"), Padding = Thickness.Zero, Size = RowHeight * Vector2.One, MinMaxSize = RowHeight * Vector2.One, Clicked = () => navigateAndSelect(rules.SourceFilename), }) }, Layout = new HBoxLayout(), }; container.CompoundPostPresenter.Add(new DelegatePresenter <Widget>((w) => { var topmostOverride = crc[key]; while ( topmostOverride.Parent != null && !(topmostOverride.CommonRules.FieldOverrides.Contains(yi) || RulesForActiveTarget(topmostOverride).FieldOverrides.Contains(yi)) ) { topmostOverride = topmostOverride.Parent; } w.PrepareRendererState(); if (target != activeTarget || rules != topmostOverride) { Renderer.DrawLine(10.0f - 30.0f, w.Height * 0.6f, w.Width - 10.0f, w.Height * 0.6f, Color4.Black.Transparentify(0.5f), 1.0f); } else { Renderer.DrawRect(Vector2.Right * -20.0f, w.Size, Color4.Green.Lighten(0.5f).Transparentify(0.5f)); } })); container.Components.Add(new PropertyOverrideComponent { Rules = rules, YuzuItem = yi, }); overridesWidget.Nodes.Add(container); var targetRuels = RulesForTarget(rules, target); var editorParams = new PropertyEditorParams(innerContainer, targetRuels, yi.Name) { ShowLabel = false, PropertySetter = (owner, name, value) => { yi.SetValue(owner, value); targetRuels.Override(name); rules.DeduceEffectiveRules(target); rules.Save(); }, NumericEditBoxFactory = () => { var r = new ThemedNumericEditBox(); r.MinMaxHeight = r.Height = RowHeight; r.TextWidget.VAlignment = VAlignment.Center; r.TextWidget.Padding.Top = r.TextWidget.Padding.Bottom = 0.0f; return(r); }, DropDownListFactory = () => { var r = new ThemedDropDownList(); r.MinMaxHeight = r.Height = RowHeight; return(r); }, EditBoxFactory = () => { var r = new ThemedEditBox(); r.MinMaxHeight = r.Height = RowHeight; r.TextWidget.Padding.Top = r.TextWidget.Padding.Bottom = 0.0f; return(r); }, }; CreatePropertyEditorForType(yi, editorParams); }
public TextEditorDialog(string title, string text, Action <string> onSave) { window = new Window(new WindowOptions { ClientSize = new Vector2(300, 200), FixedSize = false, Title = title, Visible = false, }); rootWidget = new ThemedInvalidableWindowWidget(window) { Padding = new Thickness(8), Layout = new VBoxLayout(), Nodes = { new Widget { Layout = new AnchorLayout(), Nodes = { (editor = new ThemedEditBox{ Anchors = Anchors.LeftRightTopBottom, Text = text, }) }, }, new Widget { Layout = new HBoxLayout{ Spacing = 8 }, LayoutCell = new LayoutCell{ StretchY = 0 }, Padding = new Thickness{ Top = 5 }, Nodes = { new Widget { MinMaxHeight = 0 }, (okButton = new ThemedButton{ Text = "Ok" }), (cancelButton = new ThemedButton{ Text = "Cancel" }), }, } } }; // TODO: implement multiline scrollable text editor. const int maxLines = 640; editor.Editor.EditorParams.MaxLines = maxLines; editor.MinHeight = editor.TextWidget.FontHeight * maxLines; editor.TextWidget.VAlignment = VAlignment.Top; cancelButton.Clicked += () => { window.Close(); }; okButton.Clicked += () => { onSave(editor.Text); window.Close(); }; window.ShowModal(); }
private void RenameAnimation() { var index = GetSelectedAnimationIndex(); var animation = GetAnimations()[index]; var item = (Widget)scrollView.Content.Nodes[index]; var label = item["Label"]; label.Visible = false; var editor = new ThemedEditBox(); label.Parent.Nodes.Insert(label.CollectionIndex(), editor); editor.Text = animation.Id; editor.SetFocus(); editor.AddChangeWatcher(() => editor.IsFocused(), focused => { if (!focused) { var newId = editor.Text.Trim(); if (!animation.Owner.Animations.Any(a => a.Id == newId)) { RenameAnimationHelper(newId); } editor.Unlink(); label.Visible = true; } }); editor.Submitted += s => { RenameAnimationHelper(s.Trim()); editor.Unlink(); label.Visible = true; }; void RenameAnimationHelper(string newId) { string error = null; if (animation.IsLegacy) { error = "Can't rename legacy animation"; } else if (animation.Id == Animation.ZeroPoseId) { error = "Can't rename zero pose animation"; } else if (newId.IsNullOrWhiteSpace() || newId == Animation.ZeroPoseId) { error = "Invalid animation id"; } else if (TangerineDefaultCharsetAttribute.IsValid(newId, out var message) != ValidationResult.Ok) { error = message; } else if (animation.Owner.Animations.Any(a => a.Id == newId)) { error = $"An animation '{newId}' already exists"; } if (error != null) { UI.AlertDialog.Show(error, "Ok"); return; } Document.Current.History.DoTransaction(() => { var oldId = animation.Id; Core.Operations.SetProperty.Perform(animation, nameof(Animation.Id), newId); foreach (var a in animation.Owner.Animations) { foreach (var track in a.Tracks) { foreach (var animator in track.Animators) { if (animator.AnimationId == oldId) { Core.Operations.SetProperty.Perform(animator, nameof(IAnimator.AnimationId), newId); } } } } ChangeAnimatorsAnimationId(animation.OwnerNode); void ChangeAnimatorsAnimationId(Node node) { foreach (var child in node.Nodes) { foreach (var animator in child.Animators) { if (animator.AnimationId == oldId) { Core.Operations.SetProperty.Perform(animator, nameof(IAnimator.AnimationId), newId); } } if (child.ContentsPath != null) { continue; } if (child.Animations.Any(i => i.Id == oldId)) { continue; } ChangeAnimatorsAnimationId(child); } } }); } }