/*
* 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;
namespace ElmSharp
{
///
/// The ItemObject is used to manage item object
///
/// preview
public class ItemObject
{
private static Dictionary s_IdToItemTable = new Dictionary();
private static Dictionary s_HandleToItemTable = new Dictionary();
private static int s_globalId = 0;
readonly Dictionary _partContents = new Dictionary();
Interop.Evas.SmartCallback _deleteCallback;
IntPtr _handle = IntPtr.Zero;
Dictionary _signalDatas = new Dictionary();
EvasObject _trackObject = null;
///
/// Creates and initializes a new instance of ItemObject class.
///
/// IntPtr
/// preview
protected ItemObject(IntPtr handle)
{
_deleteCallback = DeleteCallbackHandler;
Id = GetNextId();
s_IdToItemTable[Id] = this;
Handle = handle;
}
// 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.
//~ItemObject()
//{
// if (Handle != IntPtr.Zero)
// Interop.Elementary.elm_object_item_del(Handle);
//}
///
/// Gets the id of item object
///
/// preview
public int Id { get; private set; }
///
/// Sets or gets whether the item object is enabled
///
/// preview
public bool IsEnabled
{
get { return !Interop.Elementary.elm_object_item_disabled_get(Handle); }
set { Interop.Elementary.elm_object_item_disabled_set(Handle, !value); }
}
///
/// Gets track object of the item.
///
/// preview
public EvasObject TrackObject
{
get
{
if (_trackObject == null)
_trackObject = new ItemEvasObject(Handle);
return _trackObject;
}
}
///
/// Sets or gets the style of the Item.
///
/// preview
public virtual string Style
{
get
{
return Interop.Elementary.elm_object_item_style_get(Handle);
}
set
{
Interop.Elementary.elm_object_item_style_set(Handle, value);
}
}
internal IntPtr Handle
{
get
{
return _handle;
}
set
{
if (_handle == value)
return;
if (_handle != IntPtr.Zero)
{
UnsetDeleteCallback();
}
_handle = value;
SetDeleteCallback();
s_HandleToItemTable[Handle] = this;
}
}
///
/// Deleted will be triggered when the item object is deleted
///
/// preview
public event EventHandler Deleted;
///
/// Delete the item object
///
/// preview
public void Delete()
{
Interop.Elementary.elm_object_item_del(Handle);
_handle = IntPtr.Zero;
}
///
/// Set a content of an object item and delete old content
///
/// The content part name (null for the default content)
/// The content of the object item
/// preview
public void SetPartContent(string part, EvasObject content)
{
SetPartContent(part, content, false);
}
///
/// Set a content of an object item
///
/// The content part name (null for the default content)
/// The content of the object item
/// judge whether delete old content
/// preview
public void SetPartContent(string part, EvasObject content, bool preserveOldContent)
{
IntPtr oldContent = Interop.Elementary.elm_object_item_part_content_unset(Handle, part);
if (oldContent != IntPtr.Zero && !preserveOldContent)
{
Interop.Evas.evas_object_del(oldContent);
}
Interop.Elementary.elm_object_item_part_content_set(Handle, part, content);
_partContents[part ?? "__default__"] = content;
}
///
/// Set a label of an object item
///
/// The text part name (null for the default label)
/// Text of the label
/// preview
public void SetPartText(string part, string text)
{
Interop.Elementary.elm_object_item_part_text_set(Handle, part, text);
}
///
/// Gets a label of an object item
///
/// The text part name (null for the default label)
///
/// preview
public string GetPartText(string part)
{
return Interop.Elementary.elm_object_item_part_text_get(Handle, part);
}
///
/// Sets color of an object item
///
/// The text part name (null for the default label)
/// the color
/// preview
public void SetPartColor(string part, Color color)
{
Interop.Elementary.elm_object_item_color_class_color_set(Handle, part, color.R * color.A / 255,
color.G * color.A / 255,
color.B * color.A / 255,
color.A);
}
///
/// Gets color of an object item
///
/// The text part name (null for the default label)
/// the color of object item
/// preview
public Color GetPartColor(string part)
{
int r, g, b, a;
Interop.Elementary.elm_object_item_color_class_color_get(Handle, part, out r, out g, out b, out a);
return new Color((int)(r / (a / 255.0)), (int)(g / (a / 255.0)), (int)(b / (a / 255.0)), a);
}
///
/// Deletes color of an object item
///
/// The text part name
/// preview
public void DeletePartColor(string part)
{
Interop.Elementary.elm_object_item_color_class_del(Handle, part);
}
///
/// Add a function for a signal emitted by object item edje.
///
/// The signal's name.
/// The signal's source.
/// The function to be executed when the signal is emitted.
/// preview
public void AddSignalHandler(string emission, string source, Func func)
{
if (emission != null && source != null && func != null)
{
var signalData = new SignalData(emission, source, func);
if (!_signalDatas.ContainsKey(signalData))
{
var signalCallback = new Interop.Elementary.Elm_Object_Item_Signal_Cb((d, o, e, s) =>
{
return func(e, s);
});
Interop.Elementary.elm_object_item_signal_callback_add(Handle, emission, source, signalCallback, IntPtr.Zero);
}
}
}
///
/// Remove a signal-triggered function from a object item edje object.
///
/// The signal's name.
/// The signal's source.
/// The function to be executed when the signal is emitted.
/// preview
public void RemoveSignalHandler(string emission, string source, Func func)
{
if (emission != null && source != null && func != null)
{
var signalData = new SignalData(emission, source, func);
Interop.Elementary.Elm_Object_Item_Signal_Cb signalCallback = null;
_signalDatas.TryGetValue(signalData, out signalCallback);
if (signalCallback != null)
{
Interop.Elementary.elm_object_item_signal_callback_del(Handle, emission, source, signalCallback);
_signalDatas.Remove(signalData);
}
}
}
///
/// Send a signal to the edje object of the widget item.
///
/// The signal's name.
/// The signal's source.
/// preview
public void EmitSignal(string emission, string source)
{
Interop.Elementary.elm_object_item_signal_emit(Handle, emission, source);
}
///
/// Gets the handle of object item
///
/// ItemObject
/// preview
public static implicit operator IntPtr(ItemObject obj)
{
if (obj == null)
return IntPtr.Zero;
return obj.Handle;
}
///
/// OnInvalidate of object item
///
/// preview
protected virtual void OnInvalidate() { }
internal static ItemObject GetItemById(int id)
{
ItemObject value;
s_IdToItemTable.TryGetValue(id, out value);
return value;
}
internal static ItemObject GetItemByHandle(IntPtr handle)
{
ItemObject value;
s_HandleToItemTable.TryGetValue(handle, out value);
return value;
}
void DeleteCallbackHandler(IntPtr data, IntPtr obj, IntPtr info)
{
Deleted?.Invoke(this, EventArgs.Empty);
OnInvalidate();
if (s_IdToItemTable.ContainsKey(Id))
{
s_IdToItemTable.Remove(Id);
}
if (s_HandleToItemTable.ContainsKey(_handle))
{
s_HandleToItemTable.Remove(_handle);
}
_partContents.Clear();
_handle = IntPtr.Zero;
}
void UnsetDeleteCallback()
{
Interop.Elementary.elm_object_item_del_cb_set(Handle, null);
}
void SetDeleteCallback()
{
if (Handle != IntPtr.Zero)
Interop.Elementary.elm_object_item_del_cb_set(Handle, _deleteCallback);
}
static int GetNextId()
{
return s_globalId++;
}
class SignalData
{
public string Emission { get; set; }
public string Source { get; set; }
public Func Func { get; set; }
public SignalData(string emission, string source, Func func)
{
Emission = emission;
Source = source;
Func = func;
}
///
/// Indicates whether this instance and a specified object are equal.
///
/// The object to compare with the current instance.
///
/// true if obj and this instance are the same type and represent the same value.
/// otherwise, false.
///
public override bool Equals(object obj)
{
SignalData s = obj as SignalData;
if (s == null)
{
return false;
}
return (Emission == s.Emission) && (Source == s.Source) && (Func == s.Func);
}
public override int GetHashCode()
{
int hashCode = Emission.GetHashCode();
hashCode ^= Source.GetHashCode();
hashCode ^= Func.GetHashCode();
return hashCode;
}
}
class ItemEvasObject : EvasObject
{
IntPtr _parent = IntPtr.Zero;
///
/// Creates and initializes a new instance of ItemEvasObject class.
///
/// IntPtr
public ItemEvasObject(IntPtr parent) : base()
{
_parent = parent;
Realize(null);
}
///
/// Creates a widget handle.
///
/// Parent EvasObject
/// Handle IntPtr
protected override IntPtr CreateHandle(EvasObject parent)
{
return Interop.Elementary.elm_object_item_track(_parent);
}
}
}
}