|
|
@@ -1,6 +1,8 @@
|
|
|
-using InABox.Core;
|
|
|
+using com.sun.xml.@internal.bind.v2.runtime;
|
|
|
+using InABox.Core;
|
|
|
using InABox.DynamicGrid;
|
|
|
using InABox.WPF;
|
|
|
+using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
|
using PRS.Shared.Events;
|
|
|
using PRS.Shared.Grids.EventEditor;
|
|
|
using System;
|
|
|
@@ -9,6 +11,7 @@ using System.Linq;
|
|
|
using System.Text;
|
|
|
using System.Threading.Tasks;
|
|
|
using System.Windows.Controls;
|
|
|
+using System.Windows.Markup.Localizer;
|
|
|
using System.Windows.Media;
|
|
|
|
|
|
namespace PRS.Shared;
|
|
|
@@ -17,6 +20,8 @@ public class EventTriggerContainer<TEvent, TDataModel> : BaseObject
|
|
|
where TEvent : IEvent<TDataModel>
|
|
|
where TDataModel : IEventDataModel
|
|
|
{
|
|
|
+ public IEventTriggerParent<TEvent, TDataModel>? Parent { get; set; }
|
|
|
+
|
|
|
public IEventTrigger<TEvent, TDataModel> Trigger { get; set; }
|
|
|
|
|
|
public string TriggerType => Trigger.GetType().GetCaption();
|
|
|
@@ -28,11 +33,78 @@ public class EventTriggerGrid<TEvent, TDataModel> : DynamicItemsListGrid<EventTr
|
|
|
where TEvent : IEvent<TDataModel>
|
|
|
where TDataModel : IEventDataModel
|
|
|
{
|
|
|
- public IEnumerable<IEventTrigger<TEvent, TDataModel>> EventTriggers => Items.Select(x => x.Trigger);
|
|
|
+ public IEnumerable<IEventTrigger<TEvent, TDataModel>> EventTriggers => Items.Where(x => x.Parent is null).Select(x => x.Trigger);
|
|
|
|
|
|
public EventTriggerGrid(IEnumerable<IEventTrigger<TEvent, TDataModel>> items)
|
|
|
{
|
|
|
- Items.AddRange(items.Select(x => new EventTriggerContainer<TEvent, TDataModel> { Trigger = x }));
|
|
|
+ foreach(var item in items)
|
|
|
+ {
|
|
|
+ AddItem(item, null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private EventTriggerContainer<TEvent, TDataModel> GetContainer(IEventTrigger<TEvent, TDataModel> item)
|
|
|
+ {
|
|
|
+ return Items.First(x => x.Trigger == item);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void AddItem(IEventTrigger<TEvent, TDataModel> item, IEventTriggerParent<TEvent, TDataModel>? parent)
|
|
|
+ {
|
|
|
+ Items.Add(new EventTriggerContainer<TEvent, TDataModel>
|
|
|
+ {
|
|
|
+ Trigger = item,
|
|
|
+ Parent = parent
|
|
|
+ });
|
|
|
+ if(item is IEventTriggerParent<TEvent, TDataModel> parentTrigger)
|
|
|
+ {
|
|
|
+ foreach(var child in parentTrigger.ChildTriggers)
|
|
|
+ {
|
|
|
+ AddItem(child, parentTrigger);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override IDynamicGridUIComponent CreateUIComponent()
|
|
|
+ {
|
|
|
+ var component = new DynamicGridTreeUIComponent<EventTriggerContainer<TEvent, TDataModel>, IEventTrigger<TEvent, TDataModel>?>(
|
|
|
+ x => LoadItem(x).Trigger,
|
|
|
+ x => LoadItem(x).Parent,
|
|
|
+ null,
|
|
|
+ (container, parent) =>
|
|
|
+ {
|
|
|
+ if (parent is IEventTriggerParent<TEvent, TDataModel> parentTrigger)
|
|
|
+ {
|
|
|
+ parentTrigger.ChildTriggers.Add(container.Trigger);
|
|
|
+ container.Parent = parentTrigger;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ {
|
|
|
+ Parent = this,
|
|
|
+ };
|
|
|
+ component.OnContextMenuOpening += Component_OnContextMenuOpening;
|
|
|
+ return component;
|
|
|
+ }
|
|
|
+
|
|
|
+ private enum OperatorType
|
|
|
+ {
|
|
|
+ And,
|
|
|
+ Or
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Component_OnContextMenuOpening(CoreTreeNode<IEventTrigger<TEvent, TDataModel>?>? node, ContextMenu menu)
|
|
|
+ {
|
|
|
+ if(node is null)
|
|
|
+ {
|
|
|
+ PopulateAddMenu(menu, null, null);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ var andItem = menu.AddItem("And", null, null);
|
|
|
+ PopulateAddMenu(andItem, node.ID, OperatorType.And);
|
|
|
+
|
|
|
+ var orItem = menu.AddItem("Or", null, null);
|
|
|
+ PopulateAddMenu(orItem, node.ID, OperatorType.Or);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
protected override void DoReconfigure(DynamicGridOptions options)
|
|
|
@@ -51,47 +123,176 @@ public class EventTriggerGrid<TEvent, TDataModel> : DynamicItemsListGrid<EventTr
|
|
|
return cols;
|
|
|
}
|
|
|
|
|
|
- protected override void DoAdd(bool openEditorOnDirectEdit = false)
|
|
|
+ private void PopulateAddMenu(ItemsControl menu, IEventTrigger<TEvent, TDataModel>? trigger, OperatorType? op)
|
|
|
{
|
|
|
var types = EventUtils.GetEventTriggerTypes(typeof(TEvent));
|
|
|
|
|
|
- var menu = new ContextMenu();
|
|
|
foreach(var type in types)
|
|
|
{
|
|
|
- menu.AddItem(type.GetCaption(), null, type, MenuAdd_Click);
|
|
|
+ menu.AddMenuItem(type.GetCaption(), null, (type, trigger, op), MenuAdd_Click);
|
|
|
}
|
|
|
- menu.IsOpen = true;
|
|
|
}
|
|
|
|
|
|
- protected override void DoEdit()
|
|
|
+ private void MenuAdd_Click((Type type, IEventTrigger<TEvent, TDataModel>? trigger, OperatorType? op) tuple)
|
|
|
{
|
|
|
- if (SelectedRows.Length != 1) return;
|
|
|
+ if (tuple.type.IsGenericType)
|
|
|
+ {
|
|
|
+ tuple.type = tuple.type.MakeGenericType(typeof(TEvent).GenericTypeArguments);
|
|
|
+ }
|
|
|
+ var trigger = (Activator.CreateInstance(tuple.type) as IEventTrigger<TEvent, TDataModel>)!;
|
|
|
+ if (!EventTriggerEditors.EditTrigger(trigger))
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- var row = SelectedRows.First();
|
|
|
- var item = LoadItem(row);
|
|
|
- if (EventTriggerEditors.EditTrigger(item.Trigger))
|
|
|
+ var container = new EventTriggerContainer<TEvent, TDataModel> { Trigger = trigger };
|
|
|
+
|
|
|
+ if(tuple.trigger is not null)
|
|
|
{
|
|
|
- UpdateRow(row, item);
|
|
|
- DoChanged();
|
|
|
+ // Insert index of 'trigger' into 'parent'
|
|
|
+ int? parentInsertIndex = null;
|
|
|
+ IEventTriggerParent<TEvent, TDataModel>? parent = null;
|
|
|
+
|
|
|
+ var triggerContainer = GetContainer(tuple.trigger);
|
|
|
+ if(tuple.op == OperatorType.And && triggerContainer.Trigger is AndTrigger<TEvent, TDataModel> andTrigger)
|
|
|
+ {
|
|
|
+ parent = andTrigger;
|
|
|
+ parentInsertIndex = null;
|
|
|
+ }
|
|
|
+ else if(tuple.op == OperatorType.Or && triggerContainer.Trigger is OrTrigger<TEvent, TDataModel> orTrigger)
|
|
|
+ {
|
|
|
+ parent = orTrigger;
|
|
|
+ parentInsertIndex = null;
|
|
|
+ }
|
|
|
+ else if(tuple.op == OperatorType.And && triggerContainer.Parent is AndTrigger<TEvent, TDataModel> andTrigger2)
|
|
|
+ {
|
|
|
+ parent = andTrigger2;
|
|
|
+ parentInsertIndex = triggerContainer.Parent.ChildTriggers.IndexOf(triggerContainer.Trigger) + 1;
|
|
|
+ }
|
|
|
+ else if(tuple.op == OperatorType.Or && triggerContainer.Parent is OrTrigger<TEvent, TDataModel> orTrigger2)
|
|
|
+ {
|
|
|
+ parent = orTrigger2;
|
|
|
+ parentInsertIndex = triggerContainer.Parent.ChildTriggers.IndexOf(triggerContainer.Trigger) + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(parent is not null)
|
|
|
+ {
|
|
|
+ container.Parent = parent;
|
|
|
+ if (parentInsertIndex.HasValue && parentInsertIndex < parent.ChildTriggers.Count)
|
|
|
+ {
|
|
|
+ parent.ChildTriggers.Insert(parentInsertIndex.Value, trigger);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ parent.ChildTriggers.Add(trigger);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(tuple.op == OperatorType.And)
|
|
|
+ {
|
|
|
+ parent = new AndTrigger<TEvent, TDataModel>();
|
|
|
+ }
|
|
|
+ else if(tuple.op == OperatorType.Or)
|
|
|
+ {
|
|
|
+ parent = new OrTrigger<TEvent, TDataModel>();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(parent is not null)
|
|
|
+ {
|
|
|
+ int? itemsInsertIndex = null;
|
|
|
+
|
|
|
+ var parentContainer = new EventTriggerContainer<TEvent, TDataModel>()
|
|
|
+ {
|
|
|
+ Trigger = parent,
|
|
|
+ Parent = triggerContainer.Parent
|
|
|
+ };
|
|
|
+ if(triggerContainer.Parent is not null)
|
|
|
+ {
|
|
|
+ var index = triggerContainer.Parent.ChildTriggers.IndexOf(triggerContainer.Trigger);
|
|
|
+
|
|
|
+ triggerContainer.Parent.ChildTriggers[index] = parent;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ itemsInsertIndex = Items.IndexOf(triggerContainer);
|
|
|
+ }
|
|
|
+
|
|
|
+ triggerContainer.Parent = parent;
|
|
|
+ container.Parent = parent;
|
|
|
+ parent.ChildTriggers.Add(triggerContainer.Trigger);
|
|
|
+ parent.ChildTriggers.Add(trigger);
|
|
|
+
|
|
|
+ if (itemsInsertIndex.HasValue)
|
|
|
+ {
|
|
|
+ Items.Insert(itemsInsertIndex.Value, parentContainer);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Items.Add(parentContainer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ Items.Add(container);
|
|
|
+
|
|
|
+ RebuildItemsList();
|
|
|
+
|
|
|
+ Refresh(false, true);
|
|
|
+ DoChanged();
|
|
|
}
|
|
|
|
|
|
- private void MenuAdd_Click(Type type)
|
|
|
+ private void RebuildItemsList()
|
|
|
{
|
|
|
- if (type.IsGenericType)
|
|
|
+ var triggers = Items.Where(x => x.Parent is null).Select(x => x.Trigger).ToArray();
|
|
|
+ Items.Clear();
|
|
|
+ foreach(var item in triggers)
|
|
|
{
|
|
|
- type = type.MakeGenericType(typeof(TEvent).GenericTypeArguments);
|
|
|
+ AddItem(item, null);
|
|
|
}
|
|
|
- var trigger = (Activator.CreateInstance(type) as IEventTrigger<TEvent, TDataModel>)!;
|
|
|
- if (!EventTriggerEditors.EditTrigger(trigger))
|
|
|
+ }
|
|
|
+
|
|
|
+ private IEnumerable<EventTriggerContainer<TEvent, TDataModel>> GetAllChildren(EventTriggerContainer<TEvent, TDataModel> item)
|
|
|
+ {
|
|
|
+ yield return item;
|
|
|
+ if(item.Trigger is IEventTriggerParent<TEvent, TDataModel> parent)
|
|
|
{
|
|
|
- return;
|
|
|
+ foreach(var childItem in parent.ChildTriggers.SelectMany(x => GetAllChildren(GetContainer(x))))
|
|
|
+ {
|
|
|
+ yield return childItem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void DeleteItems(params CoreRow[] rows)
|
|
|
+ {
|
|
|
+ var toDelete = rows.SelectMany(x => GetAllChildren(LoadItem(x))).ToArray();
|
|
|
+ foreach(var item in toDelete)
|
|
|
+ {
|
|
|
+ item.Parent?.ChildTriggers.Remove(item.Trigger);
|
|
|
+ Items.Remove(item);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- Items.Add(new() { Trigger = trigger });
|
|
|
+ protected override void DoAdd(bool openEditorOnDirectEdit = false)
|
|
|
+ {
|
|
|
+ var menu = new ContextMenu();
|
|
|
+ PopulateAddMenu(menu, null, null);
|
|
|
+ menu.IsOpen = true;
|
|
|
+ }
|
|
|
|
|
|
- Refresh(false, true);
|
|
|
- DoChanged();
|
|
|
+ protected override void DoEdit()
|
|
|
+ {
|
|
|
+ if (SelectedRows.Length != 1) return;
|
|
|
+
|
|
|
+ var row = SelectedRows.First();
|
|
|
+ var item = LoadItem(row);
|
|
|
+ if (EventTriggerEditors.EditTrigger(item.Trigger))
|
|
|
+ {
|
|
|
+ UpdateRow(row, item);
|
|
|
+ DoChanged();
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|