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;
76 EvasObjectEvent _deleted;
77 EvasObjectEvent<EvasKeyEventArgs> _keyup;
78 EvasObjectEvent<EvasKeyEventArgs> _keydown;
79 EvasObjectEvent _moved;
80 EvasObjectEvent _resized;
81 EventHandler _renderPost;
82 Interop.Evas.EvasCallback _renderPostCallback = null;
83 Interop.Elementary.Elm_Tooltip_Content_Cb _tooltipContentCallback = null;
85 GetTooltipContentDelegate _tooltipContentDelegate = null;
87 readonly HashSet<IInvalidatable> _eventStore = new HashSet<IInvalidatable>();
90 /// Creates and initializes a new instance of the EvasObject class with parent EvasObject class parameter.
92 /// <param name="parent">Parent EvasObject class </param>
93 protected EvasObject(EvasObject parent) : this()
95 Debug.Assert(parent == null || parent.IsRealized);
100 /// Creates and initializes a new instance of the EvasObject class.
102 protected EvasObject()
104 _backButtonHandler = new Interop.Eext.EextEventCallback((d, o, i) => { _backButtonPressed?.Invoke(this, EventArgs.Empty); });
105 _moreButtonHandler = new Interop.Eext.EextEventCallback((d, o, i) => { _moreButtonPressed?.Invoke(this, EventArgs.Empty); });
109 _tooltipContentCallback = (d, o, t) =>
111 return _tooltipContentDelegate?.Invoke();
115 // C# Finalizer was called on GC thread
116 // So, We can't access to EFL object
117 // And When Finalizer was called, Field can be already released.
124 /// Deleted will be triggered when widght is deleted
126 public event EventHandler Deleted;
129 /// KeyUp will be triggered when key is loose
131 public event EventHandler<EvasKeyEventArgs> KeyUp;
134 /// KeyDown will be triggered when key is preesd down
136 public event EventHandler<EvasKeyEventArgs> KeyDown;
139 /// BackButtonPressed will be triggered when Back button is pressed
141 public event EventHandler BackButtonPressed
145 if (_backButtonPressed == null)
147 Interop.Eext.eext_object_event_callback_add(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_BACK, _backButtonHandler, IntPtr.Zero);
149 _backButtonPressed += value;
153 _backButtonPressed -= value;
154 if (_backButtonPressed == null)
156 Interop.Eext.eext_object_event_callback_del(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_BACK, _backButtonHandler);
162 /// MoreButtonPressed will be triggered when More button is pressed
164 public event EventHandler MoreButtonPressed
168 if (_moreButtonPressed == null)
170 Interop.Eext.eext_object_event_callback_add(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_MORE, _moreButtonHandler, IntPtr.Zero);
172 _moreButtonPressed += value;
176 _moreButtonPressed -= value;
177 if (_moreButtonPressed == null)
179 Interop.Eext.eext_object_event_callback_del(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_MORE, _moreButtonHandler);
185 /// Moved will be triggered when widght is moved
187 public event EventHandler Moved
189 add { _moved.On += value; }
190 remove { _moved.On -= value; }
194 /// Current widget's size Resized Event Handler
196 public event EventHandler Resized
198 add { _resized.On += value; }
199 remove { _resized.On -= value; }
203 /// Current widget RenderPost Event Handler
205 public event EventHandler RenderPost
209 _renderPost += value;
210 if (_renderPostCallback == null)
212 _renderPostCallback = new Interop.Evas.EvasCallback((o, e, d) => _renderPost?.Invoke(this, EventArgs.Empty));
213 Interop.Evas.evas_event_callback_add(Interop.Evas.evas_object_evas_get(RealHandle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback, IntPtr.Zero);
218 _renderPost -= value;
219 if (_renderPost == null)
221 Interop.Evas.evas_event_callback_del(Interop.Evas.evas_object_evas_get(RealHandle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback);
222 _renderPostCallback = null;
228 /// Called back when a widget's tooltip is activated and needs content.
230 /// <returns></returns>
231 public delegate EvasObject GetTooltipContentDelegate();
234 /// Get widget's status of Realized or not.
236 public bool IsRealized { get { return Handle != IntPtr.Zero; } }
241 public EvasCanvas EvasCanvas
245 if (_evasCanvas == null)
246 _evasCanvas = new EvasCanvas(Handle);
252 /// Gets the current class's Name.
254 public string ClassName
258 return Interop.Eo.eo_class_name_get(Interop.Eo.eo_class_get(RealHandle));
263 /// Sets or gets the horizontal pointer hints for an object's weight.
265 public double WeightX
269 return Interop.Evas.GetWeightX(Handle);
273 Interop.Evas.SetWeightX(Handle, value);
278 /// Sets or gets the vertical pointer hints for an object's weight.
280 public double WeightY
284 return Interop.Evas.GetWeightY(Handle);
288 Interop.Evas.SetWeightY(Handle, value);
293 /// Sets or gets the horizontal alignment hint of an object's alignment.
295 public virtual double AlignmentX
299 return Interop.Evas.GetAlignX(Handle);
303 Interop.Evas.SetAlignX(Handle, value);
308 /// Sets or gets the vertical alignment hint of an object's alignment.
310 public virtual double AlignmentY
314 return Interop.Evas.GetAlignY(Handle);
318 Interop.Evas.SetAlignY(Handle, value);
323 /// Sets or gets the Width hints for an object's minimum size.
325 public int MinimumWidth
330 Interop.Evas.evas_object_size_hint_min_get(RealHandle, out w, out h);
335 int h = MinimumHeight;
336 Interop.Evas.evas_object_size_hint_min_set(RealHandle, value, h);
341 /// Sets or gets the Height hints for an object's minimum size.
343 public int MinimumHeight
348 Interop.Evas.evas_object_size_hint_min_get(RealHandle, out w, out h);
353 int w = MinimumWidth;
354 Interop.Evas.evas_object_size_hint_min_set(RealHandle, w, value);
359 /// Gets the visible state of the given Evas object.
361 public bool IsVisible
365 return Interop.Evas.evas_object_visible_get(Handle);
370 /// Sets or gets the position and (rectangular) size of the given Evas object.
377 Interop.Evas.evas_object_geometry_get(Handle, out x, out y, out w, out h);
378 Rect rect = new Rect(x, y, w, h);
383 Interop.Evas.evas_object_geometry_set(Handle, value.X, value.Y, value.Width, value.Height);
388 /// Sets or gets the general or main color of the given Evas object.
390 public virtual Color Color
395 Interop.Evas.evas_object_color_get(RealHandle, out r, out g, out b, out a);
396 return Color.FromRgba(r, g, b, a);
400 Interop.Evas.SetPremultipliedColor(RealHandle, value.R, value.G, value.B, value.A);
405 /// Sets or gets the map enabled state.
407 public bool IsMapEnabled
411 return Interop.Evas.evas_object_map_enable_get(Handle);
415 Interop.Evas.evas_object_map_enable_set(Handle, value);
420 /// Sets or gets current object transformation map.
422 public EvasMap EvasMap
426 IntPtr evasMap = Interop.Evas.evas_object_map_get(Handle);
427 return new EvasMap(evasMap);
431 Interop.Evas.evas_object_map_set(Handle, value.Handle);
436 /// Sets or gets whether an object is to repeat events.
438 public bool RepeatEvents
442 return Interop.Evas.evas_object_repeat_events_get(RealHandle);
446 Interop.Evas.evas_object_repeat_events_set(RealHandle, value);
451 /// Sets or gets whether events on a smart object's member should get propagated up to its parent.
453 public bool PropagateEvents
457 return Interop.Evas.evas_object_propagate_events_get(RealHandle);
461 Interop.Evas.evas_object_propagate_events_set(RealHandle, value);
466 /// Sets or gets whether an object is set to pass (ignore) events.
468 public bool PassEvents
472 return Interop.Evas.evas_object_pass_events_get(RealHandle);
476 Interop.Evas.evas_object_pass_events_set(RealHandle, value);
481 /// Sets or Gets style for this object tooltip.
483 public string TooltipStyle
487 return Interop.Elementary.elm_object_tooltip_style_get(RealHandle);
491 Interop.Elementary.elm_object_tooltip_style_set(RealHandle, value);
496 /// Sets or gets the orientation of Tooltip.
498 public TooltipOrientation TooltipOrientation
502 return (TooltipOrientation)Interop.Elementary.elm_object_tooltip_orient_get(RealHandle);
506 Interop.Elementary.elm_object_tooltip_orient_set(RealHandle, (int)value);
511 /// Sets or gets size restriction state of an object's tooltip.
513 public bool TooltipWindowMode
517 return Interop.Elementary.elm_object_tooltip_window_mode_get(RealHandle);
521 Interop.Elementary.elm_object_tooltip_window_mode_set(RealHandle, value);
526 /// Sets the content to be shown in the tooltip object.
528 public GetTooltipContentDelegate TooltipContentDelegate
532 return _tooltipContentDelegate;
536 _tooltipContentDelegate = value;
539 Interop.Elementary.elm_object_tooltip_content_cb_set(RealHandle, _tooltipContentCallback, IntPtr.Zero, null);
543 Interop.Elementary.elm_object_tooltip_content_cb_set(RealHandle, null, IntPtr.Zero, null);
549 /// Gets the movement freeze by 1
550 /// This gets the movement freeze count by one.
552 public int TooltipMoveFreezeCount
556 return Interop.Elementary.elm_object_tooltip_move_freeze_get(RealHandle);
561 /// Sets or gets whether an Evas object is to freeze (discard) events.
563 public bool AllEventsFrozen
567 return Interop.Evas.evas_object_freeze_events_get(RealHandle);
571 Interop.Evas.evas_object_freeze_events_set(RealHandle, value);
576 /// Sets or gets the layer of its canvas that the given object will be part of.
578 public virtual int Layer
582 return Interop.Evas.evas_object_layer_get(Handle);
586 Interop.Evas.evas_object_layer_set(Handle, value);
591 /// Clips one object to another.
593 /// <param name="clip">The object to clip object by</param>
594 public void SetClip(EvasObject clip)
596 Interop.Evas.evas_object_clip_set(Handle, clip);
600 /// Sets the hints for an object's alignment.
602 /// <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>
603 /// <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>
604 public void SetAlignment(double x, double y)
606 Interop.Evas.evas_object_size_hint_align_set(Handle, x, y);
610 /// Sets the hints for an object's weight.
612 /// <param name="x">The non-negative double value to use as horizontal weight hint</param>
613 /// <param name="y">The non-negative double value to use as vertical weight hint</param>
614 public void SetWeight(double x, double y)
616 Interop.Evas.evas_object_size_hint_weight_set(Handle, x, y);
620 /// Sets the text for an object's tooltip.
622 /// <param name="text">The text value to display inside the tooltip</param>
623 public void SetTooltipText(string text)
625 Interop.Elementary.elm_object_tooltip_text_set(RealHandle, text);
629 /// Unsets an object's tooltip.
631 public void UnsetTooltip()
633 Interop.Elementary.elm_object_tooltip_unset(RealHandle);
637 /// This increments the tooltip movement freeze count by one.
638 /// If the count is more than 0, the tooltip position will be fixed.
640 public void PushTooltipMoveFreeze()
642 Interop.Elementary.elm_object_tooltip_move_freeze_push(RealHandle);
646 /// This decrements the tooltip freeze count by one.
648 public void PopTooltipMoveFreeze()
650 Interop.Elementary.elm_object_tooltip_move_freeze_pop(RealHandle);
654 /// Force hide tooltip of object.
656 public void HideTooltip()
658 Interop.Elementary.elm_object_tooltip_hide(RealHandle);
662 /// Force show tooltip of object.
664 public void ShowTooltip()
666 Interop.Elementary.elm_object_tooltip_show(RealHandle);
670 /// Makes the current object visible.
674 Interop.Evas.evas_object_show(Handle);
678 /// Makes the current object invisible.
682 Interop.Evas.evas_object_hide(Handle);
686 /// Changes the size of the current object.
688 /// <param name="w">The new width</param>
689 /// <param name="h">The new height</param>
690 public void Resize(int w, int h)
692 Interop.Evas.evas_object_resize(Handle, w, h);
696 /// Moves the current object to the given location.
698 /// <param name="x">The X position to move the object to.</param>
699 /// <param name="y">The Y position to move the object to.</param>
700 public void Move(int x, int y)
702 Interop.Evas.evas_object_move(Handle, x, y);
706 /// Lowers obj to the bottom of its layer.
710 Interop.Evas.evas_object_lower(Handle);
714 /// Define IntPtr operator
716 /// <param name="obj">Parent object</param>
717 public static implicit operator IntPtr(EvasObject obj)
725 /// Requests keyname key events be directed to current obj.
727 /// <param name="keyname">The key to request events for</param>
728 /// <param name="exclusive">Set TRUE to request that the obj is the only object receiving the keyname events,otherwise set FALSE</param>
729 /// <returns>If the call succeeded is true,otherwise is false</returns>
730 public bool KeyGrab(string keyname, bool exclusive)
732 return Interop.Evas.evas_object_key_grab(Handle, keyname, 0, 0, exclusive);
736 /// Removes the grab on keyname key events.
738 /// <param name="keyname">The key the grab is set for</param>
739 public void KeyUngrab(string keyname)
741 Interop.Evas.evas_object_key_ungrab(Handle, keyname, 0, 0);
745 /// Mark smart object as changed.
747 public void MarkChanged()
749 Interop.Evas.evas_object_smart_changed(RealHandle);
753 /// Call the calculate smart function immediately.
754 /// This will force immediate calculations needed for renderization of this object.
756 public void Calculate()
758 Interop.Evas.evas_object_smart_calculate(RealHandle);
762 /// Sets the hints for an object's aspect ratio.
764 /// <param name="aspect">The policy or type of aspect ratio to apply to object</param>
765 /// <param name="w">The integer to use as aspect width ratio term</param>
766 /// <param name="h">The integer to use as aspect height ratio term</param>
767 public void SetSizeHintAspect(AspectControl aspect, int w, int h)
769 Interop.Evas.evas_object_size_hint_aspect_set(Handle, (int)aspect, w, h);
773 /// Gets the hints for an object's aspect ratio.
775 /// <param name="aspect">The policy or type of aspect ratio to apply to object</param>
776 /// <param name="w">The integer to use as aspect width ratio term</param>
777 /// <param name="h">The integer to use as aspect height ratio term</param>
778 public void GetSizeHintAspect(out AspectControl aspect, out int w, out int h)
781 Interop.Evas.evas_object_size_hint_aspect_get(Handle, out aspectRatio, out w, out h);
782 aspect = (AspectControl)aspectRatio;
786 /// Stack immediately below anchor.
788 /// <param name="anchor">The object below which to stack.</param>
789 public void StackBelow(EvasObject anchor)
791 Interop.Evas.evas_object_stack_below(Handle, anchor);
795 /// Stack immediately above anchor.
797 /// <param name="anchor">The object above which to stack.</param>
798 public void StackAbove(EvasObject anchor)
800 Interop.Evas.evas_object_stack_above(Handle, anchor);
804 /// Raise to the top of its layer.
806 public void RaiseTop()
808 Interop.Evas.evas_object_raise(Handle);
812 /// Get the geometry of a line number.
814 /// <param name="lineNumber">the line number.</param>
815 /// <param name="x">x coord of the line.</param>
816 /// <param name="y">y coord of the line.</param>
817 /// <param name="w">w coord of the line.</param>
818 /// <param name="h">h coord of the line.</param>
819 /// <returns></returns>
820 public bool GetTextBlockGeometryByLineNumber(int lineNumber, out int x, out int y, out int w, out int h)
822 return Interop.Evas.evas_object_textblock_line_number_geometry_get(RealHandle, lineNumber, out x, out y, out w, out h);
825 internal IntPtr GetData(string key)
827 return Interop.Evas.evas_object_data_get(RealHandle, key);
830 internal void SetData(string key, IntPtr data)
832 Interop.Evas.evas_object_data_set(RealHandle, key, data);
835 internal IntPtr DeleteData(string key)
837 return Interop.Evas.evas_object_data_del(RealHandle, key);
841 /// The callback of Invalidate Event
843 protected virtual void OnInvalidate()
848 /// The callback of Instantiated Event
850 protected virtual void OnInstantiated()
855 /// The callback of Realized Event
857 protected virtual void OnRealized()
862 /// The callback of Unrealize Event
864 protected virtual void OnUnrealize()
869 /// Creates a widget handle.
871 /// <param name="parent">Parent EvasObject</param>
872 /// <returns>Handle IntPtr</returns>
873 protected abstract IntPtr CreateHandle(EvasObject parent);
876 /// For this object bind Parent object.Init handle and all kinds of EvasObjectEvent.
878 /// <param name="parent">Parent object</param>
879 public void Realize(EvasObject parent)
884 Handle = CreateHandle(parent);
885 Debug.Assert(Handle != IntPtr.Zero);
887 (parent as Window)?.AddChild(this);
890 _deleted = new EvasObjectEvent(this, EvasObjectCallbackType.Del);
891 _keydown = new EvasObjectEvent<EvasKeyEventArgs>(this, RealHandle, EvasObjectCallbackType.KeyDown, EvasKeyEventArgs.Create);
892 _keyup = new EvasObjectEvent<EvasKeyEventArgs>(this, RealHandle, EvasObjectCallbackType.KeyUp, EvasKeyEventArgs.Create);
893 _moved = new EvasObjectEvent(this, EvasObjectCallbackType.Move);
894 _resized = new EvasObjectEvent(this, EvasObjectCallbackType.Resize);
896 _deleted.On += (s, e) => MakeInvalidate();
897 _keydown.On += (s, e) => KeyDown?.Invoke(this, e);
898 _keyup.On += (s, e) => KeyUp?.Invoke(this, e);
903 /// Removes current object relationship with others.
905 public void Unrealize()
909 if (_renderPostCallback != null)
911 Interop.Evas.evas_event_callback_del(Interop.Evas.evas_object_evas_get(Handle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback);
912 _renderPostCallback = null;
916 IntPtr toBeDeleted = Handle;
917 Handle = IntPtr.Zero;
921 (Parent as Window)?.RemoveChild(this);
923 Interop.Evas.evas_object_del(toBeDeleted);
928 private void MakeInvalidate()
930 Deleted?.Invoke(this, EventArgs.Empty);
932 Handle = IntPtr.Zero;
934 MakeInvalidateEvent();
936 (Parent as Window)?.RemoveChild(this);
941 private void DisposeEvent()
943 foreach (var evt in _eventStore)
950 private void MakeInvalidateEvent()
952 foreach (var evt in _eventStore)
954 evt.MakeInvalidate();
959 internal void AddToEventLifeTracker(IInvalidatable item)
961 _eventStore.Add(item);