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 /// The EcasObject is a base class for other widget class
26 public abstract class EvasObject
28 private IntPtr _realHandle = IntPtr.Zero;
29 private event EventHandler _backButtonPressed;
30 private event EventHandler _moreButtonPressed;
31 private Interop.Eext.EextEventCallback _backButtonHandler;
32 private Interop.Eext.EextEventCallback _moreButtonHandler;
34 internal IntPtr Handle { get; set; }
35 internal EvasObject Parent { get; set; }
36 internal IntPtr RealHandle
40 return _realHandle == IntPtr.Zero ? Handle : _realHandle;
48 EvasObjectEvent _deleted;
49 EvasObjectEvent<EvasKeyEventArgs> _keyup;
50 EvasObjectEvent<EvasKeyEventArgs> _keydown;
51 EvasObjectEvent _moved;
52 EvasObjectEvent _resized;
53 EventHandler _renderPost;
54 Interop.Evas.EvasCallback _renderPostCallback = null;
56 readonly HashSet<IInvalidatable> _eventStore = new HashSet<IInvalidatable>();
59 /// Creates and initializes a new instance of the EvasObject class with parent EvasObject class parameter.
61 /// <param name="parent">Parent EvasObject class </param>
62 protected EvasObject(EvasObject parent) : this()
64 Debug.Assert(parent == null || parent.IsRealized);
69 /// Creates and initializes a new instance of the EvasObject class.
71 protected EvasObject()
73 _backButtonHandler = new Interop.Eext.EextEventCallback((d, o, i) => { _backButtonPressed?.Invoke(this, EventArgs.Empty); });
74 _moreButtonHandler = new Interop.Eext.EextEventCallback((d, o, i) => { _moreButtonPressed?.Invoke(this, EventArgs.Empty); });
79 // C# Finalizer was called on GC thread
80 // So, We can't access to EFL object
81 // And When Finalizer was called, Field can be already released.
88 /// Deleted will be triggered when widght is deleted
90 public event EventHandler Deleted;
92 /// KeyUp will be triggered when key is loose
94 public event EventHandler<EvasKeyEventArgs> KeyUp;
96 /// KeyDown will be triggered when key is preesd down
98 public event EventHandler<EvasKeyEventArgs> KeyDown;
101 /// BackButtonPressed will be triggered when Back button is pressed
103 public event EventHandler BackButtonPressed
107 if (_backButtonPressed == null)
109 Interop.Eext.eext_object_event_callback_add(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_BACK, _backButtonHandler, IntPtr.Zero);
111 _backButtonPressed += value;
115 _backButtonPressed -= value;
116 if (_backButtonPressed == null)
118 Interop.Eext.eext_object_event_callback_del(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_BACK, _backButtonHandler);
124 /// MoreButtonPressed will be triggered when More button is pressed
126 public event EventHandler MoreButtonPressed
130 if (_moreButtonPressed == null)
132 Interop.Eext.eext_object_event_callback_add(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_MORE, _moreButtonHandler, IntPtr.Zero);
134 _moreButtonPressed += value;
138 _moreButtonPressed -= value;
139 if (_moreButtonPressed == null)
141 Interop.Eext.eext_object_event_callback_del(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_MORE, _moreButtonHandler);
148 /// Moved will be triggered when widght is moved
150 public event EventHandler Moved
152 add { _moved.On += value; }
153 remove { _moved.On -= value; }
156 /// Current widget's size Resized Event Handler
158 public event EventHandler Resized
160 add { _resized.On += value; }
161 remove { _resized.On -= value; }
165 /// Current widget RenderPost Event Handler
167 public event EventHandler RenderPost
171 _renderPost += value;
172 if (_renderPostCallback == null)
174 _renderPostCallback = new Interop.Evas.EvasCallback((o, e, d) => _renderPost?.Invoke(this, EventArgs.Empty));
175 Interop.Evas.evas_event_callback_add(Interop.Evas.evas_object_evas_get(RealHandle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback, IntPtr.Zero);
180 _renderPost -= value;
181 if (_renderPost?.GetInvocationList().Length == 0)
183 Interop.Evas.evas_event_callback_del(Interop.Evas.evas_object_evas_get(RealHandle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback);
184 _renderPostCallback = null;
190 /// Get widget's status of Realized or not.
192 public bool IsRealized { get { return Handle != IntPtr.Zero; } }
195 /// Gets the current class's Name.
197 public string ClassName
201 return Interop.Eo.eo_class_name_get(Interop.Eo.eo_class_get(RealHandle));
206 /// Sets or gets the horizontal pointer hints for an object's weight.
208 public double WeightX
212 return Interop.Evas.GetWeightX(Handle);
216 Interop.Evas.SetWeightX(Handle, value);
221 /// Sets or gets the vertical pointer hints for an object's weight.
223 public double WeightY
227 return Interop.Evas.GetWeightY(Handle);
231 Interop.Evas.SetWeightY(Handle, value);
236 /// Sets or gets the horizontal alignment hint of an object's alignment.
238 public virtual double AlignmentX
242 return Interop.Evas.GetAlignX(Handle);
246 Interop.Evas.SetAlignX(Handle, value);
251 /// Sets or gets the vertical alignment hint of an object's alignment.
253 public virtual double AlignmentY
257 return Interop.Evas.GetAlignY(Handle);
261 Interop.Evas.SetAlignY(Handle, value);
266 /// Sets or gets the Width hints for an object's minimum size.
268 public int MinimumWidth
273 Interop.Evas.evas_object_size_hint_min_get(RealHandle, out w, out h);
278 int h = MinimumHeight;
279 Interop.Evas.evas_object_size_hint_min_set(RealHandle, value, h);
284 /// Sets or gets the Height hints for an object's minimum size.
286 public int MinimumHeight
291 Interop.Evas.evas_object_size_hint_min_get(RealHandle, out w, out h);
296 int w = MinimumWidth;
297 Interop.Evas.evas_object_size_hint_min_set(RealHandle, w, value);
302 /// Gets the visible state of the given Evas object.
304 public bool IsVisible
308 return Interop.Evas.evas_object_visible_get(Handle);
313 /// Sets or gets the position and (rectangular) size of the given Evas object.
320 Interop.Evas.evas_object_geometry_get(Handle, out x, out y, out w, out h);
321 Rect rect = new Rect(x, y, w, h);
326 Interop.Evas.evas_object_geometry_set(Handle, value.X, value.Y, value.Width, value.Height);
331 /// Sets or gets the general or main color of the given Evas object.
333 public virtual Color Color
338 Interop.Evas.evas_object_color_get(RealHandle, out r, out g, out b, out a);
339 return Color.FromRgba(r, g, b, a);
343 Interop.Evas.SetPremultipliedColor(RealHandle, value.R, value.G, value.B, value.A);
348 /// Sets or gets the map enabled state.
350 public bool IsMapEnabled
354 return Interop.Evas.evas_object_map_enable_get(Handle);
358 Interop.Evas.evas_object_map_enable_set(Handle, value);
363 /// Sets or gets current object transformation map.
365 public EvasMap EvasMap
369 IntPtr evasMap = Interop.Evas.evas_object_map_get(Handle);
370 return new EvasMap(evasMap);
374 Interop.Evas.evas_object_map_set(Handle, value.Handle);
379 /// Sets or gets whether an object is to repeat events.
381 public bool RepeatEvents
385 return Interop.Evas.evas_object_repeat_events_get(RealHandle);
389 Interop.Evas.evas_object_repeat_events_set(RealHandle, value);
394 /// Sets or gets whether events on a smart object's member should get propagated up to its parent.
396 public bool PropagateEvents
400 return Interop.Evas.evas_object_propagate_events_get(RealHandle);
404 Interop.Evas.evas_object_propagate_events_set(RealHandle, value);
409 /// Sets or gets whether an object is set to pass (ignore) events.
411 public bool PassEvents
415 return Interop.Evas.evas_object_pass_events_get(RealHandle);
419 Interop.Evas.evas_object_pass_events_set(RealHandle, value);
424 /// Clips one object to another.
426 /// <param name="clip">The object to clip object by</param>
427 public void SetClip(EvasObject clip)
429 Interop.Evas.evas_object_clip_set(Handle, clip);
433 /// Sets the hints for an object's alignment.
435 /// <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>
436 /// <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>
437 public void SetAlignment(double x, double y)
439 Interop.Evas.evas_object_size_hint_align_set(Handle, x, y);
443 /// Sets the hints for an object's weight.
445 /// <param name="x">The non-negative double value to use as horizontal weight hint</param>
446 /// <param name="y">The non-negative double value to use as vertical weight hint</param>
447 public void SetWeight(double x, double y)
449 Interop.Evas.evas_object_size_hint_weight_set(Handle, x, y);
453 /// Sets the text for an object's tooltip.
455 /// <param name="text">The text value to display inside the tooltip</param>
456 public void SetTooltipText(string text)
458 Interop.Elementary.elm_object_tooltip_text_set(RealHandle, text);
462 /// Unsets an object's tooltip.
464 public void UnsetTooltip()
466 Interop.Elementary.elm_object_tooltip_unset(RealHandle);
470 /// Makes the current object visible.
474 Interop.Evas.evas_object_show(Handle);
478 /// Makes the current object invisible.
482 Interop.Evas.evas_object_hide(Handle);
486 /// Changes the size of the current object.
488 /// <param name="w">The new width</param>
489 /// <param name="h">The new height</param>
490 public void Resize(int w, int h)
492 Interop.Evas.evas_object_resize(Handle, w, h);
496 /// Moves the current object to the given location.
498 /// <param name="x">The X position to move the object to.</param>
499 /// <param name="y">The Y position to move the object to.</param>
500 public void Move(int x, int y)
502 Interop.Evas.evas_object_move(Handle, x, y);
506 /// Lowers obj to the bottom of its layer.
510 Interop.Evas.evas_object_lower(Handle);
514 /// Define IntPtr operator
516 /// <param name="obj">Parent object</param>
517 public static implicit operator IntPtr(EvasObject obj)
525 /// Requests keyname key events be directed to current obj.
527 /// <param name="keyname">The key to request events for</param>
528 /// <param name="exclusive">Set TRUE to request that the obj is the only object receiving the keyname events,otherwise set FALSE</param>
529 /// <returns>If the call succeeded is true,otherwise is false</returns>
530 public bool KeyGrab(string keyname, bool exclusive)
532 return Interop.Evas.evas_object_key_grab(Handle, keyname, 0, 0, exclusive);
536 /// Removes the grab on keyname key events.
538 /// <param name="keyname">The key the grab is set for</param>
539 public void KeyUngrab(string keyname)
541 Interop.Evas.evas_object_key_ungrab(Handle, keyname, 0, 0);
545 /// Mark smart object as changed.
547 public void MarkChanged()
549 Interop.Evas.evas_object_smart_changed(RealHandle);
553 /// The callback of Invalidate Event
555 protected virtual void OnInvalidate()
560 /// The callback of Instantiated Event
562 protected virtual void OnInstantiated()
566 /// The callback of Realized Event
568 protected virtual void OnRealized()
572 /// The callback of Unrealize Event
574 protected virtual void OnUnrealize()
578 /// Creates a widget handle.
580 /// <param name="parent">Parent EvasObject</param>
581 /// <returns>Handle IntPtr</returns>
582 protected abstract IntPtr CreateHandle(EvasObject parent);
585 /// For this object bind Parent object.Init handle and all kinds of EvasObjectEvent.
587 /// <param name="parent">Parent object</param>
588 public void Realize(EvasObject parent)
593 Handle = CreateHandle(parent);
594 Debug.Assert(Handle != IntPtr.Zero);
596 (parent as Window)?.AddChild(this);
599 _deleted = new EvasObjectEvent(this, EvasObjectCallbackType.Del);
600 _keydown = new EvasObjectEvent<EvasKeyEventArgs>(this, EvasObjectCallbackType.KeyDown, EvasKeyEventArgs.Create);
601 _keyup = new EvasObjectEvent<EvasKeyEventArgs>(this, EvasObjectCallbackType.KeyUp, EvasKeyEventArgs.Create);
602 _moved = new EvasObjectEvent(this, EvasObjectCallbackType.Move);
603 _resized = new EvasObjectEvent(this, EvasObjectCallbackType.Resize);
605 _deleted.On += (s, e) => MakeInvalidate();
606 _keydown.On += (s, e) => KeyDown?.Invoke(this, e);
607 _keyup.On += (s, e) => KeyUp?.Invoke(this, e);
612 /// Removes current object relationship with others.
614 public void Unrealize()
618 if(_renderPostCallback != null)
620 Interop.Evas.evas_event_callback_del(Interop.Evas.evas_object_evas_get(Handle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback);
621 _renderPostCallback = null;
625 IntPtr toBeDeleted = Handle;
626 Handle = IntPtr.Zero;
630 (Parent as Window)?.RemoveChild(this);
632 Interop.Evas.evas_object_del(toBeDeleted);
637 private void MakeInvalidate()
639 Deleted?.Invoke(this, EventArgs.Empty);
641 Handle = IntPtr.Zero;
643 MakeInvalidateEvent();
645 (Parent as Window)?.RemoveChild(this);
650 private void DisposeEvent()
652 foreach (var evt in _eventStore)
658 private void MakeInvalidateEvent()
660 foreach (var evt in _eventStore)
662 evt.MakeInvalidate();
667 internal void AddToEventLifeTracker(IInvalidatable item)
669 _eventStore.Add(item);