123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- 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;
- using System.Collections.Generic;
- 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;
- 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();
- public string Description => Trigger.Description;
- }
- public class EventTriggerGrid<TEvent, TDataModel> : DynamicItemsListGrid<EventTriggerContainer<TEvent, TDataModel>>
- where TEvent : IEvent<TDataModel>
- where TDataModel : IEventDataModel
- {
- public IEnumerable<IEventTrigger<TEvent, TDataModel>> EventTriggers => Items.Where(x => x.Parent is null).Select(x => x.Trigger);
- public EventTriggerGrid(IEnumerable<IEventTrigger<TEvent, TDataModel>> items)
- {
- 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)
- {
- base.DoReconfigure(options);
- options.AddRows = true;
- options.EditRows = true;
- options.DeleteRows = true;
- options.MultiSelect = true;
- }
- public override DynamicGridColumns GenerateColumns()
- {
- var cols = new DynamicGridColumns<EventTriggerContainer<TEvent, TDataModel>>();
- cols.Add(x => x.Description);
- return cols;
- }
- private void PopulateAddMenu(ItemsControl menu, IEventTrigger<TEvent, TDataModel>? trigger, OperatorType? op)
- {
- var types = EventUtils.GetEventTriggerTypes(typeof(TEvent));
- foreach(var type in types)
- {
- menu.AddMenuItem(type.GetCaption(), null, (type, trigger, op), MenuAdd_Click);
- }
- }
- private void MenuAdd_Click((Type type, IEventTrigger<TEvent, TDataModel>? trigger, OperatorType? op) tuple)
- {
- 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 container = new EventTriggerContainer<TEvent, TDataModel> { Trigger = trigger };
- if(tuple.trigger is not null)
- {
- // 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 RebuildItemsList()
- {
- var triggers = Items.Where(x => x.Parent is null).Select(x => x.Trigger).ToArray();
- Items.Clear();
- foreach(var item in triggers)
- {
- AddItem(item, null);
- }
- }
- private IEnumerable<EventTriggerContainer<TEvent, TDataModel>> GetAllChildren(EventTriggerContainer<TEvent, TDataModel> item)
- {
- yield return item;
- if(item.Trigger is IEventTriggerParent<TEvent, TDataModel> parent)
- {
- 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);
- }
- }
- protected override void DoAdd(bool openEditorOnDirectEdit = false)
- {
- var menu = new ContextMenu();
- PopulateAddMenu(menu, null, null);
- menu.IsOpen = true;
- }
- 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();
- }
- }
- }
|