Release 4.0.0-preview1-00249
[platform/core/csapi/tizenfx.git] / src / ElmSharp / ElmSharp / EvasObject.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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 using System;
18 using System.Collections.Generic;
19 using System.Diagnostics;
20
21 namespace ElmSharp
22 {
23     public enum TooltipOrientation
24     {
25         None,
26         TopLeft,
27         Top,
28         TopRight,
29         Left,
30         Center,
31         Right,
32         BottomLeft,
33         Bottom,
34         BottomRight,
35     }
36
37     public enum AspectControl
38     {
39         None = 0, /* Preference on scaling unset */
40         Neither = 1, /* Same effect as unset preference on scaling */
41         Horizontal = 2, /* Use all horizontal container space to place an object, using the given aspect */
42         Vertical = 3, /* Use all vertical container space to place an object, using the given aspect */
43         Both = 4 /* Use all horizontal @b and vertical container spaces to place an object (never growing it out of those bounds), using the given aspect */
44     }
45
46     /// <summary>
47     /// The EcasObject is a base class for other widget class
48     /// </summary>
49     public abstract class EvasObject
50     {
51         private IntPtr _realHandle = IntPtr.Zero;
52         private EvasCanvas _evasCanvas;
53
54         private event EventHandler _backButtonPressed;
55
56         private event EventHandler _moreButtonPressed;
57
58         private Interop.Eext.EextEventCallback _backButtonHandler;
59         private Interop.Eext.EextEventCallback _moreButtonHandler;
60
61         public IntPtr Handle { get; protected set; }
62         public EvasObject Parent { get; private set; }
63
64         public IntPtr RealHandle
65         {
66             get
67             {
68                 return _realHandle == IntPtr.Zero ? Handle : _realHandle;
69             }
70             protected set
71             {
72                 _realHandle = value;
73                 Interop.Evas.evas_object_show(_realHandle);
74             }
75         }
76
77         EvasObjectEvent _deleted;
78         EvasObjectEvent<EvasKeyEventArgs> _keyup;
79         EvasObjectEvent<EvasKeyEventArgs> _keydown;
80         EvasObjectEvent _moved;
81         EvasObjectEvent _resized;
82         EventHandler _renderPost;
83         Interop.Evas.EvasCallback _renderPostCallback = null;
84         Interop.Elementary.Elm_Tooltip_Content_Cb _tooltipContentCallback = null;
85
86         GetTooltipContentDelegate _tooltipContentDelegate = null;
87
88         readonly HashSet<IInvalidatable> _eventStore = new HashSet<IInvalidatable>();
89
90         /// <summary>
91         /// Creates and initializes a new instance of the EvasObject class with parent EvasObject class parameter.
92         /// </summary>
93         /// <param name="parent">Parent EvasObject class </param>
94         protected EvasObject(EvasObject parent) : this()
95         {
96             Debug.Assert(parent == null || parent.IsRealized);
97             Realize(parent);
98         }
99
100         /// <summary>
101         /// Creates and initializes a new instance of the EvasObject class.
102         /// </summary>
103         protected EvasObject()
104         {
105             _backButtonHandler = new Interop.Eext.EextEventCallback((d, o, i) => { _backButtonPressed?.Invoke(this, EventArgs.Empty); });
106             _moreButtonHandler = new Interop.Eext.EextEventCallback((d, o, i) => { _moreButtonPressed?.Invoke(this, EventArgs.Empty); });
107
108             OnInstantiated();
109
110             _tooltipContentCallback = (d, o, t) =>
111             {
112                 return _tooltipContentDelegate?.Invoke();
113             };
114         }
115
116         // C# Finalizer was called on GC thread
117         // So, We can't access to EFL object
118         // And When Finalizer was called, Field can be already released.
119         //~EvasObject()
120         //{
121         //    Unrealize();
122         //}
123
124         /// <summary>
125         /// Deleted will be triggered when widght is deleted
126         /// </summary>
127         public event EventHandler Deleted;
128
129         /// <summary>
130         /// KeyUp will be triggered when key is loose
131         /// </summary>
132         public event EventHandler<EvasKeyEventArgs> KeyUp;
133
134         /// <summary>
135         /// KeyDown will be triggered when key is preesd down
136         /// </summary>
137         public event EventHandler<EvasKeyEventArgs> KeyDown;
138
139         /// <summary>
140         /// BackButtonPressed will be triggered when Back button is pressed
141         /// </summary>
142         public event EventHandler BackButtonPressed
143         {
144             add
145             {
146                 if (_backButtonPressed == null)
147                 {
148                     Interop.Eext.eext_object_event_callback_add(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_BACK, _backButtonHandler, IntPtr.Zero);
149                 }
150                 _backButtonPressed += value;
151             }
152             remove
153             {
154                 _backButtonPressed -= value;
155                 if (_backButtonPressed == null)
156                 {
157                     Interop.Eext.eext_object_event_callback_del(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_BACK, _backButtonHandler);
158                 }
159             }
160         }
161
162         /// <summary>
163         /// MoreButtonPressed will be triggered when More button is pressed
164         /// </summary>
165         public event EventHandler MoreButtonPressed
166         {
167             add
168             {
169                 if (_moreButtonPressed == null)
170                 {
171                     Interop.Eext.eext_object_event_callback_add(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_MORE, _moreButtonHandler, IntPtr.Zero);
172                 }
173                 _moreButtonPressed += value;
174             }
175             remove
176             {
177                 _moreButtonPressed -= value;
178                 if (_moreButtonPressed == null)
179                 {
180                     Interop.Eext.eext_object_event_callback_del(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_MORE, _moreButtonHandler);
181                 }
182             }
183         }
184
185         /// <summary>
186         /// Moved will be triggered when widght is moved
187         /// </summary>
188         public event EventHandler Moved
189         {
190             add { _moved.On += value; }
191             remove { _moved.On -= value; }
192         }
193
194         /// <summary>
195         /// Current widget's size Resized Event Handler
196         /// </summary>
197         public event EventHandler Resized
198         {
199             add { _resized.On += value; }
200             remove { _resized.On -= value; }
201         }
202
203         /// <summary>
204         /// Current widget RenderPost Event Handler
205         /// </summary>
206         public event EventHandler RenderPost
207         {
208             add
209             {
210                 _renderPost += value;
211                 if (_renderPostCallback == null)
212                 {
213                     _renderPostCallback = new Interop.Evas.EvasCallback((o, e, d) => _renderPost?.Invoke(this, EventArgs.Empty));
214                     Interop.Evas.evas_event_callback_add(Interop.Evas.evas_object_evas_get(RealHandle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback, IntPtr.Zero);
215                 }
216             }
217             remove
218             {
219                 _renderPost -= value;
220                 if (_renderPost == null)
221                 {
222                     Interop.Evas.evas_event_callback_del(Interop.Evas.evas_object_evas_get(RealHandle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback);
223                     _renderPostCallback = null;
224                 }
225             }
226         }
227
228         /// <summary>
229         /// Called back when a widget's tooltip is activated and needs content.
230         /// </summary>
231         /// <returns></returns>
232         public delegate EvasObject GetTooltipContentDelegate();
233
234         /// <summary>
235         /// Get widget's status of Realized or not.
236         /// </summary>
237         public bool IsRealized { get { return Handle != IntPtr.Zero; } }
238
239         /// <summary>
240         /// Gets EvasCanvas
241         /// </summary>
242         public EvasCanvas EvasCanvas
243         {
244             get
245             {
246                 if (_evasCanvas == null)
247                     _evasCanvas = new EvasCanvas(Handle);
248                 return _evasCanvas;
249             }
250         }
251
252         /// <summary>
253         /// Gets the current class's Name.
254         /// </summary>
255         public string ClassName
256         {
257             get
258             {
259                 return Interop.Eo.eo_class_name_get(Interop.Eo.eo_class_get(RealHandle));
260             }
261         }
262
263         /// <summary>
264         /// Sets or gets the horizontal pointer hints for an object's weight.
265         /// </summary>
266         public double WeightX
267         {
268             get
269             {
270                 return Interop.Evas.GetWeightX(Handle);
271             }
272             set
273             {
274                 Interop.Evas.SetWeightX(Handle, value);
275             }
276         }
277
278         /// <summary>
279         /// Sets or gets the vertical pointer hints for an object's weight.
280         /// </summary>
281         public double WeightY
282         {
283             get
284             {
285                 return Interop.Evas.GetWeightY(Handle);
286             }
287             set
288             {
289                 Interop.Evas.SetWeightY(Handle, value);
290             }
291         }
292
293         /// <summary>
294         /// Sets or gets the horizontal alignment hint of an object's alignment.
295         /// </summary>
296         public virtual double AlignmentX
297         {
298             get
299             {
300                 return Interop.Evas.GetAlignX(Handle);
301             }
302             set
303             {
304                 Interop.Evas.SetAlignX(Handle, value);
305             }
306         }
307
308         /// <summary>
309         /// Sets or gets the vertical alignment hint of an object's alignment.
310         /// </summary>
311         public virtual double AlignmentY
312         {
313             get
314             {
315                 return Interop.Evas.GetAlignY(Handle);
316             }
317             set
318             {
319                 Interop.Evas.SetAlignY(Handle, value);
320             }
321         }
322
323         /// <summary>
324         /// Sets or gets the Width hints for an object's minimum size.
325         /// </summary>
326         public int MinimumWidth
327         {
328             get
329             {
330                 int w, h;
331                 Interop.Evas.evas_object_size_hint_min_get(RealHandle, out w, out h);
332                 return w;
333             }
334             set
335             {
336                 int h = MinimumHeight;
337                 Interop.Evas.evas_object_size_hint_min_set(RealHandle, value, h);
338             }
339         }
340
341         /// <summary>
342         /// Sets or gets the Height hints for an object's minimum size.
343         /// </summary>
344         public int MinimumHeight
345         {
346             get
347             {
348                 int w, h;
349                 Interop.Evas.evas_object_size_hint_min_get(RealHandle, out w, out h);
350                 return h;
351             }
352             set
353             {
354                 int w = MinimumWidth;
355                 Interop.Evas.evas_object_size_hint_min_set(RealHandle, w, value);
356             }
357         }
358
359         /// <summary>
360         /// Gets the visible state of the given Evas object.
361         /// </summary>
362         public bool IsVisible
363         {
364             get
365             {
366                 return Interop.Evas.evas_object_visible_get(Handle);
367             }
368         }
369
370         /// <summary>
371         /// Sets or gets the position and (rectangular) size of the given Evas object.
372         /// </summary>
373         public Rect Geometry
374         {
375             get
376             {
377                 int x, y, w, h;
378                 Interop.Evas.evas_object_geometry_get(Handle, out x, out y, out w, out h);
379                 Rect rect = new Rect(x, y, w, h);
380                 return rect;
381             }
382             set
383             {
384                 Interop.Evas.evas_object_geometry_set(Handle, value.X, value.Y, value.Width, value.Height);
385             }
386         }
387
388         /// <summary>
389         /// Sets or gets the general or main color of the given Evas object.
390         /// </summary>
391         public virtual Color Color
392         {
393             get
394             {
395                 int r, g, b, a;
396                 Interop.Evas.evas_object_color_get(RealHandle, out r, out g, out b, out a);
397                 return Color.FromRgba(r, g, b, a);
398             }
399             set
400             {
401                 Interop.Evas.SetPremultipliedColor(RealHandle, value.R, value.G, value.B, value.A);
402             }
403         }
404
405         /// <summary>
406         /// Sets or gets the map enabled state.
407         /// </summary>
408         public bool IsMapEnabled
409         {
410             get
411             {
412                 return Interop.Evas.evas_object_map_enable_get(Handle);
413             }
414             set
415             {
416                 Interop.Evas.evas_object_map_enable_set(Handle, value);
417             }
418         }
419
420         /// <summary>
421         /// Sets or gets current object transformation map.
422         /// </summary>
423         public EvasMap EvasMap
424         {
425             get
426             {
427                 IntPtr evasMap = Interop.Evas.evas_object_map_get(Handle);
428                 return new EvasMap(evasMap);
429             }
430             set
431             {
432                 Interop.Evas.evas_object_map_set(Handle, value.Handle);
433             }
434         }
435
436         /// <summary>
437         /// Sets or gets whether an object is to repeat events.
438         /// </summary>
439         public bool RepeatEvents
440         {
441             get
442             {
443                 var result = Interop.Evas.evas_object_repeat_events_get(Handle);
444                 Debug.Assert(Handle == RealHandle || result == Interop.Evas.evas_object_repeat_events_get(RealHandle));
445                 return result;
446             }
447             set
448             {
449                 if (Handle != RealHandle)
450                 {
451                     Interop.Evas.evas_object_repeat_events_set(RealHandle, value);
452                 }
453                 Interop.Evas.evas_object_repeat_events_set(Handle, value);
454             }
455         }
456
457         /// <summary>
458         /// Sets or gets whether events on a smart object's member should get propagated up to its parent.
459         /// </summary>
460         public bool PropagateEvents
461         {
462             get
463             {
464                 var result = Interop.Evas.evas_object_propagate_events_get(Handle);
465                 Debug.Assert(Handle == RealHandle || result == Interop.Evas.evas_object_propagate_events_get(RealHandle));
466                 return result;
467             }
468             set
469             {
470                 if (Handle != RealHandle)
471                 {
472                     Interop.Evas.evas_object_propagate_events_set(RealHandle, value);
473                 }
474                 Interop.Evas.evas_object_propagate_events_set(Handle, value);
475             }
476         }
477
478         /// <summary>
479         /// Sets or gets whether an object is set to pass (ignore) events.
480         /// </summary>
481         public bool PassEvents
482         {
483             get
484             {
485                 var result = Interop.Evas.evas_object_pass_events_get(Handle);
486                 Debug.Assert(Handle == RealHandle || result == Interop.Evas.evas_object_pass_events_get(RealHandle));
487                 return result;
488             }
489             set
490             {
491                 if (Handle != RealHandle)
492                 {
493                     Interop.Evas.evas_object_pass_events_set(RealHandle, value);
494                 }
495                 Interop.Evas.evas_object_pass_events_set(Handle, value);
496             }
497         }
498
499         /// <summary>
500         /// Sets or Gets style for this object tooltip.
501         /// </summary>
502         public string TooltipStyle
503         {
504             get
505             {
506                 return Interop.Elementary.elm_object_tooltip_style_get(RealHandle);
507             }
508             set
509             {
510                 Interop.Elementary.elm_object_tooltip_style_set(RealHandle, value);
511             }
512         }
513
514         /// <summary>
515         /// Sets or gets the orientation of Tooltip.
516         /// </summary>
517         public TooltipOrientation TooltipOrientation
518         {
519             get
520             {
521                 return (TooltipOrientation)Interop.Elementary.elm_object_tooltip_orient_get(RealHandle);
522             }
523             set
524             {
525                 Interop.Elementary.elm_object_tooltip_orient_set(RealHandle, (int)value);
526             }
527         }
528
529         /// <summary>
530         /// Sets or gets size restriction state of an object's tooltip.
531         /// </summary>
532         public bool TooltipWindowMode
533         {
534             get
535             {
536                 return Interop.Elementary.elm_object_tooltip_window_mode_get(RealHandle);
537             }
538             set
539             {
540                 Interop.Elementary.elm_object_tooltip_window_mode_set(RealHandle, value);
541             }
542         }
543
544         /// <summary>
545         /// Sets the content to be shown in the tooltip object.
546         /// </summary>
547         public GetTooltipContentDelegate TooltipContentDelegate
548         {
549             get
550             {
551                 return _tooltipContentDelegate;
552             }
553             set
554             {
555                 _tooltipContentDelegate = value;
556                 if (value != null)
557                 {
558                     Interop.Elementary.elm_object_tooltip_content_cb_set(RealHandle, _tooltipContentCallback, IntPtr.Zero, null);
559                 }
560                 else
561                 {
562                     Interop.Elementary.elm_object_tooltip_content_cb_set(RealHandle, null, IntPtr.Zero, null);
563                 }
564             }
565         }
566
567         /// <summary>
568         /// Gets the movement freeze by 1
569         /// This gets the movement freeze count by one.
570         /// </summary>
571         public int TooltipMoveFreezeCount
572         {
573             get
574             {
575                 return Interop.Elementary.elm_object_tooltip_move_freeze_get(RealHandle);
576             }
577         }
578
579         /// <summary>
580         /// Sets or gets whether an Evas object is to freeze (discard) events.
581         /// </summary>
582         public bool AllEventsFrozen
583         {
584             get
585             {
586                 var result = Interop.Evas.evas_object_freeze_events_get(Handle);
587                 Debug.Assert(Handle == RealHandle || result == Interop.Evas.evas_object_freeze_events_get(RealHandle));
588                 return result;
589             }
590             set
591             {
592                 if (Handle != RealHandle)
593                 {
594                     Interop.Evas.evas_object_freeze_events_set(RealHandle, value);
595                 }
596                 Interop.Evas.evas_object_freeze_events_set(Handle, value);
597             }
598         }
599
600         /// <summary>
601         /// Sets or gets the layer of its canvas that the given object will be part of.
602         /// </summary>
603         public virtual int Layer
604         {
605             get
606             {
607                 return Interop.Evas.evas_object_layer_get(Handle);
608             }
609             set
610             {
611                 Interop.Evas.evas_object_layer_set(Handle, value);
612             }
613         }
614
615         /// <summary>
616         /// Clips one object to another.
617         /// </summary>
618         /// <param name="clip">The object to clip object by</param>
619         public void SetClip(EvasObject clip)
620         {
621             Interop.Evas.evas_object_clip_set(Handle, clip);
622         }
623
624         /// <summary>
625         /// Sets the hints for an object's alignment.
626         /// </summary>
627         /// <param name="x">The horizontal alignment hint as double value ranging from 0.0 to 1.0,The default alignment hint value is 0.5 </param>
628         /// <param name="y">The vertical alignment hint as double value ranging from 0.0 to 1.0,The default alignment hint value is 0.5 </param>
629         public void SetAlignment(double x, double y)
630         {
631             Interop.Evas.evas_object_size_hint_align_set(Handle, x, y);
632         }
633
634         /// <summary>
635         /// Sets the hints for an object's weight.
636         /// </summary>
637         /// <param name="x">The non-negative double value to use as horizontal weight hint</param>
638         /// <param name="y">The non-negative double value to use as vertical weight hint</param>
639         public void SetWeight(double x, double y)
640         {
641             Interop.Evas.evas_object_size_hint_weight_set(Handle, x, y);
642         }
643
644         /// <summary>
645         /// Sets the text for an object's tooltip.
646         /// </summary>
647         /// <param name="text">The text value to display inside the tooltip</param>
648         public void SetTooltipText(string text)
649         {
650             Interop.Elementary.elm_object_tooltip_text_set(RealHandle, text);
651         }
652
653         /// <summary>
654         /// Unsets an object's tooltip.
655         /// </summary>
656         public void UnsetTooltip()
657         {
658             Interop.Elementary.elm_object_tooltip_unset(RealHandle);
659         }
660
661         /// <summary>
662         /// This increments the tooltip movement freeze count by one.
663         /// If the count is more than 0, the tooltip position will be fixed.
664         /// </summary>
665         public void PushTooltipMoveFreeze()
666         {
667             Interop.Elementary.elm_object_tooltip_move_freeze_push(RealHandle);
668         }
669
670         /// <summary>
671         /// This decrements the tooltip freeze count by one.
672         /// </summary>
673         public void PopTooltipMoveFreeze()
674         {
675             Interop.Elementary.elm_object_tooltip_move_freeze_pop(RealHandle);
676         }
677
678         /// <summary>
679         /// Force hide tooltip of object.
680         /// </summary>
681         public void HideTooltip()
682         {
683             Interop.Elementary.elm_object_tooltip_hide(RealHandle);
684         }
685
686         /// <summary>
687         /// Force show tooltip of object.
688         /// </summary>
689         public void ShowTooltip()
690         {
691             Interop.Elementary.elm_object_tooltip_show(RealHandle);
692         }
693
694         /// <summary>
695         /// Makes the current object visible.
696         /// </summary>
697         public void Show()
698         {
699             Interop.Evas.evas_object_show(Handle);
700         }
701
702         /// <summary>
703         /// Makes the current object invisible.
704         /// </summary>
705         public void Hide()
706         {
707             Interop.Evas.evas_object_hide(Handle);
708         }
709
710         /// <summary>
711         /// Changes the size of the current object.
712         /// </summary>
713         /// <param name="w">The new width</param>
714         /// <param name="h">The new height</param>
715         public void Resize(int w, int h)
716         {
717             Interop.Evas.evas_object_resize(Handle, w, h);
718         }
719
720         /// <summary>
721         /// Moves the current object to the given location.
722         /// </summary>
723         /// <param name="x">The X position to move the object to.</param>
724         /// <param name="y">The Y position to move the object to.</param>
725         public void Move(int x, int y)
726         {
727             Interop.Evas.evas_object_move(Handle, x, y);
728         }
729
730         /// <summary>
731         /// Lowers obj to the bottom of its layer.
732         /// </summary>
733         public void Lower()
734         {
735             Interop.Evas.evas_object_lower(Handle);
736         }
737
738         /// <summary>
739         /// Define IntPtr operator
740         /// </summary>
741         /// <param name="obj">Parent object</param>
742         public static implicit operator IntPtr(EvasObject obj)
743         {
744             if (obj == null)
745                 return IntPtr.Zero;
746             return obj.Handle;
747         }
748
749         /// <summary>
750         /// Requests keyname key events be directed to current obj.
751         /// </summary>
752         /// <param name="keyname">The key to request events for</param>
753         /// <param name="exclusive">Set TRUE to request that the obj is the only object receiving the keyname events,otherwise set FALSE</param>
754         /// <returns>If the call succeeded is true,otherwise is false</returns>
755         public bool KeyGrab(string keyname, bool exclusive)
756         {
757             return Interop.Evas.evas_object_key_grab(Handle, keyname, 0, 0, exclusive);
758         }
759
760         /// <summary>
761         /// Removes the grab on keyname key events.
762         /// </summary>
763         /// <param name="keyname">The key the grab is set for</param>
764         public void KeyUngrab(string keyname)
765         {
766             Interop.Evas.evas_object_key_ungrab(Handle, keyname, 0, 0);
767         }
768
769         /// <summary>
770         /// Mark smart object as changed.
771         /// </summary>
772         public void MarkChanged()
773         {
774             Interop.Evas.evas_object_smart_changed(RealHandle);
775         }
776
777         /// <summary>
778         /// Call the calculate smart function immediately.
779         /// This will force immediate calculations needed for renderization of this object.
780         /// </summary>
781         public void Calculate()
782         {
783             Interop.Evas.evas_object_smart_calculate(RealHandle);
784         }
785
786         /// <summary>
787         /// Sets the hints for an object's aspect ratio.
788         /// </summary>
789         /// <param name="aspect">The policy or type of aspect ratio to apply to object</param>
790         /// <param name="w">The integer to use as aspect width ratio term</param>
791         /// <param name="h">The integer to use as aspect height ratio term</param>
792         public void SetSizeHintAspect(AspectControl aspect, int w, int h)
793         {
794             Interop.Evas.evas_object_size_hint_aspect_set(Handle, (int)aspect, w, h);
795         }
796
797         /// <summary>
798         /// Gets the hints for an object's aspect ratio.
799         /// </summary>
800         /// <param name="aspect">The policy or type of aspect ratio to apply to object</param>
801         /// <param name="w">The integer to use as aspect width ratio term</param>
802         /// <param name="h">The integer to use as aspect height ratio term</param>
803         public void GetSizeHintAspect(out AspectControl aspect, out int w, out int h)
804         {
805             int aspectRatio;
806             Interop.Evas.evas_object_size_hint_aspect_get(Handle, out aspectRatio, out w, out h);
807             aspect = (AspectControl)aspectRatio;
808         }
809
810         /// <summary>
811         /// Stack immediately below anchor.
812         /// </summary>
813         /// <param name="anchor">The object below which to stack.</param>
814         public void StackBelow(EvasObject anchor)
815         {
816             Interop.Evas.evas_object_stack_below(Handle, anchor);
817         }
818
819         /// <summary>
820         /// Stack immediately above anchor.
821         /// </summary>
822         /// <param name="anchor">The object above which to stack.</param>
823         public void StackAbove(EvasObject anchor)
824         {
825             Interop.Evas.evas_object_stack_above(Handle, anchor);
826         }
827
828         /// <summary>
829         /// Raise to the top of its layer.
830         /// </summary>
831         public void RaiseTop()
832         {
833             Interop.Evas.evas_object_raise(Handle);
834         }
835
836         /// <summary>
837         /// Get the geometry of a line number.
838         /// </summary>
839         /// <param name="lineNumber">the line number.</param>
840         /// <param name="x">x coord of the line.</param>
841         /// <param name="y">y coord of the line.</param>
842         /// <param name="w">w coord of the line.</param>
843         /// <param name="h">h coord of the line.</param>
844         /// <returns></returns>
845         public bool GetTextBlockGeometryByLineNumber(int lineNumber, out int x, out int y, out int w, out int h)
846         {
847             return Interop.Evas.evas_object_textblock_line_number_geometry_get(RealHandle, lineNumber, out x, out y, out w, out h);
848         }
849
850         internal IntPtr GetData(string key)
851         {
852             return Interop.Evas.evas_object_data_get(RealHandle, key);
853         }
854
855         internal void SetData(string key, IntPtr data)
856         {
857             Interop.Evas.evas_object_data_set(RealHandle, key, data);
858         }
859
860         internal IntPtr DeleteData(string key)
861         {
862             return Interop.Evas.evas_object_data_del(RealHandle, key);
863         }
864
865         /// <summary>
866         /// The callback of Invalidate Event
867         /// </summary>
868         protected virtual void OnInvalidate()
869         {
870         }
871
872         /// <summary>
873         /// The callback of Instantiated Event
874         /// </summary>
875         protected virtual void OnInstantiated()
876         {
877         }
878
879         /// <summary>
880         /// The callback of Realized Event
881         /// </summary>
882         protected virtual void OnRealized()
883         {
884         }
885
886         /// <summary>
887         /// The callback of Unrealize Event
888         /// </summary>
889         protected virtual void OnUnrealize()
890         {
891         }
892
893         /// <summary>
894         /// Creates a widget handle.
895         /// </summary>
896         /// <param name="parent">Parent EvasObject</param>
897         /// <returns>Handle IntPtr</returns>
898         protected abstract IntPtr CreateHandle(EvasObject parent);
899
900         /// <summary>
901         /// For this object bind Parent object.Init handle and all kinds of EvasObjectEvent.
902         /// </summary>
903         /// <param name="parent">Parent object</param>
904         public void Realize(EvasObject parent)
905         {
906             if (!IsRealized)
907             {
908                 Parent = parent;
909                 Handle = CreateHandle(parent);
910                 Debug.Assert(Handle != IntPtr.Zero);
911
912                 (parent as Window)?.AddChild(this);
913
914                 OnRealized();
915                 _deleted = new EvasObjectEvent(this, EvasObjectCallbackType.Del);
916                 _keydown = new EvasObjectEvent<EvasKeyEventArgs>(this, RealHandle, EvasObjectCallbackType.KeyDown, EvasKeyEventArgs.Create);
917                 _keyup = new EvasObjectEvent<EvasKeyEventArgs>(this, RealHandle, EvasObjectCallbackType.KeyUp, EvasKeyEventArgs.Create);
918                 _moved = new EvasObjectEvent(this, EvasObjectCallbackType.Move);
919                 _resized = new EvasObjectEvent(this, EvasObjectCallbackType.Resize);
920
921                 _deleted.On += (s, e) => MakeInvalidate();
922                 _keydown.On += (s, e) => KeyDown?.Invoke(this, e);
923                 _keyup.On += (s, e) => KeyUp?.Invoke(this, e);
924             }
925         }
926
927         /// <summary>
928         /// Removes current object relationship with others.
929         /// </summary>
930         public void Unrealize()
931         {
932             if (IsRealized)
933             {
934                 if (_renderPostCallback != null)
935                 {
936                     Interop.Evas.evas_event_callback_del(Interop.Evas.evas_object_evas_get(Handle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback);
937                     _renderPostCallback = null;
938                 }
939
940                 OnUnrealize();
941                 IntPtr toBeDeleted = Handle;
942                 Handle = IntPtr.Zero;
943
944                 DisposeEvent();
945
946                 (Parent as Window)?.RemoveChild(this);
947
948                 Interop.Evas.evas_object_del(toBeDeleted);
949                 Parent = null;
950             }
951         }
952
953         private void MakeInvalidate()
954         {
955             Deleted?.Invoke(this, EventArgs.Empty);
956             OnInvalidate();
957             Handle = IntPtr.Zero;
958
959             MakeInvalidateEvent();
960
961             (Parent as Window)?.RemoveChild(this);
962             Parent = null;
963             _deleted = null;
964         }
965
966         private void DisposeEvent()
967         {
968             foreach (var evt in _eventStore)
969             {
970                 evt.Dispose();
971             }
972             _eventStore.Clear();
973         }
974
975         private void MakeInvalidateEvent()
976         {
977             foreach (var evt in _eventStore)
978             {
979                 evt.MakeInvalidate();
980             }
981             _eventStore.Clear();
982         }
983
984         internal void AddToEventLifeTracker(IInvalidatable item)
985         {
986             _eventStore.Add(item);
987         }
988     }
989 }