[NUI] Adjust directory (#903)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / XamlBinding / Interactivity / EventTrigger.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Linq;
5 using System.Reflection;
6 using Tizen.NUI.Binding.Internals;
7
8 namespace Tizen.NUI.Binding
9 {
10     /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
11     [EditorBrowsable(EditorBrowsableState.Never)]
12     [ContentProperty("Actions")]
13     public sealed class EventTrigger : TriggerBase
14     {
15         static readonly MethodInfo s_handlerinfo = typeof(EventTrigger).GetRuntimeMethods().Single(mi => mi.Name == "OnEventTriggered" && mi.IsPublic == false);
16         readonly List<BindableObject> _associatedObjects = new List<BindableObject>();
17
18         EventInfo _eventinfo;
19
20         string _eventname;
21         Delegate _handlerdelegate;
22
23         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
24         [EditorBrowsable(EditorBrowsableState.Never)]
25         public EventTrigger() : base(typeof(BindableObject))
26         {
27             Actions = new SealedList<TriggerAction>();
28         }
29
30         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
31         [EditorBrowsable(EditorBrowsableState.Never)]
32         public IList<TriggerAction> Actions { get; }
33
34         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
35         [EditorBrowsable(EditorBrowsableState.Never)]
36         public string Event
37         {
38             get { return _eventname; }
39             set
40             {
41                 if (_eventname == value)
42                     return;
43                 if (IsSealed)
44                     throw new InvalidOperationException("Event cannot be changed once the Trigger has been applied");
45                 OnPropertyChanging();
46                 _eventname = value;
47                 OnPropertyChanged();
48             }
49         }
50
51         internal override void OnAttachedTo(BindableObject bindable)
52         {
53             base.OnAttachedTo(bindable);
54             if (!string.IsNullOrEmpty(Event))
55                 AttachHandlerTo(bindable);
56             _associatedObjects.Add(bindable);
57         }
58
59         internal override void OnDetachingFrom(BindableObject bindable)
60         {
61             _associatedObjects.Remove(bindable);
62             DetachHandlerFrom(bindable);
63             base.OnDetachingFrom(bindable);
64         }
65
66         internal override void OnSeal()
67         {
68             base.OnSeal();
69             ((SealedList<TriggerAction>)Actions).IsReadOnly = true;
70         }
71
72         void AttachHandlerTo(BindableObject bindable)
73         {
74             try
75             {
76                 _eventinfo = bindable.GetType().GetRuntimeEvent(Event);
77                 _handlerdelegate = s_handlerinfo.CreateDelegate(_eventinfo?.EventHandlerType, this);
78             }
79             catch (Exception)
80             {
81                 Console.WriteLine("EventTrigger", "Can not attach EventTrigger to {0}.{1}. Check if the handler exists and if the signature is right.", bindable.GetType(), Event);
82             }
83             if (_eventinfo != null && _handlerdelegate != null)
84                 _eventinfo.AddEventHandler(bindable, _handlerdelegate);
85         }
86
87         void DetachHandlerFrom(BindableObject bindable)
88         {
89             if (_eventinfo != null && _handlerdelegate != null)
90                 _eventinfo.RemoveEventHandler(bindable, _handlerdelegate);
91         }
92
93         // [Preserve]
94         void OnEventTriggered(object sender, EventArgs e)
95         {
96             var bindable = (BindableObject)sender;
97             foreach (TriggerAction action in Actions)
98                 action.DoInvoke(bindable);
99         }
100     }
101 }