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