Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / ElmSharp / ElmSharp / ItemObject.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 using System;
18 using System.Collections.Generic;
19
20 namespace ElmSharp
21 {
22     /// <summary>
23     /// The ItemObject is used to manage item object
24     /// </summary>
25     public class ItemObject
26     {
27         private static Dictionary<int, ItemObject> s_IdToItemTable = new Dictionary<int, ItemObject>();
28         private static Dictionary<IntPtr, ItemObject> s_HandleToItemTable = new Dictionary<IntPtr, ItemObject>();
29         private static int s_globalId = 0;
30
31         readonly Dictionary<string, EvasObject> _partContents = new Dictionary<string, EvasObject>();
32         Interop.Evas.SmartCallback _deleteCallback;
33         IntPtr _handle = IntPtr.Zero;
34         Dictionary<SignalData, Interop.Elementary.Elm_Object_Item_Signal_Cb> _signalDatas = new Dictionary<SignalData, Interop.Elementary.Elm_Object_Item_Signal_Cb>();
35         EvasObject _trackObject = null;
36
37         /// <summary>
38         /// Creates and initializes a new instance of ItemObject class.
39         /// </summary>
40         /// <param name="handle">IntPtr</param>
41         protected ItemObject(IntPtr handle)
42         {
43             _deleteCallback = DeleteCallbackHandler;
44             Id = GetNextId();
45             s_IdToItemTable[Id] = this;
46             Handle = handle;
47         }
48
49         // C# Finalizer was called on GC thread
50         // So, We can't access to EFL object
51         // And When Finalizer was called, Field can be already released.
52         //~ItemObject()
53         //{
54         //    if (Handle != IntPtr.Zero)
55         //        Interop.Elementary.elm_object_item_del(Handle);
56         //}
57
58         /// <summary>
59         /// Gets the id of item object
60         /// </summary>
61         public int Id { get; private set; }
62
63         /// <summary>
64         /// Sets or gets whether the item object is enabled
65         /// </summary>
66         public bool IsEnabled
67         {
68             get { return !Interop.Elementary.elm_object_item_disabled_get(Handle); }
69             set { Interop.Elementary.elm_object_item_disabled_set(Handle, !value); }
70         }
71
72         /// <summary>
73         /// Gets track object of the item.
74         /// </summary>
75         public EvasObject TrackObject
76         {
77             get
78             {
79                 if (_trackObject == null)
80                     _trackObject = new ItemEvasObject(Handle);
81                 return _trackObject;
82             }
83         }
84
85         internal IntPtr Handle
86         {
87             get
88             {
89                 return _handle;
90             }
91             set
92             {
93                 if (_handle == value)
94                     return;
95
96                 if (_handle != IntPtr.Zero)
97                 {
98                     UnsetDeleteCallback();
99                 }
100                 _handle = value;
101                 SetDeleteCallback();
102                 s_HandleToItemTable[Handle] = this;
103             }
104         }
105
106         /// <summary>
107         /// Deleted will be triggered when the item object is deleted
108         /// </summary>
109         public event EventHandler Deleted;
110
111         /// <summary>
112         /// Delete the item object
113         /// </summary>
114         public void Delete()
115         {
116             Interop.Elementary.elm_object_item_del(Handle);
117             _handle = IntPtr.Zero;
118         }
119
120         /// <summary>
121         /// Set a content of an object item and delete old content
122         /// </summary>
123         /// <param name="part">The content part name (null for the default content)</param>
124         /// <param name="content">The content of the object item</param>
125         public void SetPartContent(string part, EvasObject content)
126         {
127             SetPartContent(part, content, false);
128         }
129
130         /// <summary>
131         /// Set a content of an object item
132         /// </summary>
133         /// <param name="part">The content part name (null for the default content)</param>
134         /// <param name="content">The content of the object item</param>
135         /// <param name="preserveOldContent">judge whether delete old content</param>
136         public void SetPartContent(string part, EvasObject content, bool preserveOldContent)
137         {
138             IntPtr oldContent = Interop.Elementary.elm_object_item_part_content_unset(Handle, part);
139             if (oldContent != IntPtr.Zero && !preserveOldContent)
140             {
141                 Interop.Evas.evas_object_del(oldContent);
142             }
143             Interop.Elementary.elm_object_item_part_content_set(Handle, part, content);
144             _partContents[part ?? "__default__"] = content;
145         }
146
147         /// <summary>
148         /// Set a label of an object item
149         /// </summary>
150         /// <param name="part">The text part name (null for the default label)</param>
151         /// <param name="text">Text of the label</param>
152         public void SetPartText(string part, string text)
153         {
154             Interop.Elementary.elm_object_item_part_text_set(Handle, part, text);
155         }
156
157         /// <summary>
158         /// Gets a label of an object item
159         /// </summary>
160         /// <param name="part">The text part name (null for the default label)</param>
161         /// <returns></returns>
162         public string GetPartText(string part)
163         {
164             return Interop.Elementary.elm_object_item_part_text_get(Handle, part);
165         }
166
167         /// <summary>
168         /// Sets color of an object item
169         /// </summary>
170         /// <param name="part">The text part name (null for the default label)</param>
171         /// <param name="color">the color</param>
172         public void SetPartColor(string part, Color color)
173         {
174             Interop.Elementary.elm_object_item_color_class_color_set(Handle, part, color.R * color.A / 255,
175                                                                               color.G * color.A / 255,
176                                                                               color.B * color.A / 255,
177                                                                               color.A);
178         }
179
180         /// <summary>
181         /// Gets color of an object item
182         /// </summary>
183         /// <param name="part">The text part name (null for the default label)</param>
184         /// <returns>the color of object item</returns>
185         public Color GetPartColor(string part)
186         {
187             int r, g, b, a;
188             Interop.Elementary.elm_object_item_color_class_color_get(Handle, part, out r, out g, out b, out a);
189             return new Color((int)(r / (a / 255.0)), (int)(g / (a / 255.0)), (int)(b / (a / 255.0)), a);
190         }
191
192         /// <summary>
193         /// Deletes color of an object item
194         /// </summary>
195         /// <param name="part">The text part name</param>
196         public void DeletePartColor(string part)
197         {
198             Interop.Elementary.elm_object_item_color_class_del(Handle, part);
199         }
200
201         /// <summary>
202         /// Add a function for a signal emitted by object item edje.
203         /// </summary>
204         /// <param name="emission">The signal's name.</param>
205         /// <param name="source">The signal's source.</param>
206         /// <param name="func">The function to be executed when the signal is emitted.</param>
207         public void AddSignalHandler(string emission, string source, Func<string, string, bool> func)
208         {
209             if (emission != null && source != null && func != null)
210             {
211                 var signalData = new SignalData(emission, source, func);
212                 if (!_signalDatas.ContainsKey(signalData))
213                 {
214                     var signalCallback = new Interop.Elementary.Elm_Object_Item_Signal_Cb((d, o, e, s) =>
215                     {
216                         return func(e, s);
217                     });
218                     Interop.Elementary.elm_object_item_signal_callback_add(Handle, emission, source, signalCallback, IntPtr.Zero);
219                 }
220             }
221         }
222
223         /// <summary>
224         /// Remove a signal-triggered function from a object item edje object.
225         /// </summary>
226         /// <param name="emission">The signal's name.</param>
227         /// <param name="source">The signal's source.</param>
228         /// <param name="func">The function to be executed when the signal is emitted.</param>
229         public void RemoveSignalHandler(string emission, string source, Func<string, string, bool> func)
230         {
231             if (emission != null && source != null && func != null)
232             {
233                 var signalData = new SignalData(emission, source, func);
234
235                 Interop.Elementary.Elm_Object_Item_Signal_Cb signalCallback = null;
236                 _signalDatas.TryGetValue(signalData, out signalCallback);
237
238                 if (signalCallback != null)
239                 {
240                     Interop.Elementary.elm_object_item_signal_callback_del(Handle, emission, source, signalCallback);
241                     _signalDatas.Remove(signalData);
242                 }
243             }
244         }
245
246         /// <summary>
247         /// Send a signal to the edje object of the widget item.
248         /// </summary>
249         /// <param name="emission">The signal's name.</param>
250         /// <param name="source">The signal's source.</param>
251         public void EmitSignal(string emission, string source)
252         {
253             Interop.Elementary.elm_object_item_signal_emit(Handle, emission, source);
254         }
255
256         /// <summary>
257         /// Gets the handle of object item
258         /// </summary>
259         /// <param name="obj">ItemObject</param>
260         public static implicit operator IntPtr(ItemObject obj)
261         {
262             if (obj == null)
263                 return IntPtr.Zero;
264             return obj.Handle;
265         }
266
267         /// <summary>
268         /// OnInvalidate of object item
269         /// </summary>
270         protected virtual void OnInvalidate() { }
271
272         internal static ItemObject GetItemById(int id)
273         {
274             ItemObject value;
275             s_IdToItemTable.TryGetValue(id, out value);
276             return value;
277         }
278
279         internal static ItemObject GetItemByHandle(IntPtr handle)
280         {
281             ItemObject value;
282             s_HandleToItemTable.TryGetValue(handle, out value);
283             return value;
284         }
285
286         void DeleteCallbackHandler(IntPtr data, IntPtr obj, IntPtr info)
287         {
288             Deleted?.Invoke(this, EventArgs.Empty);
289             OnInvalidate();
290             if (s_IdToItemTable.ContainsKey(Id))
291             {
292                 s_IdToItemTable.Remove(Id);
293             }
294             if (s_HandleToItemTable.ContainsKey(_handle))
295             {
296                 s_HandleToItemTable.Remove(_handle);
297             }
298             _partContents.Clear();
299             _handle = IntPtr.Zero;
300         }
301
302         void UnsetDeleteCallback()
303         {
304             Interop.Elementary.elm_object_item_del_cb_set(Handle, null);
305         }
306
307         void SetDeleteCallback()
308         {
309             if (Handle != IntPtr.Zero)
310                 Interop.Elementary.elm_object_item_del_cb_set(Handle, _deleteCallback);
311         }
312
313         static int GetNextId()
314         {
315             return s_globalId++;
316         }
317
318         class SignalData
319         {
320             public string Emission { get; set; }
321             public string Source { get; set; }
322             public Func<string, string, bool> Func { get; set; }
323
324             public SignalData(string emission, string source, Func<string, string, bool> func)
325             {
326                 Emission = emission;
327                 Source = source;
328                 Func = func;
329             }
330
331             public override bool Equals(object obj)
332             {
333                 SignalData s = obj as SignalData;
334                 if (s == null)
335                 {
336                     return false;
337                 }
338                 return (Emission == s.Emission) && (Source == s.Source) && (Func == s.Func);
339             }
340
341             public override int GetHashCode()
342             {
343                 int hashCode = Emission.GetHashCode();
344                 hashCode ^= Source.GetHashCode();
345                 hashCode ^= Func.GetHashCode();
346                 return hashCode;
347             }
348         }
349
350         class ItemEvasObject : EvasObject
351         {
352             IntPtr _parent = IntPtr.Zero;
353
354             public ItemEvasObject(IntPtr parent) : base()
355             {
356                 _parent = parent;
357                 Realize(null);
358             }
359
360             protected override IntPtr CreateHandle(EvasObject parent)
361             {
362                 return Interop.Elementary.elm_object_item_track(_parent);
363             }
364         }
365     }
366 }