[NUI] Add DispatchParentTouchEvent
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / BaseComponents / ViewEvent.cs
1 /*
2  * Copyright(c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 using System;
19 using System.ComponentModel;
20 using System.Runtime.InteropServices;
21
22 namespace Tizen.NUI.BaseComponents
23 {
24     /// <summary>
25     /// View is the base class for all views.
26     /// </summary>
27     /// <since_tizen> 3 </since_tizen>
28     public partial class View
29     {
30         private EventHandler offWindowEventHandler;
31         private OffWindowEventCallbackType offWindowEventCallback;
32         private EventHandlerWithReturnType<object, WheelEventArgs, bool> wheelEventHandler;
33         private WheelEventCallbackType wheelEventCallback;
34         private EventHandlerWithReturnType<object, KeyEventArgs, bool> keyEventHandler;
35         private KeyCallbackType keyCallback;
36         private EventHandlerWithReturnType<object, TouchEventArgs, bool> interceptTouchDataEventHandler;
37         private TouchDataCallbackType interceptTouchDataCallback;
38         private EventHandlerWithReturnType<object, TouchEventArgs, bool> touchDataEventHandler;
39         private TouchDataCallbackType touchDataCallback;
40         private EventHandlerWithReturnType<object, HoverEventArgs, bool> hoverEventHandler;
41         private HoverEventCallbackType hoverEventCallback;
42         private EventHandler<VisibilityChangedEventArgs> visibilityChangedEventHandler;
43         private VisibilityChangedEventCallbackType visibilityChangedEventCallback;
44         private EventHandler keyInputFocusGainedEventHandler;
45
46         private KeyInputFocusGainedCallbackType keyInputFocusGainedCallback;
47         private EventHandler keyInputFocusLostEventHandler;
48
49         private KeyInputFocusLostCallbackType keyInputFocusLostCallback;
50         private EventHandler onRelayoutEventHandler;
51         private OnRelayoutEventCallbackType onRelayoutEventCallback;
52         private EventHandler onWindowEventHandler;
53         private OnWindowEventCallbackType onWindowEventCallback;
54         private EventHandler<LayoutDirectionChangedEventArgs> layoutDirectionChangedEventHandler;
55         private LayoutDirectionChangedEventCallbackType layoutDirectionChangedEventCallback;
56         // Resource Ready Signal
57         private EventHandler resourcesLoadedEventHandler;
58         private ResourcesLoadedCallbackType resourcesLoadedCallback;
59         private EventHandler<BackgroundResourceLoadedEventArgs> backgroundResourceLoadedEventHandler;
60         private _backgroundResourceLoadedCallbackType backgroundResourceLoadedCallback;
61         private TouchDataCallbackType hitTestResultDataCallback;
62
63         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
64         private delegate void OffWindowEventCallbackType(IntPtr control);
65         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
66         private delegate bool WheelEventCallbackType(IntPtr view, IntPtr wheelEvent);
67         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
68         private delegate bool KeyCallbackType(IntPtr control, IntPtr keyEvent);
69         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
70         private delegate bool TouchDataCallbackType(IntPtr view, IntPtr touchData);
71         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
72         private delegate bool HoverEventCallbackType(IntPtr view, IntPtr hoverEvent);
73         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
74         private delegate void VisibilityChangedEventCallbackType(IntPtr data, bool visibility, VisibilityChangeType type);
75         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
76         private delegate void ResourcesLoadedCallbackType(IntPtr control);
77         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
78         private delegate void _backgroundResourceLoadedCallbackType(IntPtr view);
79
80         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
81         private delegate void KeyInputFocusGainedCallbackType(IntPtr control);
82         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
83         private delegate void KeyInputFocusLostCallbackType(IntPtr control);
84
85         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
86         private delegate void OnRelayoutEventCallbackType(IntPtr control);
87         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
88         private delegate void OnWindowEventCallbackType(IntPtr control);
89         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
90         private delegate void LayoutDirectionChangedEventCallbackType(IntPtr data, ViewLayoutDirectionType type);
91
92         /// <summary>
93         /// Event when a child is removed.
94         /// </summary>
95         /// <since_tizen> 5 </since_tizen>
96         public new event EventHandler<ChildRemovedEventArgs> ChildRemoved;
97         /// <summary>
98         /// Event when a child is added.
99         /// </summary>
100         /// <since_tizen> 5 </since_tizen>
101         public new event EventHandler<ChildAddedEventArgs> ChildAdded;
102
103         /// <summary>
104         /// An event for the KeyInputFocusGained signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
105         /// The KeyInputFocusGained signal is emitted when the control gets the key input focus.<br />
106         /// </summary>
107         /// <since_tizen> 3 </since_tizen>
108         public event EventHandler FocusGained
109         {
110             add
111             {
112                 if (keyInputFocusGainedEventHandler == null)
113                 {
114                     keyInputFocusGainedCallback = OnKeyInputFocusGained;
115                     Interop.ViewSignal.KeyInputFocusGainedConnect(SwigCPtr, keyInputFocusGainedCallback.ToHandleRef(this));
116                     NDalicPINVOKE.ThrowExceptionIfExists();
117                 }
118                 keyInputFocusGainedEventHandler += value;
119             }
120
121             remove
122             {
123                 keyInputFocusGainedEventHandler -= value;
124                 if (keyInputFocusGainedEventHandler == null && keyInputFocusGainedCallback != null)
125                 {
126                     Interop.ViewSignal.KeyInputFocusGainedDisconnect(SwigCPtr, keyInputFocusGainedCallback.ToHandleRef(this));
127                     NDalicPINVOKE.ThrowExceptionIfExists();
128                     keyInputFocusGainedCallback = null;
129                 }
130             }
131         }
132
133         /// <summary>
134         /// An event for the KeyInputFocusLost signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
135         /// The KeyInputFocusLost signal is emitted when the control loses the key input focus.<br />
136         /// </summary>
137         /// <since_tizen> 3 </since_tizen>
138         public event EventHandler FocusLost
139         {
140             add
141             {
142                 if (keyInputFocusLostEventHandler == null)
143                 {
144                     keyInputFocusLostCallback = OnKeyInputFocusLost;
145                     Interop.ViewSignal.KeyInputFocusLostConnect(SwigCPtr, keyInputFocusLostCallback.ToHandleRef(this));
146                     NDalicPINVOKE.ThrowExceptionIfExists();
147                 }
148                 keyInputFocusLostEventHandler += value;
149             }
150
151             remove
152             {
153                 keyInputFocusLostEventHandler -= value;
154                 if (keyInputFocusLostEventHandler == null && keyInputFocusLostCallback != null)
155                 {
156                     Interop.ViewSignal.KeyInputFocusLostDisconnect(SwigCPtr, keyInputFocusLostCallback.ToHandleRef(this));
157                     NDalicPINVOKE.ThrowExceptionIfExists();
158                     keyInputFocusLostCallback = null;
159                 }
160             }
161         }
162
163         /// <summary>
164         /// An event for the KeyPressed signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
165         /// The KeyPressed signal is emitted when the key event is received.<br />
166         /// </summary>
167         /// <since_tizen> 3 </since_tizen>
168         public event EventHandlerWithReturnType<object, KeyEventArgs, bool> KeyEvent
169         {
170             add
171             {
172                 if (keyEventHandler == null)
173                 {
174                     keyCallback = OnKeyEvent;
175                     Interop.ViewSignal.KeyEventConnect(SwigCPtr, keyCallback.ToHandleRef(this));
176                     NDalicPINVOKE.ThrowExceptionIfExists();
177                 }
178                 keyEventHandler += value;
179             }
180
181             remove
182             {
183                 keyEventHandler -= value;
184                 if (keyEventHandler == null && keyCallback != null)
185                 {
186                     Interop.ViewSignal.KeyEventDisconnect(SwigCPtr, keyCallback.ToHandleRef(this));
187                     NDalicPINVOKE.ThrowExceptionIfExists();
188                     keyCallback = null;
189                 }
190             }
191         }
192
193         /// <summary>
194         /// An event for the OnRelayout signal which can be used to subscribe or unsubscribe the event handler.<br />
195         /// The OnRelayout signal is emitted after the size has been set on the view during relayout.<br />
196         /// </summary>
197         /// <since_tizen> 3 </since_tizen>
198         public event EventHandler Relayout
199         {
200             add
201             {
202                 if (onRelayoutEventHandler == null)
203                 {
204                     onRelayoutEventCallback = OnRelayout;
205                     Interop.ActorSignal.OnRelayoutConnect(SwigCPtr, onRelayoutEventCallback.ToHandleRef(this));
206                     NDalicPINVOKE.ThrowExceptionIfExists();
207                 }
208                 onRelayoutEventHandler += value;
209             }
210
211             remove
212             {
213                 onRelayoutEventHandler -= value;
214                 if (onRelayoutEventHandler == null && onRelayoutEventCallback != null)
215                 {
216                     Interop.ActorSignal.OnRelayoutDisconnect(SwigCPtr, onRelayoutEventCallback.ToHandleRef(this));
217                     NDalicPINVOKE.ThrowExceptionIfExists();
218                     onRelayoutEventCallback = null;
219                 }
220             }
221         }
222
223         /// <summary>
224         /// An event for the touched signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
225         /// The touched signal is emitted when the touch input is received.<br />
226         /// This can receive touch events before child. <br />
227         /// If it returns false, the child can receive the touch event. If it returns true, the touch event is intercepted. So child cannot receive touch event.<br />
228         /// </summary>
229         [EditorBrowsable(EditorBrowsableState.Never)]
230         public event EventHandlerWithReturnType<object, TouchEventArgs, bool> InterceptTouchEvent
231         {
232             add
233             {
234                 if (interceptTouchDataEventHandler == null)
235                 {
236                     interceptTouchDataCallback = OnInterceptTouch;
237                     Interop.ActorSignal.InterceptTouchConnect(SwigCPtr, interceptTouchDataCallback.ToHandleRef(this));
238                     NDalicPINVOKE.ThrowExceptionIfExists();
239                 }
240                 interceptTouchDataEventHandler += value;
241             }
242
243             remove
244             {
245                 interceptTouchDataEventHandler -= value;
246                 if (interceptTouchDataEventHandler == null && interceptTouchDataCallback != null)
247                 {
248                     Interop.ActorSignal.InterceptTouchDisconnect(SwigCPtr, interceptTouchDataCallback.ToHandleRef(this));
249                     NDalicPINVOKE.ThrowExceptionIfExists();
250                     interceptTouchDataCallback = null;
251                 }
252             }
253         }
254
255         /// <summary>
256         /// If child view doesn't want the parent's view to intercept the touch, you can set it to true.
257         /// for example :
258         ///    parent.Add(child);
259         ///    parent.InterceptTouchEvent += OnInterceptTouchEvent;
260         ///    View view = child.GetParent() as View;
261         ///    view.DisallowInterceptTouchEvent = true;
262         ///  This prevents the parent from intercepting touch.
263         /// </summary>
264         [EditorBrowsable(EditorBrowsableState.Never)]
265         public bool DisallowInterceptTouchEvent { get; set; }
266
267
268         /// <summary>
269         /// An event for the touched signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
270         /// The touched signal is emitted when the touch input is received.<br />
271         /// </summary>
272         /// <since_tizen> 3 </since_tizen>
273         public event EventHandlerWithReturnType<object, TouchEventArgs, bool> TouchEvent
274         {
275             add
276             {
277                 if (touchDataEventHandler == null)
278                 {
279                     touchDataCallback = OnTouch;
280                     Interop.ActorSignal.TouchConnect(SwigCPtr, touchDataCallback.ToHandleRef(this));
281                     NDalicPINVOKE.ThrowExceptionIfExists();
282                 }
283                 touchDataEventHandler += value;
284             }
285
286             remove
287             {
288                 touchDataEventHandler -= value;
289                 if (touchDataEventHandler == null && touchDataCallback != null)
290                 {
291                     Interop.ActorSignal.TouchDisconnect(SwigCPtr, touchDataCallback.ToHandleRef(this));
292                     NDalicPINVOKE.ThrowExceptionIfExists();
293                     touchDataCallback = null;
294                 }
295             }
296         }
297
298         /// <summary>
299         /// An event for the hovered signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
300         /// The hovered signal is emitted when the hover input is received.<br />
301         /// </summary>
302         /// <since_tizen> 3 </since_tizen>
303         public event EventHandlerWithReturnType<object, HoverEventArgs, bool> HoverEvent
304         {
305             add
306             {
307                 if (hoverEventHandler == null)
308                 {
309                     hoverEventCallback = OnHoverEvent;
310                     Interop.ActorSignal.HoveredConnect(SwigCPtr, hoverEventCallback.ToHandleRef(this));
311                     NDalicPINVOKE.ThrowExceptionIfExists();
312                 }
313                 hoverEventHandler += value;
314             }
315
316             remove
317             {
318                 hoverEventHandler -= value;
319                 if (hoverEventHandler == null && hoverEventCallback != null)
320                 {
321                     Interop.ActorSignal.HoveredDisconnect(SwigCPtr, hoverEventCallback.ToHandleRef(this));
322                     NDalicPINVOKE.ThrowExceptionIfExists();
323                     hoverEventCallback = null;
324                 }
325             }
326         }
327
328         /// <summary>
329         /// An event for the WheelMoved signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
330         /// The WheelMoved signal is emitted when the wheel event is received.<br />
331         /// </summary>
332         /// <since_tizen> 3 </since_tizen>
333         public event EventHandlerWithReturnType<object, WheelEventArgs, bool> WheelEvent
334         {
335             add
336             {
337                 if (wheelEventHandler == null)
338                 {
339                     wheelEventCallback = OnWheelEvent;
340                     Interop.ActorSignal.WheelEventConnect(SwigCPtr, wheelEventCallback.ToHandleRef(this));
341                     NDalicPINVOKE.ThrowExceptionIfExists();
342                 }
343                 wheelEventHandler += value;
344             }
345
346             remove
347             {
348                 wheelEventHandler -= value;
349                 if (wheelEventHandler == null && wheelEventCallback != null)
350                 {
351                     Interop.ActorSignal.WheelEventDisconnect(SwigCPtr, wheelEventCallback.ToHandleRef(this));
352                     NDalicPINVOKE.ThrowExceptionIfExists();
353                     wheelEventCallback = null;
354                 }
355             }
356         }
357
358         /// <summary>
359         /// An event for the OnWindow signal which can be used to subscribe or unsubscribe the event handler.<br />
360         /// The OnWindow signal is emitted after the view has been connected to the window.<br />
361         /// </summary>
362         /// <since_tizen> 3 </since_tizen>
363         public event EventHandler AddedToWindow
364         {
365             add
366             {
367                 if (onWindowEventHandler == null)
368                 {
369                     onWindowEventCallback = OnWindow;
370                     Interop.ActorSignal.OnSceneConnect(SwigCPtr, onWindowEventCallback.ToHandleRef(this));
371                     NDalicPINVOKE.ThrowExceptionIfExists();
372                 }
373                 onWindowEventHandler += value;
374             }
375
376             remove
377             {
378                 onWindowEventHandler -= value;
379                 if (onWindowEventHandler == null && onWindowEventCallback != null)
380                 {
381                     Interop.ActorSignal.OnSceneDisconnect(SwigCPtr, onWindowEventCallback.ToHandleRef(this));
382                     NDalicPINVOKE.ThrowExceptionIfExists();
383                     onWindowEventCallback = null;
384                 }
385             }
386         }
387
388         /// <summary>
389         /// An event for the OffWindow signal, which can be used to subscribe or unsubscribe the event handler.<br />
390         /// OffWindow signal is emitted after the view has been disconnected from the window.<br />
391         /// </summary>
392         /// <since_tizen> 3 </since_tizen>
393         public event EventHandler RemovedFromWindow
394         {
395             add
396             {
397                 if (offWindowEventHandler == null)
398                 {
399                     offWindowEventCallback = OffWindow;
400                     Interop.ActorSignal.OffSceneConnect(SwigCPtr, offWindowEventCallback.ToHandleRef(this));
401                     NDalicPINVOKE.ThrowExceptionIfExists();
402                 }
403                 offWindowEventHandler += value;
404             }
405
406             remove
407             {
408                 offWindowEventHandler -= value;
409                 if (offWindowEventHandler == null && offWindowEventCallback != null)
410                 {
411                     Interop.ActorSignal.OffSceneDisconnect(SwigCPtr, offWindowEventCallback.ToHandleRef(this));
412                     NDalicPINVOKE.ThrowExceptionIfExists();
413                     offWindowEventCallback = null;
414                 }
415             }
416         }
417
418         /// <summary>
419         /// An event for visibility change which can be used to subscribe or unsubscribe the event handler.<br />
420         /// This signal is emitted when the visible property of this or a parent view is changed.<br />
421         /// </summary>
422         /// <since_tizen> 3 </since_tizen>
423         public event EventHandler<VisibilityChangedEventArgs> VisibilityChanged
424         {
425             add
426             {
427                 if (visibilityChangedEventHandler == null)
428                 {
429                     visibilityChangedEventCallback = OnVisibilityChanged;
430                     Interop.ActorSignal.VisibilityChangedConnect(SwigCPtr, visibilityChangedEventCallback.ToHandleRef(this));
431                     NDalicPINVOKE.ThrowExceptionIfExists();
432                 }
433                 visibilityChangedEventHandler += value;
434             }
435
436             remove
437             {
438                 visibilityChangedEventHandler -= value;
439                 if (visibilityChangedEventHandler == null && visibilityChangedEventCallback != null)
440                 {
441                     Interop.ActorSignal.VisibilityChangedDisconnect(SwigCPtr, visibilityChangedEventCallback.ToHandleRef(this));
442                     NDalicPINVOKE.ThrowExceptionIfExists();
443                     visibilityChangedEventCallback = null;
444                 }
445             }
446         }
447
448         /// <summary>
449         /// Event for layout direction change which can be used to subscribe/unsubscribe the event handler.<br />
450         /// This signal is emitted when the layout direction property of this or a parent view is changed.<br />
451         /// </summary>
452         /// <since_tizen> 4 </since_tizen>
453         public event EventHandler<LayoutDirectionChangedEventArgs> LayoutDirectionChanged
454         {
455             add
456             {
457                 if (layoutDirectionChangedEventHandler == null)
458                 {
459                     layoutDirectionChangedEventCallback = OnLayoutDirectionChanged;
460                     Interop.ActorSignal.LayoutDirectionChangedConnect(SwigCPtr, layoutDirectionChangedEventCallback.ToHandleRef(this));
461                     NDalicPINVOKE.ThrowExceptionIfExists();
462                 }
463
464                 layoutDirectionChangedEventHandler += value;
465             }
466
467             remove
468             {
469                 layoutDirectionChangedEventHandler -= value;
470
471                 if (layoutDirectionChangedEventHandler == null && layoutDirectionChangedEventCallback != null)
472                 {
473                     Interop.ActorSignal.LayoutDirectionChangedDisconnect(SwigCPtr, layoutDirectionChangedEventCallback.ToHandleRef(this));
474                     NDalicPINVOKE.ThrowExceptionIfExists();
475                     layoutDirectionChangedEventCallback = null;
476                 }
477             }
478         }
479
480         /// <summary>
481         /// An event for the ResourcesLoadedSignal signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
482         /// This signal is emitted after all resources required by a view are loaded and ready.<br />
483         /// </summary>
484         /// <since_tizen> 3 </since_tizen>
485         public event EventHandler ResourcesLoaded
486         {
487             add
488             {
489                 if (resourcesLoadedEventHandler == null)
490                 {
491                     resourcesLoadedCallback = OnResourcesLoaded;
492                     Interop.ViewSignal.ResourceReadyConnect(SwigCPtr, resourcesLoadedCallback.ToHandleRef(this));
493                     NDalicPINVOKE.ThrowExceptionIfExists();
494                 }
495                 resourcesLoadedEventHandler += value;
496             }
497
498             remove
499             {
500                 resourcesLoadedEventHandler -= value;
501                 if (resourcesLoadedEventHandler == null && resourcesLoadedCallback != null)
502                 {
503                     Interop.ViewSignal.ResourceReadyDisconnect(SwigCPtr, resourcesLoadedCallback.ToHandleRef(this));
504                     NDalicPINVOKE.ThrowExceptionIfExists();
505                     resourcesLoadedCallback = null;
506                 }
507             }
508         }
509
510         private EventHandler _backKeyPressed;
511
512         /// <summary>
513         /// An event for getting notice when physical back key is pressed.<br />
514         /// This event is emitted BackKey is up.<br />
515         /// </summary>
516         [EditorBrowsable(EditorBrowsableState.Never)]
517         public event EventHandler BackKeyPressed
518         {
519             add
520             {
521                 _backKeyPressed += value;
522                 BackKeyManager.Instance.Subscriber.Add(this);
523             }
524
525             remove
526             {
527                 BackKeyManager.Instance.Subscriber.Remove(this);
528                 _backKeyPressed -= value;
529             }
530         }
531
532         /// <summary>
533         /// Function for emitting BackKeyPressed event outside of View instance
534         /// </summary>
535         [EditorBrowsable(EditorBrowsableState.Never)]
536         internal void EmitBackKeyPressed()
537         {
538             _backKeyPressed.Invoke(this, null);
539         }
540
541
542         internal event EventHandler<BackgroundResourceLoadedEventArgs> BackgroundResourceLoaded
543         {
544             add
545             {
546                 if (backgroundResourceLoadedEventHandler == null)
547                 {
548                     backgroundResourceLoadedCallback = OnBackgroundResourceLoaded;
549                     Interop.ViewSignal.ResourceReadyConnect(SwigCPtr, backgroundResourceLoadedCallback.ToHandleRef(this));
550                     NDalicPINVOKE.ThrowExceptionIfExists();
551                 }
552                 backgroundResourceLoadedEventHandler += value;
553             }
554
555             remove
556             {
557                 backgroundResourceLoadedEventHandler -= value;
558                 if (backgroundResourceLoadedEventHandler == null && backgroundResourceLoadedCallback != null)
559                 {
560                     Interop.ViewSignal.ResourceReadyDisconnect(SwigCPtr, backgroundResourceLoadedCallback.ToHandleRef(this));
561                     NDalicPINVOKE.ThrowExceptionIfExists();
562                     backgroundResourceLoadedCallback = null;
563                 }
564             }
565         }
566
567         private void OnColorChanged(float r, float g, float b, float a)
568         {
569             Color = new Color(r, g, b, a);
570         }
571
572         private void OnMinimumSizeChanged(int width, int height)
573         {
574             MinimumSize = new Size2D(width, height);
575         }
576
577         private void OnMaximumSizeChanged(int width, int height)
578         {
579             MaximumSize = new Size2D(width, height);
580         }
581
582         private void OnPosition2DChanged(int x, int y)
583         {
584             SetPosition((float)x, (float)y, 0);
585         }
586
587         private void OnPositionChanged(float x, float y, float z)
588         {
589             SetPosition(x, y, z);
590         }
591
592         private void OnSize2DChanged(int width, int height)
593         {
594             SetSize((float)width, (float)height, 0);
595         }
596
597         private void OnSizeChanged(float width, float height, float depth)
598         {
599             SetSize(width, height, depth);
600         }
601
602         private void OnParentOriginChanged(float x, float y, float z)
603         {
604             ParentOrigin = new Position(x, y, z);
605         }
606
607         private void OnPivotPointChanged(float x, float y, float z)
608         {
609             PivotPoint = new Position(x, y, z);
610         }
611
612         private void OnImageShadowChanged(ShadowBase instance)
613         {
614             ImageShadow = (ImageShadow)instance;
615         }
616
617         private void OnBoxShadowChanged(ShadowBase instance)
618         {
619             BoxShadow = (Shadow)instance;
620         }
621
622         private void OnBackgroundImageBorderChanged(int left, int right, int bottom, int top)
623         {
624             BackgroundImageBorder = new Rectangle(left, right, bottom, top);
625         }
626
627         private void OnKeyInputFocusGained(IntPtr view)
628         {
629             if (IsNativeHandleInvalid())
630             {
631                 if (this.Disposed)
632                 {
633                     if (keyInputFocusGainedEventHandler != null)
634                     {
635                         var process = global::System.Diagnostics.Process.GetCurrentProcess().Id;
636                         var thread = global::System.Threading.Thread.CurrentThread.ManagedThreadId;
637                         var me = this.GetType().FullName;
638
639                         throw new ObjectDisposedException(nameof(SwigCPtr), $"Error! NUI's native dali object is already disposed. " +
640                             $"OR the native dali object handle of NUI becomes null! \n" +
641                             $" process:{process} thread:{thread}, isDisposed:{this.Disposed}, isDisposeQueued:{this.IsDisposeQueued}, me:{me}\n");
642                     }
643                 }
644                 else
645                 {
646                     if (this.IsDisposeQueued)
647                     {
648                         var process = global::System.Diagnostics.Process.GetCurrentProcess().Id;
649                         var thread = global::System.Threading.Thread.CurrentThread.ManagedThreadId;
650                         var me = this.GetType().FullName;
651
652                         //in this case, the View object is ready to be disposed waiting on DisposeQueue, so event callback should not be invoked!
653                         Tizen.Log.Error("NUI", "in this case, the View object is ready to be disposed waiting on DisposeQueue, so event callback should not be invoked! just return here! \n" +
654                             $"process:{process} thread:{thread}, isDisposed:{this.Disposed}, isDisposeQueued:{this.IsDisposeQueued}, me:{me}\n");
655                         return;
656                     }
657                 }
658             }
659
660             keyInputFocusGainedEventHandler?.Invoke(this, null);
661         }
662
663         private void OnKeyInputFocusLost(IntPtr view)
664         {
665             if (IsNativeHandleInvalid())
666             {
667                 if (this.Disposed)
668                 {
669                     if (keyInputFocusLostEventHandler != null)
670                     {
671                         var process = global::System.Diagnostics.Process.GetCurrentProcess().Id;
672                         var thread = global::System.Threading.Thread.CurrentThread.ManagedThreadId;
673                         var me = this.GetType().FullName;
674
675                         throw new ObjectDisposedException(nameof(SwigCPtr), $"Error! NUI's native dali object is already disposed. " +
676                             $"OR the native dali object handle of NUI becomes null! \n" +
677                             $" process:{process} thread:{thread}, isDisposed:{this.Disposed}, isDisposeQueued:{this.IsDisposeQueued}, me:{me}\n");
678                     }
679                 }
680                 else
681                 {
682                     if (this.IsDisposeQueued)
683                     {
684                         var process = global::System.Diagnostics.Process.GetCurrentProcess().Id;
685                         var thread = global::System.Threading.Thread.CurrentThread.ManagedThreadId;
686                         var me = this.GetType().FullName;
687
688                         //in this case, the View object is ready to be disposed waiting on DisposeQueue, so event callback should not be invoked!
689                         Tizen.Log.Error("NUI", "in this case, the View object is ready to be disposed waiting on DisposeQueue, so event callback should not be invoked! just return here! \n" +
690                             $"process:{process} thread:{thread}, isDisposed:{this.Disposed}, isDisposeQueued:{this.IsDisposeQueued}, me:{me}\n");
691                         return;
692                     }
693                 }
694             }
695
696             keyInputFocusLostEventHandler?.Invoke(this, null);
697         }
698
699         private bool OnKeyEvent(IntPtr view, IntPtr keyEvent)
700         {
701             if (keyEvent == global::System.IntPtr.Zero)
702             {
703                 NUILog.Error("keyEvent should not be null!");
704                 return true;
705             }
706
707             KeyEventArgs e = new KeyEventArgs();
708
709             bool result = false;
710
711             e.Key = Tizen.NUI.Key.GetKeyFromPtr(keyEvent);
712
713             if (keyEventHandler != null)
714             {
715                 Delegate[] delegateList = keyEventHandler.GetInvocationList();
716
717                 // Oring the result of each callback.
718                 foreach (EventHandlerWithReturnType<object, KeyEventArgs, bool> del in delegateList)
719                 {
720                     result |= del(this, e);
721                 }
722             }
723
724             return result;
725         }
726
727         // Callback for View OnRelayout signal
728         private void OnRelayout(IntPtr data)
729         {
730             if (onRelayoutEventHandler != null)
731             {
732                 onRelayoutEventHandler(this, null);
733             }
734         }
735
736         // Callback for View HitTestResultSignal
737         private bool OnHitTestResult(IntPtr view, IntPtr touchData)
738         {
739             if (touchData == global::System.IntPtr.Zero)
740             {
741                 NUILog.Error("touchData should not be null!");
742                 return true;
743             }
744
745             TouchEventArgs e = new TouchEventArgs();
746             e.Touch = Tizen.NUI.Touch.GetTouchFromPtr(touchData);
747             return HitTest(e.Touch);
748         }
749
750         // Callback for View TouchSignal
751         private bool OnInterceptTouch(IntPtr view, IntPtr touchData)
752         {
753             if (touchData == global::System.IntPtr.Zero)
754             {
755                 NUILog.Error("touchData should not be null!");
756                 return true;
757             }
758
759             // DisallowInterceptTouchEvent prevents the parent from intercepting touch.
760             if (DisallowInterceptTouchEvent)
761             {
762                 return false;
763             }
764
765             TouchEventArgs e = new TouchEventArgs();
766
767             e.Touch = Tizen.NUI.Touch.GetTouchFromPtr(touchData);
768
769             bool consumed = false;
770
771             if (interceptTouchDataEventHandler != null)
772             {
773                 consumed = interceptTouchDataEventHandler(this, e);
774             }
775
776             return consumed;
777         }
778
779         // Callback for View TouchSignal
780         private bool OnTouch(IntPtr view, IntPtr touchData)
781         {
782             if (touchData == global::System.IntPtr.Zero)
783             {
784                 NUILog.Error("touchData should not be null!");
785                 return true;
786             }
787
788             if (DispatchTouchEvents == false)
789             {
790                 NUILog.Debug("If DispatchTouchEvents is false, it can not dispatch.");
791                 return true;
792             }
793
794             TouchEventArgs e = new TouchEventArgs();
795
796             e.Touch = Tizen.NUI.Touch.GetTouchFromPtr(touchData);
797
798             bool consumed = false;
799
800             if (touchDataEventHandler != null)
801             {
802                 consumed = touchDataEventHandler(this, e);
803             }
804
805             if (enableControlState && !consumed)
806             {
807                 consumed = HandleControlStateOnTouch(e.Touch);
808             }
809
810             if (DispatchParentTouchEvents == false)
811             {
812                 NUILog.Debug("If DispatchParentTouchEvents is false, it can not dispatch to parent.");
813                 return true;
814             }
815
816             return consumed;
817         }
818
819         // Callback for View Hover signal
820         private bool OnHoverEvent(IntPtr view, IntPtr hoverEvent)
821         {
822             if (hoverEvent == global::System.IntPtr.Zero)
823             {
824                 NUILog.Error("hoverEvent should not be null!");
825                 return true;
826             }
827
828             HoverEventArgs e = new HoverEventArgs();
829
830             e.Hover = Tizen.NUI.Hover.GetHoverFromPtr(hoverEvent);
831
832             if (hoverEventHandler != null)
833             {
834                 return hoverEventHandler(this, e);
835             }
836             return false;
837         }
838
839         // Callback for View Wheel signal
840         private bool OnWheelEvent(IntPtr view, IntPtr wheelEvent)
841         {
842             if (wheelEvent == global::System.IntPtr.Zero)
843             {
844                 NUILog.Error("wheelEvent should not be null!");
845                 return true;
846             }
847
848             WheelEventArgs e = new WheelEventArgs();
849
850             e.Wheel = Tizen.NUI.Wheel.GetWheelFromPtr(wheelEvent);
851
852             if (wheelEventHandler != null)
853             {
854                 return wheelEventHandler(this, e);
855             }
856             return false;
857         }
858
859         // Callback for View OnWindow signal
860         private void OnWindow(IntPtr data)
861         {
862             if (onWindowEventHandler != null)
863             {
864                 onWindowEventHandler(this, null);
865             }
866         }
867
868         // Callback for View OffWindow signal
869         private void OffWindow(IntPtr data)
870         {
871             if (offWindowEventHandler != null)
872             {
873                 offWindowEventHandler(this, null);
874             }
875         }
876
877         // Callback for View visibility change signal
878         private void OnVisibilityChanged(IntPtr data, bool visibility, VisibilityChangeType type)
879         {
880             VisibilityChangedEventArgs e = new VisibilityChangedEventArgs();
881             if (data != null)
882             {
883                 e.View = Registry.GetManagedBaseHandleFromNativePtr(data) as View;
884             }
885             e.Visibility = visibility;
886             e.Type = type;
887
888             if (visibilityChangedEventHandler != null)
889             {
890                 visibilityChangedEventHandler(this, e);
891             }
892         }
893
894         // Callback for View layout direction change signal
895         private void OnLayoutDirectionChanged(IntPtr data, ViewLayoutDirectionType type)
896         {
897             LayoutDirectionChangedEventArgs e = new LayoutDirectionChangedEventArgs();
898             if (data != null)
899             {
900                 e.View = Registry.GetManagedBaseHandleFromNativePtr(data) as View;
901             }
902             e.Type = type;
903
904             if (layoutDirectionChangedEventHandler != null)
905             {
906                 layoutDirectionChangedEventHandler(this, e);
907             }
908         }
909
910         private void OnResourcesLoaded(IntPtr view)
911         {
912             if(!CheckResourceReady())
913             {
914                 return;
915             }
916
917             if (resourcesLoadedEventHandler != null)
918             {
919                 resourcesLoadedEventHandler(this, null);
920             }
921         }
922
923         private void OnBackgroundResourceLoaded(IntPtr view)
924         {
925             BackgroundResourceLoadedEventArgs e = new BackgroundResourceLoadedEventArgs();
926             e.Status = (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.BACKGROUND);
927
928             if (backgroundResourceLoadedEventHandler != null)
929             {
930                 backgroundResourceLoadedEventHandler(this, e);
931             }
932         }
933
934         /// <summary>
935         /// Event argument passed through the ChildAdded event.
936         /// </summary>
937         /// <since_tizen> 5 </since_tizen>
938         public class ChildAddedEventArgs : EventArgs
939         {
940             /// <summary>
941             /// Added child view at moment.
942             /// </summary>
943             /// <since_tizen> 5 </since_tizen>
944             public View Added { get; set; }
945         }
946
947         /// <summary>
948         /// Event argument passed through the ChildRemoved event.
949         /// </summary>
950         /// <since_tizen> 5 </since_tizen>
951         public class ChildRemovedEventArgs : EventArgs
952         {
953             /// <summary>
954             /// Removed child view at moment.
955             /// </summary>
956             /// <since_tizen> 5 </since_tizen>
957             public View Removed { get; set; }
958         }
959
960         /// <summary>
961         /// Event arguments that passed via the KeyEvent signal.
962         /// </summary>
963         /// <since_tizen> 3 </since_tizen>
964         public class KeyEventArgs : EventArgs
965         {
966             private Key _key;
967
968             /// <summary>
969             /// Key - is the key sent to the view.
970             /// </summary>
971             /// <since_tizen> 3 </since_tizen>
972             public Key Key
973             {
974                 get
975                 {
976                     return _key;
977                 }
978                 set
979                 {
980                     _key = value;
981                 }
982             }
983         }
984
985         /// <summary>
986         /// Event arguments that passed via the touch signal.
987         /// </summary>
988         /// <since_tizen> 3 </since_tizen>
989         public class TouchEventArgs : EventArgs
990         {
991             private Touch _touch;
992
993             /// <summary>
994             /// Touch - contains the information of touch points.
995             /// </summary>
996             /// <since_tizen> 3 </since_tizen>
997             public Touch Touch
998             {
999                 get
1000                 {
1001                     return _touch;
1002                 }
1003                 set
1004                 {
1005                     _touch = value;
1006                 }
1007             }
1008         }
1009
1010         /// <summary>
1011         /// Event arguments that passed via the hover signal.
1012         /// </summary>
1013         /// <since_tizen> 3 </since_tizen>
1014         public class HoverEventArgs : EventArgs
1015         {
1016             private Hover _hover;
1017
1018             /// <summary>
1019             /// Hover - contains touch points that represent the points that are currently being hovered or the points where a hover has stopped.
1020             /// </summary>
1021             /// <since_tizen> 3 </since_tizen>
1022             public Hover Hover
1023             {
1024                 get
1025                 {
1026                     return _hover;
1027                 }
1028                 set
1029                 {
1030                     _hover = value;
1031                 }
1032             }
1033         }
1034
1035         /// <summary>
1036         /// Event arguments that passed via the wheel signal.
1037         /// </summary>
1038         /// <since_tizen> 3 </since_tizen>
1039         public class WheelEventArgs : EventArgs
1040         {
1041             private Wheel _wheel;
1042
1043             /// <summary>
1044             /// WheelEvent - store a wheel rolling type: MOUSE_WHEEL or CUSTOM_WHEEL.
1045             /// </summary>
1046             /// <since_tizen> 3 </since_tizen>
1047             public Wheel Wheel
1048             {
1049                 get
1050                 {
1051                     return _wheel;
1052                 }
1053                 set
1054                 {
1055                     _wheel = value;
1056                 }
1057             }
1058         }
1059
1060         /// <summary>
1061         /// Event arguments of visibility changed.
1062         /// </summary>
1063         /// <since_tizen> 3 </since_tizen>
1064         public class VisibilityChangedEventArgs : EventArgs
1065         {
1066             private View _view;
1067             private bool _visibility;
1068             private VisibilityChangeType _type;
1069
1070             /// <summary>
1071             /// The view, or child of view, whose visibility has changed.
1072             /// </summary>
1073             /// <since_tizen> 3 </since_tizen>
1074             public View View
1075             {
1076                 get
1077                 {
1078                     return _view;
1079                 }
1080                 set
1081                 {
1082                     _view = value;
1083                 }
1084             }
1085
1086             /// <summary>
1087             /// Whether the view is now visible or not.
1088             /// </summary>
1089             /// <since_tizen> 3 </since_tizen>
1090             public bool Visibility
1091             {
1092                 get
1093                 {
1094                     return _visibility;
1095                 }
1096                 set
1097                 {
1098                     _visibility = value;
1099                 }
1100             }
1101
1102             /// <summary>
1103             /// Whether the view's visible property has changed or a parent's.
1104             /// </summary>
1105             /// <since_tizen> 3 </since_tizen>
1106             public VisibilityChangeType Type
1107             {
1108                 get
1109                 {
1110                     return _type;
1111                 }
1112                 set
1113                 {
1114                     _type = value;
1115                 }
1116             }
1117         }
1118
1119         /// <summary>
1120         /// Event arguments of layout direction changed.
1121         /// </summary>
1122         /// <since_tizen> 4 </since_tizen>
1123         public class LayoutDirectionChangedEventArgs : EventArgs
1124         {
1125             private View _view;
1126             private ViewLayoutDirectionType _type;
1127
1128             /// <summary>
1129             /// The view, or child of view, whose layout direction has changed.
1130             /// </summary>
1131             /// <since_tizen> 4 </since_tizen>
1132             public View View
1133             {
1134                 get
1135                 {
1136                     return _view;
1137                 }
1138                 set
1139                 {
1140                     _view = value;
1141                 }
1142             }
1143
1144             /// <summary>
1145             /// Whether the view's layout direction property has changed or a parent's.
1146             /// </summary>
1147             /// <since_tizen> 4 </since_tizen>
1148             public ViewLayoutDirectionType Type
1149             {
1150                 get
1151                 {
1152                     return _type;
1153                 }
1154                 set
1155                 {
1156                     _type = value;
1157                 }
1158             }
1159         }
1160
1161         internal class BackgroundResourceLoadedEventArgs : EventArgs
1162         {
1163             private ResourceLoadingStatusType status = ResourceLoadingStatusType.Invalid;
1164             public ResourceLoadingStatusType Status
1165             {
1166                 get
1167                 {
1168                     return status;
1169                 }
1170                 set
1171                 {
1172                     status = value;
1173                 }
1174             }
1175         }
1176
1177         /// <summary>
1178         /// The class represents the information of the situation where the View's control state changes.
1179         /// </summary>
1180         [EditorBrowsable(EditorBrowsableState.Never)]
1181         public class ControlStateChangedEventArgs : EventArgs
1182         {
1183             /// <summary>
1184             /// Create an instance with mandatory fields.
1185             /// </summary>
1186             /// <param name="previousState">The previous control state.</param>
1187             /// <param name="currentState">The current control state.</param>
1188             [EditorBrowsable(EditorBrowsableState.Never)]
1189             public ControlStateChangedEventArgs(ControlState previousState, ControlState currentState)
1190             {
1191                 PreviousState = previousState;
1192                 CurrentState = currentState;
1193             }
1194
1195             /// <summary>
1196             /// The previous control state.
1197             /// </summary>
1198             [EditorBrowsable(EditorBrowsableState.Never)]
1199             public ControlState PreviousState { get; }
1200
1201             /// <summary>
1202             /// The current control state.
1203             /// </summary>
1204             [EditorBrowsable(EditorBrowsableState.Never)]
1205             public ControlState CurrentState { get; }
1206         }
1207
1208         /// <summary>
1209         /// The expanded touch area.
1210         /// TouchArea can expand the view's touchable area.<br/>
1211         /// If you set the TouchAreaOffset on an view, when you touch the view, the touch area is used rather than the size of the view.<br/>
1212         /// </summary>
1213         /// <remarks>
1214         /// This is based on the top left x, y coordinates.<br/>
1215         /// For example) <br/>
1216         /// <code>
1217         ///  view.Size = new Size(100, 100);
1218         ///  view.TouchAreaOffset = new Offset(-10, 20, 30, -40); // left, right, bottom, top
1219         /// </code>
1220         /// Then, touch area is 130x170.<br/>
1221         /// This is view.width + TouchAreaOffset.right - TouchAreaOffset.left and view.height + TouchAreaOffset.bottom - TouchAreaOffset.top <br/>
1222         /// +---------------------+ <br/>
1223         /// |         ^           | <br/>
1224         /// |         |           | <br/>
1225         /// |         | -40       | <br/>
1226         /// |         |           | <br/>
1227         /// |         |           | <br/>
1228         /// |    +----+----+      | <br/>
1229         /// |    |         |      | <br/>
1230         /// | -10|         | 20   | <br/>
1231         /// |&lt;---+         +-----&gt;| <br/>
1232         /// |    |         |      | <br/>
1233         /// |    |         |      | <br/>
1234         /// |    +----+----+      | <br/>
1235         /// |         |           | <br/>
1236         /// |         | 30        | <br/>
1237         /// |         |           | <br/>
1238         /// |         v           | <br/>
1239         /// +---------------------+ <br/>
1240         /// </remarks>
1241         [EditorBrowsable(EditorBrowsableState.Never)]
1242         public Offset TouchAreaOffset
1243         {
1244             get
1245             {
1246                 return (Offset)GetValue(TouchAreaOffsetProperty);
1247             }
1248             set
1249             {
1250                 SetValue(TouchAreaOffsetProperty, value);
1251                 NotifyPropertyChanged();
1252             }
1253         }
1254
1255         private Offset InternalTouchAreaOffset
1256         {
1257             get
1258             {
1259                 Interop.ActorInternal.GetTouchAreaOffset(SwigCPtr, out int left, out int right, out int bottom, out int top);
1260                 if (NDalicPINVOKE.SWIGPendingException.Pending)
1261                     throw NDalicPINVOKE.SWIGPendingException.Retrieve();
1262                 return new Offset(left, right, bottom, top);
1263             }
1264             set
1265             {
1266                 Interop.ActorInternal.SetTouchAreaOffset(SwigCPtr, value.Left, value.Right, value.Bottom, value.Top);
1267                 if (NDalicPINVOKE.SWIGPendingException.Pending)
1268                     throw NDalicPINVOKE.SWIGPendingException.Retrieve();
1269             }
1270         }
1271
1272     }
1273 }