/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace ElmSharp
{
///
/// Enumeration for the Tooltip orientation.
///
/// preview
public enum TooltipOrientation
{
///
/// Default value. Tooltip moves with a mouse pointer.
///
None,
///
/// Tooltip should appear to the top left of the parent.
///
TopLeft,
///
/// Tooltip should appear to the left of the parent.
///
Top,
///
/// Tooltip should appear to the top right of the parent.
///
TopRight,
///
/// Tooltip should appear to the left of the parent.
///
Left,
///
/// Tooltip should appear to the center of the parent.
///
Center,
///
/// Tooltip should appear to the right of the parent.
///
Right,
///
/// Tooltip should appear to the bottom left of the parent.
///
BottomLeft,
///
/// Tooltip should appear to the bottom of the parent.
///
Bottom,
///
/// Tooltip should appear to the bottom right of the parent.
///
BottomRight,
}
///
/// Enumeration for the aspect control.
///
/// preview
public enum AspectControl
{
///
/// Preference on the scaling unset.
///
None = 0,
///
/// Same effect as the unset preference on the scaling.
///
Neither = 1,
///
/// Use all horizontal container space to place an object using the given aspect.
///
Horizontal = 2,
///
/// Use all vertical container space to place an object using the given aspect.
///
Vertical = 3,
///
/// Use all horizontal @b and vertical container spaces to place an object (never growing it out of those bounds), using the given aspect.
///
Both = 4
}
///
/// How the object should be rendered to output.
///
/// 5
public enum RenderOp
{
///
/// default op: d = d * (1 - sa) + s
///
Blend = 0,
///
/// d = d*(1 - sa) + s*da
///
BlendRel = 1,
///
/// d = s
///
Copy = 2,
///
/// d = s*da
///
CopyRel = 3,
///
/// d = d + s
///
Add = 4,
///
/// d = d + s*da
///
AddRel = 5,
///
/// d = d - s
///
Sub = 6,
///
/// d = d - s*da
///
SubRel = 7,
///
/// d = d*s + d*(1 - sa) + s*(1 - da)
///
Tint = 8,
///
/// d = d*(1 - sa + s)
///
TintRel = 9,
///
/// d = d*sa
///
Mask = 10,
///
/// d = d*s
///
Mul = 11
}
///
/// The EvasObject is a base class for other widget classes.
///
/// preview
public abstract class EvasObject
{
private IntPtr _realHandle = IntPtr.Zero;
private EvasCanvas _evasCanvas;
private string _automationId;
private event EventHandler _backButtonPressed;
private event EventHandler _moreButtonPressed;
private Interop.Eext.EextEventCallback _backButtonHandler;
private Interop.Eext.EextEventCallback _moreButtonHandler;
private static Dictionary s_handleTable = new Dictionary();
///
/// Sets or gets the handle for EvasObject.
///
/// preview
public IntPtr Handle { get; protected set; }
///
/// Gets the parent object for EvasObject.
///
/// preview
public EvasObject Parent { get; private set; }
///
/// Sets or gets the real handle for EvasObject.
///
/// preview
public IntPtr RealHandle
{
get
{
return _realHandle == IntPtr.Zero ? Handle : _realHandle;
}
protected set
{
_realHandle = value;
Interop.Evas.evas_object_show(_realHandle);
}
}
EvasObjectEvent _deleted;
EvasObjectEvent _keyup;
EvasObjectEvent _keydown;
EvasObjectEvent _moved;
EvasObjectEvent _resized;
EvasObjectEvent _shown;
EvasObjectEvent _hidden;
EventHandler _renderPost;
Interop.Evas.EvasCallback _renderPostCallback = null;
Interop.Elementary.Elm_Tooltip_Content_Cb _tooltipContentCallback = null;
GetTooltipContentDelegate _tooltipContentDelegate = null;
readonly HashSet _eventStore = new HashSet();
///
/// Creates and initializes a new instance of the EvasObject class with the parent EvasObject class parameter.
///
/// Parent EvasObject class.
/// preview
protected EvasObject(EvasObject parent) : this()
{
Debug.Assert(parent == null || parent.IsRealized);
Realize(parent);
}
///
/// Creates and initializes a new instance of the EvasObject class.
///
/// preview
protected EvasObject()
{
_backButtonHandler = new Interop.Eext.EextEventCallback((d, o, i) => { _backButtonPressed?.Invoke(this, EventArgs.Empty); });
_moreButtonHandler = new Interop.Eext.EextEventCallback((d, o, i) => { _moreButtonPressed?.Invoke(this, EventArgs.Empty); });
OnInstantiated();
_tooltipContentCallback = (d, o, t) =>
{
return _tooltipContentDelegate?.Invoke();
};
}
// C# Finalizer was called on GC thread
// So, We can't access to EFL object
// And When Finalizer was called, Field can be already released.
//~EvasObject()
//{
// Unrealize();
//}
///
/// Deleted will be triggered when the widght is deleted.
///
/// preview
public event EventHandler Deleted;
///
/// KeyUp will be triggered when the key is loose.
///
/// preview
public event EventHandler KeyUp
{
add { _keyup.On += value; }
remove { _keyup.On -= value; }
}
///
/// KeyDown will be triggered when the key is pressed down.
///
/// preview
public event EventHandler KeyDown
{
add { _keydown.On += value; }
remove { _keydown.On -= value; }
}
///
/// BackButtonPressed will be triggered when the Back button is pressed.
///
/// preview
public event EventHandler BackButtonPressed
{
add
{
if (_backButtonPressed == null)
{
Interop.Eext.eext_object_event_callback_add(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_BACK, _backButtonHandler, IntPtr.Zero);
}
_backButtonPressed += value;
}
remove
{
_backButtonPressed -= value;
if (_backButtonPressed == null)
{
Interop.Eext.eext_object_event_callback_del(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_BACK, _backButtonHandler);
}
}
}
///
/// MoreButtonPressed will be triggered when the More button is pressed.
///
/// preview
public event EventHandler MoreButtonPressed
{
add
{
if (_moreButtonPressed == null)
{
Interop.Eext.eext_object_event_callback_add(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_MORE, _moreButtonHandler, IntPtr.Zero);
}
_moreButtonPressed += value;
}
remove
{
_moreButtonPressed -= value;
if (_moreButtonPressed == null)
{
Interop.Eext.eext_object_event_callback_del(RealHandle, Interop.Eext.EextCallbackType.EEXT_CALLBACK_MORE, _moreButtonHandler);
}
}
}
///
/// Moved will be triggered when the widght is moved.
///
/// preview
public event EventHandler Moved
{
add { _moved.On += value; }
remove { _moved.On -= value; }
}
///
/// Resized Event Handler of the current widget's size.
///
/// preview
public event EventHandler Resized
{
add { _resized.On += value; }
remove { _resized.On -= value; }
}
///
/// Shown will be triggered when the widget is shown.
///
/// preview
public event EventHandler Shown
{
add { _shown.On += value; }
remove { _shown.On -= value; }
}
///
/// Hidden will be triggered when the widget is hidden.
///
/// preview
public event EventHandler Hidden
{
add { _hidden.On += value; }
remove { _hidden.On -= value; }
}
///
/// RenderPost Event Handler of the current widget.
///
/// preview
public event EventHandler RenderPost
{
add
{
_renderPost += value;
if (_renderPostCallback == null)
{
_renderPostCallback = new Interop.Evas.EvasCallback((o, e, d) => _renderPost?.Invoke(this, EventArgs.Empty));
Interop.Evas.evas_event_callback_add(Interop.Evas.evas_object_evas_get(RealHandle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback, IntPtr.Zero);
}
}
remove
{
_renderPost -= value;
if (_renderPost == null)
{
Interop.Evas.evas_event_callback_del(Interop.Evas.evas_object_evas_get(RealHandle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback);
_renderPostCallback = null;
}
}
}
///
/// Called when a widget's tooltip is activated and needs content.
///
///
/// preview
public delegate EvasObject GetTooltipContentDelegate();
///
/// Gets a widget's status of realized or not.
///
/// preview
public bool IsRealized { get { return Handle != IntPtr.Zero; } }
///
/// Gets EvasCanvas.
///
/// preview
public EvasCanvas EvasCanvas
{
get
{
if (_evasCanvas == null)
_evasCanvas = new EvasCanvas(Handle);
return _evasCanvas;
}
}
///
/// Sets of gets a value that allow the automation framework to find and interact with this object.
///
/// preview
public string AutomationId
{
get
{
return _automationId;
}
set
{
if (_automationId != null)
throw new InvalidOperationException("AutomationId may only be set one time.");
_automationId = value;
}
}
///
/// Gets the current class's Name.
///
/// preview
public string ClassName
{
get
{
return Interop.Eo.efl_class_name_get(Interop.Eo.efl_class_get(RealHandle));
}
}
///
/// Sets or gets the horizontal pointer hints for an object's weight.
///
/// preview
public double WeightX
{
get
{
return Interop.Evas.GetWeightX(Handle);
}
set
{
Interop.Evas.SetWeightX(Handle, value);
}
}
///
/// Sets or gets the vertical pointer hints for an object's weight.
///
/// preview
public double WeightY
{
get
{
return Interop.Evas.GetWeightY(Handle);
}
set
{
Interop.Evas.SetWeightY(Handle, value);
}
}
///
/// Sets or gets the horizontal alignment hint of an object's alignment.
///
/// preview
public virtual double AlignmentX
{
get
{
return Interop.Evas.GetAlignX(Handle);
}
set
{
Interop.Evas.SetAlignX(Handle, value);
}
}
///
/// Sets or gets the vertical alignment hint of an object's alignment.
///
/// preview
public virtual double AlignmentY
{
get
{
return Interop.Evas.GetAlignY(Handle);
}
set
{
Interop.Evas.SetAlignY(Handle, value);
}
}
///
/// Sets or gets the width hints for an object's minimum size.
///
/// preview
public int MinimumWidth
{
get
{
int w, h;
Interop.Evas.evas_object_size_hint_min_get(RealHandle, out w, out h);
return w;
}
set
{
int h = MinimumHeight;
Interop.Evas.evas_object_size_hint_min_set(RealHandle, value, h);
}
}
///
/// Sets or gets the height hints for an object's minimum size.
///
/// preview
public int MinimumHeight
{
get
{
int w, h;
Interop.Evas.evas_object_size_hint_min_get(RealHandle, out w, out h);
return h;
}
set
{
int w = MinimumWidth;
Interop.Evas.evas_object_size_hint_min_set(RealHandle, w, value);
}
}
///
/// Gets the visible state of the given Evas object.
///
/// preview
public bool IsVisible
{
get
{
return Interop.Evas.evas_object_visible_get(Handle);
}
}
///
/// Sets or gets the position and (rectangular) size of the given Evas object.
///
/// preview
public Rect Geometry
{
get
{
int x, y, w, h;
Interop.Evas.evas_object_geometry_get(Handle, out x, out y, out w, out h);
Rect rect = new Rect(x, y, w, h);
return rect;
}
set
{
Interop.Evas.evas_object_geometry_set(Handle, value.X, value.Y, value.Width, value.Height);
}
}
///
/// Sets or gets the general or main color of the given Evas object.
///
/// preview
public virtual Color Color
{
get
{
int r, g, b, a;
Interop.Evas.evas_object_color_get(RealHandle, out r, out g, out b, out a);
return Color.FromRgba(r, g, b, a);
}
set
{
Interop.Evas.SetPremultipliedColor(RealHandle, value.R, value.G, value.B, value.A);
}
}
///
/// Sets or gets the map enabled state.
///
/// preview
public bool IsMapEnabled
{
get
{
return Interop.Evas.evas_object_map_enable_get(Handle);
}
set
{
Interop.Evas.evas_object_map_enable_set(Handle, value);
}
}
///
/// Sets or gets the current object's transformation map.
///
/// preview
public EvasMap EvasMap
{
get
{
IntPtr evasMap = Interop.Evas.evas_object_map_get(Handle);
return new EvasMap(evasMap);
}
set
{
Interop.Evas.evas_object_map_set(Handle, value.Handle);
}
}
///
/// Sets or gets whether an object is to repeat events.
///
/// preview
public bool RepeatEvents
{
get
{
var result = Interop.Evas.evas_object_repeat_events_get(Handle);
Debug.Assert(Handle == RealHandle || result == Interop.Evas.evas_object_repeat_events_get(RealHandle));
return result;
}
set
{
if (Handle != RealHandle)
{
Interop.Evas.evas_object_repeat_events_set(RealHandle, value);
}
Interop.Evas.evas_object_repeat_events_set(Handle, value);
}
}
///
/// Sets or gets whether events on a smart object's member should get propagated up to its parent.
///
/// preview
public bool PropagateEvents
{
get
{
var result = Interop.Evas.evas_object_propagate_events_get(Handle);
Debug.Assert(Handle == RealHandle || result == Interop.Evas.evas_object_propagate_events_get(RealHandle));
return result;
}
set
{
if (Handle != RealHandle)
{
Interop.Evas.evas_object_propagate_events_set(RealHandle, value);
}
Interop.Evas.evas_object_propagate_events_set(Handle, value);
}
}
///
/// Sets or gets whether an object is set to pass (ignore) events.
///
/// preview
public bool PassEvents
{
get
{
var result = Interop.Evas.evas_object_pass_events_get(Handle);
Debug.Assert(Handle == RealHandle || result == Interop.Evas.evas_object_pass_events_get(RealHandle));
return result;
}
set
{
if (Handle != RealHandle)
{
Interop.Evas.evas_object_pass_events_set(RealHandle, value);
}
Interop.Evas.evas_object_pass_events_set(Handle, value);
}
}
///
/// Sets or gets the style for this object tooltip.
///
/// preview
public string TooltipStyle
{
get
{
return Interop.Elementary.elm_object_tooltip_style_get(RealHandle);
}
set
{
Interop.Elementary.elm_object_tooltip_style_set(RealHandle, value);
}
}
///
/// Sets or gets the orientation of tooltip.
///
/// preview
public TooltipOrientation TooltipOrientation
{
get
{
return (TooltipOrientation)Interop.Elementary.elm_object_tooltip_orient_get(RealHandle);
}
set
{
Interop.Elementary.elm_object_tooltip_orient_set(RealHandle, (int)value);
}
}
///
/// Sets or gets size restriction state of an object's tooltip.
///
/// preview
public bool TooltipWindowMode
{
get
{
return Interop.Elementary.elm_object_tooltip_window_mode_get(RealHandle);
}
set
{
Interop.Elementary.elm_object_tooltip_window_mode_set(RealHandle, value);
}
}
///
/// Sets the content to be shown in the tooltip object.
///
/// preview
public GetTooltipContentDelegate TooltipContentDelegate
{
get
{
return _tooltipContentDelegate;
}
set
{
_tooltipContentDelegate = value;
if (value != null)
{
Interop.Elementary.elm_object_tooltip_content_cb_set(RealHandle, _tooltipContentCallback, IntPtr.Zero, null);
}
else
{
Interop.Elementary.elm_object_tooltip_content_cb_set(RealHandle, null, IntPtr.Zero, null);
}
}
}
///
/// Gets the movement freeze by 1.
/// This gets the movement freeze count by one.
///
/// preview
public int TooltipMoveFreezeCount
{
get
{
return Interop.Elementary.elm_object_tooltip_move_freeze_get(RealHandle);
}
}
///
/// Sets or gets whether an Evas object is to freeze (discard) events.
///
/// preview
public bool AllEventsFrozen
{
get
{
var result = Interop.Evas.evas_object_freeze_events_get(Handle);
Debug.Assert(Handle == RealHandle || result == Interop.Evas.evas_object_freeze_events_get(RealHandle));
return result;
}
set
{
if (Handle != RealHandle)
{
Interop.Evas.evas_object_freeze_events_set(RealHandle, value);
}
Interop.Evas.evas_object_freeze_events_set(Handle, value);
}
}
///
/// Sets or gets the layer of its canvas that the given object will be part of.
///
/// preview
public virtual int Layer
{
get
{
return Interop.Evas.evas_object_layer_get(Handle);
}
set
{
Interop.Evas.evas_object_layer_set(Handle, value);
}
}
///
/// Sets or gets the render operation to be used for rendering the Evas object.
///
/// 5
public RenderOp RenderOperation
{
get
{
return (RenderOp)Interop.Evas.evas_object_render_op_get(RealHandle);
}
set
{
Interop.Evas.evas_object_render_op_set(RealHandle, (Interop.Evas.RenderOp)value);
}
}
///
/// Clips one object to another.
///
/// The object to clip object by.
/// preview
public void SetClip(EvasObject clip)
{
Interop.Evas.evas_object_clip_set(Handle, clip);
}
///
/// Sets the hints for an object's alignment.
///
/// The horizontal alignment hint as double value ranging from 0.0 to 1.0. The default alignment hint value is 0.5.
/// The vertical alignment hint as double value ranging from 0.0 to 1.0. The default alignment hint value is 0.5.
/// preview
public void SetAlignment(double x, double y)
{
Interop.Evas.evas_object_size_hint_align_set(Handle, x, y);
}
///
/// Sets the hints for an object's weight.
///
/// The non-negative double value to be used as horizontal weight hint.
/// The non-negative double value to be used as vertical weight hint.
/// preview
public void SetWeight(double x, double y)
{
Interop.Evas.evas_object_size_hint_weight_set(Handle, x, y);
}
///
/// Sets the text for an object's tooltip.
///
/// The text value to display inside the tooltip.
/// preview
public void SetTooltipText(string text)
{
Interop.Elementary.elm_object_tooltip_text_set(RealHandle, text);
}
///
/// Unsets an object's tooltip.
///
/// preview
public void UnsetTooltip()
{
Interop.Elementary.elm_object_tooltip_unset(RealHandle);
}
///
/// This increments the tooltip movement freeze count by one.
/// If the count is more than 0, the tooltip position will be fixed.
///
/// preview
public void PushTooltipMoveFreeze()
{
Interop.Elementary.elm_object_tooltip_move_freeze_push(RealHandle);
}
///
/// This decrements the tooltip freeze count by one.
///
/// preview
public void PopTooltipMoveFreeze()
{
Interop.Elementary.elm_object_tooltip_move_freeze_pop(RealHandle);
}
///
/// Force hide the tooltip of the object.
///
/// preview
public void HideTooltip()
{
Interop.Elementary.elm_object_tooltip_hide(RealHandle);
}
///
/// Force show the tooltip of the object.
///
/// preview
public void ShowTooltip()
{
Interop.Elementary.elm_object_tooltip_show(RealHandle);
}
///
/// Makes the current object visible.
///
/// preview
public void Show()
{
Interop.Evas.evas_object_show(Handle);
}
///
/// Makes the current object invisible.
///
/// preview
public void Hide()
{
Interop.Evas.evas_object_hide(Handle);
}
///
/// Changes the size of the current object.
///
/// The new width.
/// The new height.
/// preview
public void Resize(int w, int h)
{
Interop.Evas.evas_object_resize(Handle, w, h);
}
///
/// Moves the current object to the given location.
///
/// The X position to move the object.
/// The Y position to move the object.
/// preview
public void Move(int x, int y)
{
Interop.Evas.evas_object_move(Handle, x, y);
}
///
/// Lowers the object to the bottom of its layer.
///
/// preview
public void Lower()
{
Interop.Evas.evas_object_lower(Handle);
}
///
/// Define the IntPtr operator.
///
/// Parent object.
/// preview
public static implicit operator IntPtr(EvasObject obj)
{
if (obj == null)
return IntPtr.Zero;
return obj.Handle;
}
///
/// Define cast to EvasObject operator from IntPtr
///
/// Native handle to EvasObject
/// preview
public static explicit operator EvasObject(IntPtr handle) => EvasObject.s_handleTable.TryGetValue(handle, out EvasObject obj) ? obj : null;
///
/// Requests the keyname key events to be directed to the current object.
///
/// The key to request events for.
/// Set TRUE to request that the obj is the only object receiving the keyname events, otherwise set to FALSE.
/// If the call succeeds then true, otherwise false.
/// preview
public bool KeyGrab(string keyname, bool exclusive)
{
return Interop.Evas.evas_object_key_grab(Handle, keyname, 0, 0, exclusive);
}
///
/// Removes the grab on the keyname key events.
///
/// The key the grab is set for.
/// preview
public void KeyUngrab(string keyname)
{
Interop.Evas.evas_object_key_ungrab(Handle, keyname, 0, 0);
}
///
/// Marks the smart object as changed.
///
/// preview
public void MarkChanged()
{
Interop.Evas.evas_object_smart_changed(RealHandle);
}
///
/// Calls the calculate smart function immediately.
/// This will force immediate calculations needed for renderization of this object.
///
/// preview
public void Calculate()
{
Interop.Evas.evas_object_smart_calculate(RealHandle);
}
///
/// Sets the hints for an object's aspect ratio.
///
/// The policy or type of aspect ratio to apply to an object.
/// The integer to be used as aspect width ratio term.
/// The integer to be used as aspect height ratio term.
/// preview
public void SetSizeHintAspect(AspectControl aspect, int w, int h)
{
Interop.Evas.evas_object_size_hint_aspect_set(Handle, (int)aspect, w, h);
}
///
/// Gets the hints for an object's aspect ratio.
///
/// The policy or type of aspect ratio to apply to an object.
/// The integer to be used as aspect width ratio term.
/// The integer to be used as aspect height ratio term.
/// preview
public void GetSizeHintAspect(out AspectControl aspect, out int w, out int h)
{
int aspectRatio;
Interop.Evas.evas_object_size_hint_aspect_get(Handle, out aspectRatio, out w, out h);
aspect = (AspectControl)aspectRatio;
}
///
/// Stacks immediately below anchor.
///
/// The object below which to stack.
/// preview
public void StackBelow(EvasObject anchor)
{
Interop.Evas.evas_object_stack_below(Handle, anchor);
}
///
/// Stacks immediately above anchor.
///
/// The object above which to stack.
/// preview
public void StackAbove(EvasObject anchor)
{
Interop.Evas.evas_object_stack_above(Handle, anchor);
}
///
/// Raises to the top of its layer.
///
/// preview
public void RaiseTop()
{
Interop.Evas.evas_object_raise(Handle);
}
///
/// Gets the geometry of a line number.
///
/// The line number.
/// x coordinate of the line.
/// y coordinate of the line.
/// w coordinate of the line.
/// h coordinate of the line.
/// True on success, or False on error.
/// preview
[Obsolete("GetTextBlockGeometryByLineNumber is obsolete as of version 5.0.0.14299 and is no longer supported.")]
public bool GetTextBlockGeometryByLineNumber(int lineNumber, out int x, out int y, out int w, out int h)
{
x = -1; y = -1; w = -1; h = -1;
IntPtr _edjeHandle = Interop.Elementary.elm_layout_edje_get(RealHandle);
if (_edjeHandle == IntPtr.Zero)
{
return false;
}
IntPtr _textblock = Interop.Elementary.edje_object_part_object_get(_edjeHandle, "elm.text");
if (_textblock == IntPtr.Zero)
{
return false;
}
return Interop.Evas.evas_object_textblock_line_number_geometry_get(_textblock, lineNumber, out x, out y, out w, out h);
}
internal IntPtr GetData(string key)
{
return Interop.Evas.evas_object_data_get(RealHandle, key);
}
internal void SetData(string key, IntPtr data)
{
Interop.Evas.evas_object_data_set(RealHandle, key, data);
}
internal IntPtr DeleteData(string key)
{
return Interop.Evas.evas_object_data_del(RealHandle, key);
}
///
/// The callback of the Invalidate Event.
///
/// preview
protected virtual void OnInvalidate()
{
}
///
/// The callback of the Instantiated Event.
///
/// preview
protected virtual void OnInstantiated()
{
}
///
/// The callback of the Realized Event.
///
/// preview
protected virtual void OnRealized()
{
}
///
/// The callback of the Unrealize Event.
///
/// preview
protected virtual void OnUnrealize()
{
}
///
/// Creates a widget handle.
///
/// Parent EvasObject.
/// Handle IntPtr.
/// preview
protected abstract IntPtr CreateHandle(EvasObject parent);
///
/// For this object bind Parent object.Init handle and all kinds of EvasObjectEvent.
///
/// Parent object.
/// preview
public void Realize(EvasObject parent)
{
if (!IsRealized)
{
Parent = parent;
Handle = CreateHandle(parent);
Debug.Assert(Handle != IntPtr.Zero);
s_handleTable[Handle] = this;
(parent as Window)?.AddChild(this);
OnRealized();
_deleted = new EvasObjectEvent(this, EvasObjectCallbackType.Del);
_keydown = new EvasObjectEvent(this, RealHandle, EvasObjectCallbackType.KeyDown, EvasKeyEventArgs.Create);
_keyup = new EvasObjectEvent(this, RealHandle, EvasObjectCallbackType.KeyUp, EvasKeyEventArgs.Create);
_moved = new EvasObjectEvent(this, EvasObjectCallbackType.Move);
_resized = new EvasObjectEvent(this, EvasObjectCallbackType.Resize);
_shown = new EvasObjectEvent(this, EvasObjectCallbackType.Show);
_hidden = new EvasObjectEvent(this, EvasObjectCallbackType.Hide);
_deleted.On += (s, e) => MakeInvalidate();
_shown.On += (s, e) => Elementary.SendEvasObjectRealized(this);
}
}
///
/// Removes the current object relationship with others.
///
/// preview
public void Unrealize()
{
if (IsRealized)
{
if (_renderPostCallback != null)
{
Interop.Evas.evas_event_callback_del(Interop.Evas.evas_object_evas_get(Handle), Interop.Evas.ObjectCallbackType.RenderPost, _renderPostCallback);
_renderPostCallback = null;
}
OnUnrealize();
IntPtr toBeDeleted = Handle;
Handle = IntPtr.Zero;
DisposeEvent();
(Parent as Window)?.RemoveChild(this);
Interop.Evas.evas_object_del(toBeDeleted);
Deleted?.Invoke(this, EventArgs.Empty);
Parent = null;
s_handleTable.Remove(toBeDeleted);
}
}
private void MakeInvalidate()
{
Deleted?.Invoke(this, EventArgs.Empty);
OnInvalidate();
IntPtr toBeDeleted = Handle;
Handle = IntPtr.Zero;
MakeInvalidateEvent();
(Parent as Window)?.RemoveChild(this);
Parent = null;
_deleted = null;
s_handleTable.Remove(toBeDeleted);
}
private void DisposeEvent()
{
var events = new List(_eventStore);
foreach (var evt in events)
{
evt.Dispose();
}
_eventStore.Clear();
}
private void MakeInvalidateEvent()
{
foreach (var evt in _eventStore)
{
evt.MakeInvalidate();
}
_eventStore.Clear();
}
internal void AddToEventLifeTracker(IInvalidatable item)
{
_eventStore.Add(item);
}
internal void RemoveFromEventLifeTracker(IInvalidatable item)
{
_eventStore.Remove(item);
}
}
}