Editor/ChitChat/DialogueSelector.cs
using Sandbox;
using Editor;
using System;
using System.Linq;
namespace ChitChat.Editor;
public class DialogueSelector : Widget
{
public Action<SerializedProperty> onDialogueActionSelected;
public Action onSelectedDialogueRemoved;
private ScrollArea _dialogueArea;
private ListControlView _listView;
private Menu _menu;
private SerializedObject _serializedObject;
private SerializedCollection _serializedDialogueDatasArray;
private int _lastSelectedIndex = -1;
public DialogueSelector(Widget parent, DialogueData data) : base(parent)
{
WindowTitle = "Dialogue Selector";
Name = "Dialogue Selector";
Size = new Vector2(ChitChatEditorWindow.WINDOW_SIZE_X * 0.5f, ChitChatEditorWindow.WINDOW_SIZE_Y * 0.5f);
Layout = Layout.Column();
SetWindowIcon("list_alt");
_serializedObject = data.GetSerialized();
Rebuild();
}
public void SetData(DialogueData data) => _serializedObject = data.GetSerialized();
public void SelectLastest()
{
_listView.SelectItem(_lastSelectedIndex);
}
//TODO: Use this to see if something changed and update asset
public override void ChildValuesChanged(Widget source)
{
base.ChildValuesChanged(source);
}
public void Rebuild()
{
//Needs to save last selected index to reload it at that index
if(_listView.IsValid())
_lastSelectedIndex = _listView.SelectedIndex;
Layout.Clear(true);
SerializedProperty prop = _serializedObject.GetProperty(nameof(DialogueData.DialogueDatas));
//Scroll area
_dialogueArea = new ScrollArea(this);
_dialogueArea.Layout = Layout.Column();
_dialogueArea.Canvas = new Widget(_dialogueArea);
_dialogueArea.Canvas.Layout = Layout.Column();
_dialogueArea.Canvas.Layout.Alignment = TextFlag.LeftTop;
_dialogueArea.Canvas.Parent.Update();
if (prop.TryGetAsObject(out var obj))
{
//Dialogue list
_serializedDialogueDatasArray = (SerializedCollection)obj;
_listView = new ListControlView(prop, _serializedDialogueDatasArray, OnCreateUIListItem, false);
_listView.onItemSelected += OnItemSelected;
_listView.onItemRemoved += OnItemMovedOrRemoved;
_listView.onItemMoved += OnItemMovedOrRemoved;
_listView.onItemRightClicked += CreateDialogueActionMenuWithIndex;
_dialogueArea.Canvas.Layout.Add(_listView);
}
//Add dialogue action button
Widget addButtonContainer = new Widget(_dialogueArea.Canvas);
addButtonContainer.Layout = Layout.Row();
addButtonContainer.Layout.Alignment = TextFlag.Left;
addButtonContainer.Layout.AddSpacingCell(24);
IconButton addDialogueActionButton = new IconButton("add", CreateDialogueActionMenu);
addDialogueActionButton.Background = Theme.ControlBackground;
addButtonContainer.Layout.Add(addDialogueActionButton);
_dialogueArea.Canvas.Layout.Add(addButtonContainer);
_dialogueArea.Canvas.Layout.AddStretchCell();
Layout.Add(_dialogueArea);
}
private ControlWidget OnCreateUIListItem(SerializedProperty prop)
{
DialogueActionBase baseAction = prop.GetValue<DialogueActionBase>();
if (baseAction is SpeakAction)
{
return new SpeakActionControlWidget(prop);
}
else if (baseAction is EventAction)
{
return new EventActionControlWidget(prop);
}
else if (baseAction is ChoiceAction)
{
return new ChoiceActionControlWidget(prop);
}
return ControlWidget.Create(prop);
}
private void CreateDialogueActionMenu()
{
if(_menu.IsValid())
return;
CreateDialogueActionMenuWithIndex(_serializedDialogueDatasArray.Count() - 1);
}
private void CreateDialogueActionMenuWithIndex(int index)
{
if (_menu.IsValid())
return;
_menu = new ContextMenu();
_menu.AddHeading("Dialogue Actions");
_menu.AddOption("Speak Action", "record_voice_over", () => _serializedDialogueDatasArray.Add(index + 1, new SpeakAction(TemplateWindow.s_SpeakActionTemplate)));
_menu.AddSeparator();
_menu.AddOption("Event Action", "event", () => _serializedDialogueDatasArray.Add(index + 1, new EventAction(TemplateWindow.s_EventActionTemplate)));
_menu.AddSeparator();
_menu.AddOption("Choice Action", "alt_route", () => _serializedDialogueDatasArray.Add(index + 1, new ChoiceAction(TemplateWindow.s_ChoiceActionTemplate)));
_menu.OpenAtCursor(true);
_menu.MinimumWidth = ScreenRect.Width;
}
private void OnItemMovedOrRemoved(int index)
{
if(index == _listView.SelectedIndex)
onSelectedDialogueRemoved?.Invoke();
}
private void OnItemSelected(SerializedProperty prop)
{
onDialogueActionSelected?.Invoke(prop);
}
}