2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Collections.Generic;
19 using System.Diagnostics;
23 public enum TooltipOrientation
37 public enum AspectControl
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 */
47 /// The EcasObject is a base class for other widget class
49 public abstract class EvasObject
51 private IntPtr _realHandle = IntPtr.Zero;
52 private EvasCanvas _evasCanvas;
54 private event EventHandler _backButtonPressed;
56 private event EventHandler _moreButtonPressed;
58 private Interop.Eext.EextEventCallback _backButtonHandler;
59 private Interop.Eext.EextEventCallback _moreButtonHandler;
61 public IntPtr Handle { get; protected set; }
62 public EvasObject Parent { get; private set; }
64 public IntPtr RealHandle
68 return _realHandle == IntPtr.Zero ? Handle : _realHandle;
73 Interop.Evas.evas_object_show(_realHandle);
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;
86 GetTooltipContentDelegate _tooltipContentDelegate = null;
88 readonly HashSet<IInvalidatable> _eventStore = new HashSet<IInvalidatable>();
91 /// Creates and initializes a new instance of the EvasObject class with parent EvasObject class parameter.
93 /// <param name="parent">Parent EvasObject class </param>
94 protected EvasObject(EvasObject parent) : this()
96 Debug.Assert(parent == null || parent.IsRealized);
101 /// Creates and initializes a new instance of the EvasObject class.
103 protected EvasObject()
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); });
110 _tooltipContentCallback = (d, o, t) =>
112 return _tooltipContentDelegate?.Invoke();
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.
125 /// Deleted will be triggered when widght is deleted
127 public event EventHandler Deleted;
130 /// KeyUp will be triggered when key is loose
132 public event EventHandler<EvasKeyEventArgs> KeyUp;
135 /// KeyDown will be triggered when key is preesd down
137 public event EventHandler<EvasKeyEventArgs> KeyDown;
140 /// BackButtonPressed will be triggered when Back button is pressed
142 public event EventHandler BackButtonPressed
146 if (_backButtonPressed == null)
148 Interop.Eext.eext_object_event_callback_add(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_BACK, _backButtonHandler, IntPtr.Zero);
150 _backButtonPressed += value;
154 _backButtonPressed -= value;
155 if (_backButtonPressed == null)
157 Interop.Eext.eext_object_event_callback_del(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_BACK, _backButtonHandler);
163 /// MoreButtonPressed will be triggered when More button is pressed
165 public event EventHandler MoreButtonPressed
169 if (_moreButtonPressed == null)
171 Interop.Eext.eext_object_event_callback_add(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_MORE, _moreButtonHandler, IntPtr.Zero);
173 _moreButtonPressed += value;
177 _moreButtonPressed -= value;
178 if (_moreButtonPressed == null)
180 Interop.Eext.eext_object_event_callback_del(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_MORE, _moreButtonHandler);
186 /// Moved will be triggered when widght is moved
188 public event EventHandler Moved
190 add { _moved.On += value; }
191 remove { _moved.On -= value; }
195 /// Current widget's size Resized Event Handler
197 public event EventHandler Resized
199 add { _resized.On += value; }
200 remove { _resized.On -= value; }
204 /// Current widget RenderPost Event Handler
206 public event EventHandler RenderPost
210 _renderPost += value;
211 if (_renderPostCallback == null)
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);
219 _renderPost -= value;
220 if (_renderPost == null)
222 Interop.Evas.evas_event_callback_del(Interop.Evas.evas_object_evas_get(RealHandle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback);
223 _renderPostCallback = null;
229 /// Called back when a widget's tooltip is activated and needs content.
231 /// <returns></returns>
232 public delegate EvasObject GetTooltipContentDelegate();
235 /// Get widget's status of Realized or not.
237 public bool IsRealized { get { return Handle != IntPtr.Zero; } }
242 public EvasCanvas EvasCanvas
246 if (_evasCanvas == null)
247 _evasCanvas = new EvasCanvas(Handle);
253 /// Gets the current class's Name.
255 public string ClassName
259 return Interop.Eo.eo_class_name_get(Interop.Eo.eo_class_get(RealHandle));
264 /// Sets or gets the horizontal pointer hints for an object's weight.
266 public double WeightX
270 return Interop.Evas.GetWeightX(Handle);
274 Interop.Evas.SetWeightX(Handle, value);
279 /// Sets or gets the vertical pointer hints for an object's weight.
281 public double WeightY
285 return Interop.Evas.GetWeightY(Handle);
289 Interop.Evas.SetWeightY(Handle, value);
294 /// Sets or gets the horizontal alignment hint of an object's alignment.
296 public virtual double AlignmentX
300 return Interop.Evas.GetAlignX(Handle);
304 Interop.Evas.SetAlignX(Handle, value);
309 /// Sets or gets the vertical alignment hint of an object's alignment.
311 public virtual double AlignmentY
315 return Interop.Evas.GetAlignY(Handle);
319 Interop.Evas.SetAlignY(Handle, value);
324 /// Sets or gets the Width hints for an object's minimum size.
326 public int MinimumWidth
331 Interop.Evas.evas_object_size_hint_min_get(RealHandle, out w, out h);
336 int h = MinimumHeight;
337 Interop.Evas.evas_object_size_hint_min_set(RealHandle, value, h);
342 /// Sets or gets the Height hints for an object's minimum size.
344 public int MinimumHeight
349 Interop.Evas.evas_object_size_hint_min_get(RealHandle, out w, out h);
354 int w = MinimumWidth;
355 Interop.Evas.evas_object_size_hint_min_set(RealHandle, w, value);
360 /// Gets the visible state of the given Evas object.
362 public bool IsVisible
366 return Interop.Evas.evas_object_visible_get(Handle);
371 /// Sets or gets the position and (rectangular) size of the given Evas object.
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);
384 Interop.Evas.evas_object_geometry_set(Handle, value.X, value.Y, value.Width, value.Height);
389 /// Sets or gets the general or main color of the given Evas object.
391 public virtual Color Color
396 Interop.Evas.evas_object_color_get(RealHandle, out r, out g, out b, out a);
397 return Color.FromRgba(r, g, b, a);
401 Interop.Evas.SetPremultipliedColor(RealHandle, value.R, value.G, value.B, value.A);
406 /// Sets or gets the map enabled state.
408 public bool IsMapEnabled
412 return Interop.Evas.evas_object_map_enable_get(Handle);
416 Interop.Evas.evas_object_map_enable_set(Handle, value);
421 /// Sets or gets current object transformation map.
423 public EvasMap EvasMap
427 IntPtr evasMap = Interop.Evas.evas_object_map_get(Handle);
428 return new EvasMap(evasMap);
432 Interop.Evas.evas_object_map_set(Handle, value.Handle);
437 /// Sets or gets whether an object is to repeat events.
439 public bool RepeatEvents
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));
449 if (Handle != RealHandle)
451 Interop.Evas.evas_object_repeat_events_set(RealHandle, value);
453 Interop.Evas.evas_object_repeat_events_set(Handle, value);
458 /// Sets or gets whether events on a smart object's member should get propagated up to its parent.
460 public bool PropagateEvents
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));
470 if (Handle != RealHandle)
472 Interop.Evas.evas_object_propagate_events_set(RealHandle, value);
474 Interop.Evas.evas_object_propagate_events_set(Handle, value);
479 /// Sets or gets whether an object is set to pass (ignore) events.
481 public bool PassEvents
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));
491 if (Handle != RealHandle)
493 Interop.Evas.evas_object_pass_events_set(RealHandle, value);
495 Interop.Evas.evas_object_pass_events_set(Handle, value);
500 /// Sets or Gets style for this object tooltip.
502 public string TooltipStyle
506 return Interop.Elementary.elm_object_tooltip_style_get(RealHandle);
510 Interop.Elementary.elm_object_tooltip_style_set(RealHandle, value);
515 /// Sets or gets the orientation of Tooltip.
517 public TooltipOrientation TooltipOrientation
521 return (TooltipOrientation)Interop.Elementary.elm_object_tooltip_orient_get(RealHandle);
525 Interop.Elementary.elm_object_tooltip_orient_set(RealHandle, (int)value);
530 /// Sets or gets size restriction state of an object's tooltip.
532 public bool TooltipWindowMode
536 return Interop.Elementary.elm_object_tooltip_window_mode_get(RealHandle);
540 Interop.Elementary.elm_object_tooltip_window_mode_set(RealHandle, value);
545 /// Sets the content to be shown in the tooltip object.
547 public GetTooltipContentDelegate TooltipContentDelegate
551 return _tooltipContentDelegate;
555 _tooltipContentDelegate = value;
558 Interop.Elementary.elm_object_tooltip_content_cb_set(RealHandle, _tooltipContentCallback, IntPtr.Zero, null);
562 Interop.Elementary.elm_object_tooltip_content_cb_set(RealHandle, null, IntPtr.Zero, null);
568 /// Gets the movement freeze by 1
569 /// This gets the movement freeze count by one.
571 public int TooltipMoveFreezeCount
575 return Interop.Elementary.elm_object_tooltip_move_freeze_get(RealHandle);
580 /// Sets or gets whether an Evas object is to freeze (discard) events.
582 public bool AllEventsFrozen
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));
592 if (Handle != RealHandle)
594 Interop.Evas.evas_object_freeze_events_set(RealHandle, value);
596 Interop.Evas.evas_object_freeze_events_set(Handle, value);
601 /// Sets or gets the layer of its canvas that the given object will be part of.
603 public virtual int Layer
607 return Interop.Evas.evas_object_layer_get(Handle);
611 Interop.Evas.evas_object_layer_set(Handle, value);
616 /// Clips one object to another.
618 /// <param name="clip">The object to clip object by</param>
619 public void SetClip(EvasObject clip)
621 Interop.Evas.evas_object_clip_set(Handle, clip);
625 /// Sets the hints for an object's alignment.
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)
631 Interop.Evas.evas_object_size_hint_align_set(Handle, x, y);
635 /// Sets the hints for an object's weight.
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)
641 Interop.Evas.evas_object_size_hint_weight_set(Handle, x, y);
645 /// Sets the text for an object's tooltip.
647 /// <param name="text">The text value to display inside the tooltip</param>
648 public void SetTooltipText(string text)
650 Interop.Elementary.elm_object_tooltip_text_set(RealHandle, text);
654 /// Unsets an object's tooltip.
656 public void UnsetTooltip()
658 Interop.Elementary.elm_object_tooltip_unset(RealHandle);
662 /// This increments the tooltip movement freeze count by one.
663 /// If the count is more than 0, the tooltip position will be fixed.
665 public void PushTooltipMoveFreeze()
667 Interop.Elementary.elm_object_tooltip_move_freeze_push(RealHandle);
671 /// This decrements the tooltip freeze count by one.
673 public void PopTooltipMoveFreeze()
675 Interop.Elementary.elm_object_tooltip_move_freeze_pop(RealHandle);
679 /// Force hide tooltip of object.
681 public void HideTooltip()
683 Interop.Elementary.elm_object_tooltip_hide(RealHandle);
687 /// Force show tooltip of object.
689 public void ShowTooltip()
691 Interop.Elementary.elm_object_tooltip_show(RealHandle);
695 /// Makes the current object visible.
699 Interop.Evas.evas_object_show(Handle);
703 /// Makes the current object invisible.
707 Interop.Evas.evas_object_hide(Handle);
711 /// Changes the size of the current object.
713 /// <param name="w">The new width</param>
714 /// <param name="h">The new height</param>
715 public void Resize(int w, int h)
717 Interop.Evas.evas_object_resize(Handle, w, h);
721 /// Moves the current object to the given location.
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)
727 Interop.Evas.evas_object_move(Handle, x, y);
731 /// Lowers obj to the bottom of its layer.
735 Interop.Evas.evas_object_lower(Handle);
739 /// Define IntPtr operator
741 /// <param name="obj">Parent object</param>
742 public static implicit operator IntPtr(EvasObject obj)
750 /// Requests keyname key events be directed to current obj.
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)
757 return Interop.Evas.evas_object_key_grab(Handle, keyname, 0, 0, exclusive);
761 /// Removes the grab on keyname key events.
763 /// <param name="keyname">The key the grab is set for</param>
764 public void KeyUngrab(string keyname)
766 Interop.Evas.evas_object_key_ungrab(Handle, keyname, 0, 0);
770 /// Mark smart object as changed.
772 public void MarkChanged()
774 Interop.Evas.evas_object_smart_changed(RealHandle);
778 /// Call the calculate smart function immediately.
779 /// This will force immediate calculations needed for renderization of this object.
781 public void Calculate()
783 Interop.Evas.evas_object_smart_calculate(RealHandle);
787 /// Sets the hints for an object's aspect ratio.
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)
794 Interop.Evas.evas_object_size_hint_aspect_set(Handle, (int)aspect, w, h);
798 /// Gets the hints for an object's aspect ratio.
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)
806 Interop.Evas.evas_object_size_hint_aspect_get(Handle, out aspectRatio, out w, out h);
807 aspect = (AspectControl)aspectRatio;
811 /// Stack immediately below anchor.
813 /// <param name="anchor">The object below which to stack.</param>
814 public void StackBelow(EvasObject anchor)
816 Interop.Evas.evas_object_stack_below(Handle, anchor);
820 /// Stack immediately above anchor.
822 /// <param name="anchor">The object above which to stack.</param>
823 public void StackAbove(EvasObject anchor)
825 Interop.Evas.evas_object_stack_above(Handle, anchor);
829 /// Raise to the top of its layer.
831 public void RaiseTop()
833 Interop.Evas.evas_object_raise(Handle);
837 /// Get the geometry of a line number.
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)
847 return Interop.Evas.evas_object_textblock_line_number_geometry_get(RealHandle, lineNumber, out x, out y, out w, out h);
850 internal IntPtr GetData(string key)
852 return Interop.Evas.evas_object_data_get(RealHandle, key);
855 internal void SetData(string key, IntPtr data)
857 Interop.Evas.evas_object_data_set(RealHandle, key, data);
860 internal IntPtr DeleteData(string key)
862 return Interop.Evas.evas_object_data_del(RealHandle, key);
866 /// The callback of Invalidate Event
868 protected virtual void OnInvalidate()
873 /// The callback of Instantiated Event
875 protected virtual void OnInstantiated()
880 /// The callback of Realized Event
882 protected virtual void OnRealized()
887 /// The callback of Unrealize Event
889 protected virtual void OnUnrealize()
894 /// Creates a widget handle.
896 /// <param name="parent">Parent EvasObject</param>
897 /// <returns>Handle IntPtr</returns>
898 protected abstract IntPtr CreateHandle(EvasObject parent);
901 /// For this object bind Parent object.Init handle and all kinds of EvasObjectEvent.
903 /// <param name="parent">Parent object</param>
904 public void Realize(EvasObject parent)
909 Handle = CreateHandle(parent);
910 Debug.Assert(Handle != IntPtr.Zero);
912 (parent as Window)?.AddChild(this);
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);
921 _deleted.On += (s, e) => MakeInvalidate();
922 _keydown.On += (s, e) => KeyDown?.Invoke(this, e);
923 _keyup.On += (s, e) => KeyUp?.Invoke(this, e);
928 /// Removes current object relationship with others.
930 public void Unrealize()
934 if (_renderPostCallback != null)
936 Interop.Evas.evas_event_callback_del(Interop.Evas.evas_object_evas_get(Handle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback);
937 _renderPostCallback = null;
941 IntPtr toBeDeleted = Handle;
942 Handle = IntPtr.Zero;
946 (Parent as Window)?.RemoveChild(this);
948 Interop.Evas.evas_object_del(toBeDeleted);
953 private void MakeInvalidate()
955 Deleted?.Invoke(this, EventArgs.Empty);
957 Handle = IntPtr.Zero;
959 MakeInvalidateEvent();
961 (Parent as Window)?.RemoveChild(this);
966 private void DisposeEvent()
968 foreach (var evt in _eventStore)
975 private void MakeInvalidateEvent()
977 foreach (var evt in _eventStore)
979 evt.MakeInvalidate();
984 internal void AddToEventLifeTracker(IInvalidatable item)
986 _eventStore.Add(item);