EventEditor.xaml.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. using AutoProperties;
  2. using Comal.Classes;
  3. using InABox.Core;
  4. using InABox.DynamicGrid;
  5. using InABox.WPF;
  6. using PRS.Shared.Events;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.ComponentModel;
  10. using System.Diagnostics;
  11. using System.Linq;
  12. using System.Reflection;
  13. using System.Runtime.CompilerServices;
  14. using System.Text;
  15. using System.Threading.Tasks;
  16. using System.Windows;
  17. using System.Windows.Controls;
  18. using System.Windows.Data;
  19. using System.Windows.Documents;
  20. using System.Windows.Input;
  21. using System.Windows.Media;
  22. using System.Windows.Media.Imaging;
  23. using System.Windows.Shapes;
  24. namespace PRS.Shared;
  25. /// <summary>
  26. /// Interaction logic for EventEditorWIndow.xaml
  27. /// </summary>
  28. public partial class EventEditor : UserControl, INotifyPropertyChanged
  29. {
  30. private EventType? _eventType;
  31. public EventType? EventType
  32. {
  33. get => _eventType;
  34. set
  35. {
  36. _eventType = value;
  37. OnPropertyChanged();
  38. HasType = value.HasValue && EventTypeHasEntityType(value.Value);
  39. HasTriggers = value != Comal.Classes.EventType.Scheduled;
  40. DoChanged();
  41. UpdateEventData();
  42. }
  43. }
  44. private Type? _entityType;
  45. public Type? EntityType
  46. {
  47. get => _entityType;
  48. set
  49. {
  50. _entityType = value;
  51. OnPropertyChanged();
  52. UpdateEventData();
  53. }
  54. }
  55. private bool _hasTriggers = true;
  56. public bool HasTriggers
  57. {
  58. get => _hasTriggers;
  59. set
  60. {
  61. _hasTriggers = value;
  62. OnPropertyChanged();
  63. }
  64. }
  65. private bool _hasProperties;
  66. public bool HasProperties
  67. {
  68. get => _hasProperties;
  69. set
  70. {
  71. _hasProperties = value;
  72. OnPropertyChanged();
  73. }
  74. }
  75. private bool _hasType;
  76. public bool HasType
  77. {
  78. get => _hasType;
  79. set
  80. {
  81. _hasType = value;
  82. OnPropertyChanged();
  83. }
  84. }
  85. private Type? EventDataType;
  86. private Type? DataModelType;
  87. private IEventEditorControl? _eventEditorControl;
  88. private bool _changed;
  89. public bool Changed
  90. {
  91. get => _changed;
  92. set
  93. {
  94. _changed = value;
  95. OnPropertyChanged();
  96. }
  97. }
  98. public IEventData? Data
  99. {
  100. get => _eventEditorControl?.Data;
  101. set
  102. {
  103. OnPropertyChanged();
  104. if(value is not null && EventType.HasValue)
  105. {
  106. if(EventDataType is null || DataModelType is null)
  107. {
  108. var inter = value.GetType().GetSuperclassDefinition(typeof(EventData<,>))!;
  109. EventDataType = inter.GenericTypeArguments[0];
  110. DataModelType = inter.GenericTypeArguments[1];
  111. if (EventTypeGetEntityType(EventType.Value, EventDataType) is Type entityType)
  112. {
  113. EntityType = entityType;
  114. }
  115. }
  116. var control = Activator.CreateInstance(typeof(EventEditorControl<,>).MakeGenericType(EventDataType, DataModelType), value);
  117. _eventEditorControl = (control as IEventEditorControl)!;
  118. _eventEditorControl.OnChanged += DoChanged;
  119. Content.Content = control;
  120. Content.Visibility = Visibility.Visible;
  121. Placeholder.Visibility = Visibility.Collapsed;
  122. }
  123. else
  124. {
  125. _eventEditorControl = null;
  126. Content.Content = null;
  127. Content.Visibility = Visibility.Collapsed;
  128. Placeholder.Visibility = Visibility.Visible;
  129. }
  130. DoChanged();
  131. }
  132. }
  133. public EventEditor()
  134. {
  135. InitializeComponent();
  136. EventTypeBox.ItemsSource = Enum.GetValues<EventType>();
  137. var entities = CoreUtils.Entities.Where(x => !x.IsGenericType && x.IsSubclassOf(typeof(Entity))).ToArray();
  138. entities.SortBy(x => x.Name);
  139. EntityTypeBox.ItemsSource = entities;
  140. }
  141. private void DoChanged()
  142. {
  143. Changed = true;
  144. }
  145. private bool EventTypeHasEntityType(EventType eventType)
  146. {
  147. return EventUtils.GetEventType(eventType).HasInterface(typeof(IEntityEvent<>));
  148. }
  149. private Type? EventTypeGetEntityType(EventType eventType, Type eventDataType)
  150. {
  151. var evType = EventUtils.GetEventType(eventType);
  152. var entType = evType?.GetInterfaceDefinition(typeof(IEntityEvent<>))?.GenericTypeArguments[0];
  153. if (evType is null || entType is null) return null;
  154. var idx = Array.IndexOf(evType.GetGenericArguments(), entType);
  155. return eventDataType.GenericTypeArguments[idx];
  156. }
  157. private void UpdateEventData()
  158. {
  159. if (EventType is null || (EventTypeHasEntityType(EventType.Value) && EntityType is null))
  160. {
  161. Data = null;
  162. HasProperties = false;
  163. return;
  164. }
  165. Type dataModelType;
  166. var eventType = EventUtils.GetEventType(EventType.Value);
  167. if (eventType.IsGenericTypeDefinition)
  168. {
  169. if(!eventType.BuildGenericType()
  170. .AddInterface(typeof(IEntityEvent<>), EntityType!)
  171. .TryBuild(out eventType))
  172. {
  173. Data = null;
  174. HasProperties = false;
  175. return;
  176. }
  177. }
  178. dataModelType = eventType.GetInterfaceDefinition(typeof(IEvent<>))!.GenericTypeArguments[0];
  179. HasProperties = eventType.HasInterface(typeof(IPropertiesEvent<>));
  180. var ev = Activator.CreateInstance(eventType);
  181. EventDataType = eventType;
  182. DataModelType = dataModelType;
  183. Data = (Activator.CreateInstance(typeof(EventData<,>).MakeGenericType(eventType, dataModelType), ev) as IEventData)!;
  184. }
  185. private void EditButton_Click(object sender, RoutedEventArgs e)
  186. {
  187. if (EventDataType is null || EventDataType.GetInterfaceDefinition(typeof(IPropertiesEvent<>)) is not Type propertiesInterface) return;
  188. var method = GetType().GetMethod(nameof(EditProperties), BindingFlags.Instance | BindingFlags.NonPublic)!
  189. .MakeGenericMethod(propertiesInterface.GenericTypeArguments[0]);
  190. method.Invoke(this, []);
  191. }
  192. private void EditProperties<TProperties>() where TProperties : BaseObject, new()
  193. {
  194. if (Data?.Event is not IPropertiesEvent<TProperties> propertiesEvent) return;
  195. var props = propertiesEvent.GetProperties();
  196. if (DynamicGridUtils.EditEntity(props))
  197. {
  198. propertiesEvent.SetProperties(props);
  199. DoChanged();
  200. }
  201. }
  202. public static bool Run(ref EventType evType, ref IEventData? eventData)
  203. {
  204. var editor = new EventEditor();
  205. editor.EventType = evType;
  206. if(eventData is not null)
  207. {
  208. editor.Data = eventData;
  209. }
  210. editor.Changed = false;
  211. var dialog = new DynamicContentDialog(editor)
  212. {
  213. SizeToContent = SizeToContent.Height,
  214. Title = "Edit Event"
  215. };
  216. dialog.Bind(DynamicContentDialog.CanSaveProperty, editor, x => x.Changed);
  217. if(dialog.ShowDialog() == true)
  218. {
  219. eventData = editor.Data;
  220. evType = editor.EventType ?? default;
  221. return true;
  222. }
  223. else
  224. {
  225. return false;
  226. }
  227. }
  228. }