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;
24 /// Enumeration for tooltip orientation.
26 public enum TooltipOrientation
29 /// Default value, Tooltip moves with mouse pointer.
34 /// Tooltip should appear at the top left of parent.
39 /// Tooltip should appear at the left of parent.
44 /// Tooltip should appear at the top right of parent.
49 /// Tooltip should appear at the left of parent.
54 /// Tooltip should appear at the center of parent.
59 /// Tooltip should appear at the right of parent.
64 /// Tooltip should appear at the bottom left of parent.
69 /// Tooltip should appear at the bottom of parent.
74 /// Tooltip should appear at the bottom right of parent.
80 /// Enumeration for aspect control.
82 public enum AspectControl
85 /// Preference on scaling unset.
90 /// Same effect as unset preference on scaling.
95 /// Use all horizontal container space to place an object, using the given aspect
100 /// Use all vertical container space to place an object, using the given aspect.
105 /// Use all horizontal @b and vertical container spaces to place an object (never growing it out of those bounds), using the given aspect.
111 /// The EcasObject is a base class for other widget class
113 public abstract class EvasObject
115 private IntPtr _realHandle = IntPtr.Zero;
116 private EvasCanvas _evasCanvas;
118 private event EventHandler _backButtonPressed;
120 private event EventHandler _moreButtonPressed;
122 private Interop.Eext.EextEventCallback _backButtonHandler;
123 private Interop.Eext.EextEventCallback _moreButtonHandler;
126 /// Sets or gets the handle for EvasObject.
128 public IntPtr Handle { get; protected set; }
131 /// Gets the parent object for EvasObject.
133 public EvasObject Parent { get; private set; }
136 /// Sets or gets the real handle for EvasObject.
138 public IntPtr RealHandle
142 return _realHandle == IntPtr.Zero ? Handle : _realHandle;
147 Interop.Evas.evas_object_show(_realHandle);
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;
160 GetTooltipContentDelegate _tooltipContentDelegate = null;
162 readonly HashSet<IInvalidatable> _eventStore = new HashSet<IInvalidatable>();
165 /// Creates and initializes a new instance of the EvasObject class with parent EvasObject class parameter.
167 /// <param name="parent">Parent EvasObject class </param>
168 protected EvasObject(EvasObject parent) : this()
170 Debug.Assert(parent == null || parent.IsRealized);
175 /// Creates and initializes a new instance of the EvasObject class.
177 protected EvasObject()
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); });
184 _tooltipContentCallback = (d, o, t) =>
186 return _tooltipContentDelegate?.Invoke();
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.
199 /// Deleted will be triggered when widght is deleted
201 public event EventHandler Deleted;
204 /// KeyUp will be triggered when key is loose
206 public event EventHandler<EvasKeyEventArgs> KeyUp;
209 /// KeyDown will be triggered when key is preesd down
211 public event EventHandler<EvasKeyEventArgs> KeyDown;
214 /// BackButtonPressed will be triggered when Back button is pressed
216 public event EventHandler BackButtonPressed
220 if (_backButtonPressed == null)
222 Interop.Eext.eext_object_event_callback_add(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_BACK, _backButtonHandler, IntPtr.Zero);
224 _backButtonPressed += value;
228 _backButtonPressed -= value;
229 if (_backButtonPressed == null)
231 Interop.Eext.eext_object_event_callback_del(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_BACK, _backButtonHandler);
237 /// MoreButtonPressed will be triggered when More button is pressed
239 public event EventHandler MoreButtonPressed
243 if (_moreButtonPressed == null)
245 Interop.Eext.eext_object_event_callback_add(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_MORE, _moreButtonHandler, IntPtr.Zero);
247 _moreButtonPressed += value;
251 _moreButtonPressed -= value;
252 if (_moreButtonPressed == null)
254 Interop.Eext.eext_object_event_callback_del(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_MORE, _moreButtonHandler);
260 /// Moved will be triggered when widght is moved
262 public event EventHandler Moved
264 add { _moved.On += value; }
265 remove { _moved.On -= value; }
269 /// Current widget's size Resized Event Handler
271 public event EventHandler Resized
273 add { _resized.On += value; }
274 remove { _resized.On -= value; }
278 /// Current widget RenderPost Event Handler
280 public event EventHandler RenderPost
284 _renderPost += value;
285 if (_renderPostCallback == null)
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);
293 _renderPost -= value;
294 if (_renderPost == null)
296 Interop.Evas.evas_event_callback_del(Interop.Evas.evas_object_evas_get(RealHandle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback);
297 _renderPostCallback = null;
303 /// Called back when a widget's tooltip is activated and needs content.
305 /// <returns></returns>
306 public delegate EvasObject GetTooltipContentDelegate();
309 /// Get widget's status of Realized or not.
311 public bool IsRealized { get { return Handle != IntPtr.Zero; } }
316 public EvasCanvas EvasCanvas
320 if (_evasCanvas == null)
321 _evasCanvas = new EvasCanvas(Handle);
327 /// Gets the current class's Name.
329 public string ClassName
333 return Interop.Eo.eo_class_name_get(Interop.Eo.eo_class_get(RealHandle));
338 /// Sets or gets the horizontal pointer hints for an object's weight.
340 public double WeightX
344 return Interop.Evas.GetWeightX(Handle);
348 Interop.Evas.SetWeightX(Handle, value);
353 /// Sets or gets the vertical pointer hints for an object's weight.
355 public double WeightY
359 return Interop.Evas.GetWeightY(Handle);
363 Interop.Evas.SetWeightY(Handle, value);
368 /// Sets or gets the horizontal alignment hint of an object's alignment.
370 public virtual double AlignmentX
374 return Interop.Evas.GetAlignX(Handle);
378 Interop.Evas.SetAlignX(Handle, value);
383 /// Sets or gets the vertical alignment hint of an object's alignment.
385 public virtual double AlignmentY
389 return Interop.Evas.GetAlignY(Handle);
393 Interop.Evas.SetAlignY(Handle, value);
398 /// Sets or gets the Width hints for an object's minimum size.
400 public int MinimumWidth
405 Interop.Evas.evas_object_size_hint_min_get(RealHandle, out w, out h);
410 int h = MinimumHeight;
411 Interop.Evas.evas_object_size_hint_min_set(RealHandle, value, h);
416 /// Sets or gets the Height hints for an object's minimum size.
418 public int MinimumHeight
423 Interop.Evas.evas_object_size_hint_min_get(RealHandle, out w, out h);
428 int w = MinimumWidth;
429 Interop.Evas.evas_object_size_hint_min_set(RealHandle, w, value);
434 /// Gets the visible state of the given Evas object.
436 public bool IsVisible
440 return Interop.Evas.evas_object_visible_get(Handle);
445 /// Sets or gets the position and (rectangular) size of the given Evas object.
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);
458 Interop.Evas.evas_object_geometry_set(Handle, value.X, value.Y, value.Width, value.Height);
463 /// Sets or gets the general or main color of the given Evas object.
465 public virtual Color Color
470 Interop.Evas.evas_object_color_get(RealHandle, out r, out g, out b, out a);
471 return Color.FromRgba(r, g, b, a);
475 Interop.Evas.SetPremultipliedColor(RealHandle, value.R, value.G, value.B, value.A);
480 /// Sets or gets the map enabled state.
482 public bool IsMapEnabled
486 return Interop.Evas.evas_object_map_enable_get(Handle);
490 Interop.Evas.evas_object_map_enable_set(Handle, value);
495 /// Sets or gets current object transformation map.
497 public EvasMap EvasMap
501 IntPtr evasMap = Interop.Evas.evas_object_map_get(Handle);
502 return new EvasMap(evasMap);
506 Interop.Evas.evas_object_map_set(Handle, value.Handle);
511 /// Sets or gets whether an object is to repeat events.
513 public bool RepeatEvents
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));
523 if (Handle != RealHandle)
525 Interop.Evas.evas_object_repeat_events_set(RealHandle, value);
527 Interop.Evas.evas_object_repeat_events_set(Handle, value);
532 /// Sets or gets whether events on a smart object's member should get propagated up to its parent.
534 public bool PropagateEvents
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));
544 if (Handle != RealHandle)
546 Interop.Evas.evas_object_propagate_events_set(RealHandle, value);
548 Interop.Evas.evas_object_propagate_events_set(Handle, value);
553 /// Sets or gets whether an object is set to pass (ignore) events.
555 public bool PassEvents
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));
565 if (Handle != RealHandle)
567 Interop.Evas.evas_object_pass_events_set(RealHandle, value);
569 Interop.Evas.evas_object_pass_events_set(Handle, value);
574 /// Sets or Gets style for this object tooltip.
576 public string TooltipStyle
580 return Interop.Elementary.elm_object_tooltip_style_get(RealHandle);
584 Interop.Elementary.elm_object_tooltip_style_set(RealHandle, value);
589 /// Sets or gets the orientation of Tooltip.
591 public TooltipOrientation TooltipOrientation
595 return (TooltipOrientation)Interop.Elementary.elm_object_tooltip_orient_get(RealHandle);
599 Interop.Elementary.elm_object_tooltip_orient_set(RealHandle, (int)value);
604 /// Sets or gets size restriction state of an object's tooltip.
606 public bool TooltipWindowMode
610 return Interop.Elementary.elm_object_tooltip_window_mode_get(RealHandle);
614 Interop.Elementary.elm_object_tooltip_window_mode_set(RealHandle, value);
619 /// Sets the content to be shown in the tooltip object.
621 public GetTooltipContentDelegate TooltipContentDelegate
625 return _tooltipContentDelegate;
629 _tooltipContentDelegate = value;
632 Interop.Elementary.elm_object_tooltip_content_cb_set(RealHandle, _tooltipContentCallback, IntPtr.Zero, null);
636 Interop.Elementary.elm_object_tooltip_content_cb_set(RealHandle, null, IntPtr.Zero, null);
642 /// Gets the movement freeze by 1
643 /// This gets the movement freeze count by one.
645 public int TooltipMoveFreezeCount
649 return Interop.Elementary.elm_object_tooltip_move_freeze_get(RealHandle);
654 /// Sets or gets whether an Evas object is to freeze (discard) events.
656 public bool AllEventsFrozen
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));
666 if (Handle != RealHandle)
668 Interop.Evas.evas_object_freeze_events_set(RealHandle, value);
670 Interop.Evas.evas_object_freeze_events_set(Handle, value);
675 /// Sets or gets the layer of its canvas that the given object will be part of.
677 public virtual int Layer
681 return Interop.Evas.evas_object_layer_get(Handle);
685 Interop.Evas.evas_object_layer_set(Handle, value);
690 /// Clips one object to another.
692 /// <param name="clip">The object to clip object by</param>
693 public void SetClip(EvasObject clip)
695 Interop.Evas.evas_object_clip_set(Handle, clip);
699 /// Sets the hints for an object's alignment.
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)
705 Interop.Evas.evas_object_size_hint_align_set(Handle, x, y);
709 /// Sets the hints for an object's weight.
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)
715 Interop.Evas.evas_object_size_hint_weight_set(Handle, x, y);
719 /// Sets the text for an object's tooltip.
721 /// <param name="text">The text value to display inside the tooltip</param>
722 public void SetTooltipText(string text)
724 Interop.Elementary.elm_object_tooltip_text_set(RealHandle, text);
728 /// Unsets an object's tooltip.
730 public void UnsetTooltip()
732 Interop.Elementary.elm_object_tooltip_unset(RealHandle);
736 /// This increments the tooltip movement freeze count by one.
737 /// If the count is more than 0, the tooltip position will be fixed.
739 public void PushTooltipMoveFreeze()
741 Interop.Elementary.elm_object_tooltip_move_freeze_push(RealHandle);
745 /// This decrements the tooltip freeze count by one.
747 public void PopTooltipMoveFreeze()
749 Interop.Elementary.elm_object_tooltip_move_freeze_pop(RealHandle);
753 /// Force hide tooltip of object.
755 public void HideTooltip()
757 Interop.Elementary.elm_object_tooltip_hide(RealHandle);
761 /// Force show tooltip of object.
763 public void ShowTooltip()
765 Interop.Elementary.elm_object_tooltip_show(RealHandle);
769 /// Makes the current object visible.
773 Interop.Evas.evas_object_show(Handle);
777 /// Makes the current object invisible.
781 Interop.Evas.evas_object_hide(Handle);
785 /// Changes the size of the current object.
787 /// <param name="w">The new width</param>
788 /// <param name="h">The new height</param>
789 public void Resize(int w, int h)
791 Interop.Evas.evas_object_resize(Handle, w, h);
795 /// Moves the current object to the given location.
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)
801 Interop.Evas.evas_object_move(Handle, x, y);
805 /// Lowers obj to the bottom of its layer.
809 Interop.Evas.evas_object_lower(Handle);
813 /// Define IntPtr operator
815 /// <param name="obj">Parent object</param>
816 public static implicit operator IntPtr(EvasObject obj)
824 /// Requests keyname key events be directed to current obj.
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)
831 return Interop.Evas.evas_object_key_grab(Handle, keyname, 0, 0, exclusive);
835 /// Removes the grab on keyname key events.
837 /// <param name="keyname">The key the grab is set for</param>
838 public void KeyUngrab(string keyname)
840 Interop.Evas.evas_object_key_ungrab(Handle, keyname, 0, 0);
844 /// Mark smart object as changed.
846 public void MarkChanged()
848 Interop.Evas.evas_object_smart_changed(RealHandle);
852 /// Call the calculate smart function immediately.
853 /// This will force immediate calculations needed for renderization of this object.
855 public void Calculate()
857 Interop.Evas.evas_object_smart_calculate(RealHandle);
861 /// Sets the hints for an object's aspect ratio.
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)
868 Interop.Evas.evas_object_size_hint_aspect_set(Handle, (int)aspect, w, h);
872 /// Gets the hints for an object's aspect ratio.
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)
880 Interop.Evas.evas_object_size_hint_aspect_get(Handle, out aspectRatio, out w, out h);
881 aspect = (AspectControl)aspectRatio;
885 /// Stack immediately below anchor.
887 /// <param name="anchor">The object below which to stack.</param>
888 public void StackBelow(EvasObject anchor)
890 Interop.Evas.evas_object_stack_below(Handle, anchor);
894 /// Stack immediately above anchor.
896 /// <param name="anchor">The object above which to stack.</param>
897 public void StackAbove(EvasObject anchor)
899 Interop.Evas.evas_object_stack_above(Handle, anchor);
903 /// Raise to the top of its layer.
905 public void RaiseTop()
907 Interop.Evas.evas_object_raise(Handle);
911 /// Get the geometry of a line number.
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)
921 return Interop.Evas.evas_object_textblock_line_number_geometry_get(RealHandle, lineNumber, out x, out y, out w, out h);
924 internal IntPtr GetData(string key)
926 return Interop.Evas.evas_object_data_get(RealHandle, key);
929 internal void SetData(string key, IntPtr data)
931 Interop.Evas.evas_object_data_set(RealHandle, key, data);
934 internal IntPtr DeleteData(string key)
936 return Interop.Evas.evas_object_data_del(RealHandle, key);
940 /// The callback of Invalidate Event
942 protected virtual void OnInvalidate()
947 /// The callback of Instantiated Event
949 protected virtual void OnInstantiated()
954 /// The callback of Realized Event
956 protected virtual void OnRealized()
961 /// The callback of Unrealize Event
963 protected virtual void OnUnrealize()
968 /// Creates a widget handle.
970 /// <param name="parent">Parent EvasObject</param>
971 /// <returns>Handle IntPtr</returns>
972 protected abstract IntPtr CreateHandle(EvasObject parent);
975 /// For this object bind Parent object.Init handle and all kinds of EvasObjectEvent.
977 /// <param name="parent">Parent object</param>
978 public void Realize(EvasObject parent)
983 Handle = CreateHandle(parent);
984 Debug.Assert(Handle != IntPtr.Zero);
986 (parent as Window)?.AddChild(this);
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);
995 _deleted.On += (s, e) => MakeInvalidate();
996 _keydown.On += (s, e) => KeyDown?.Invoke(this, e);
997 _keyup.On += (s, e) => KeyUp?.Invoke(this, e);
1002 /// Removes current object relationship with others.
1004 public void Unrealize()
1008 if (_renderPostCallback != null)
1010 Interop.Evas.evas_event_callback_del(Interop.Evas.evas_object_evas_get(Handle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback);
1011 _renderPostCallback = null;
1015 IntPtr toBeDeleted = Handle;
1016 Handle = IntPtr.Zero;
1020 (Parent as Window)?.RemoveChild(this);
1022 Interop.Evas.evas_object_del(toBeDeleted);
1027 private void MakeInvalidate()
1029 Deleted?.Invoke(this, EventArgs.Empty);
1031 Handle = IntPtr.Zero;
1033 MakeInvalidateEvent();
1035 (Parent as Window)?.RemoveChild(this);
1040 private void DisposeEvent()
1042 foreach (var evt in _eventStore)
1046 _eventStore.Clear();
1049 private void MakeInvalidateEvent()
1051 foreach (var evt in _eventStore)
1053 evt.MakeInvalidate();
1055 _eventStore.Clear();
1058 internal void AddToEventLifeTracker(IInvalidatable item)
1060 _eventStore.Add(item);