[NUI] TCSACR-226 code change (#1032)
[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 the item object.
24     /// </summary>
25     /// <since_tizen> preview </since_tizen>
26     public class ItemObject
27     {
28         private static Dictionary<int, ItemObject> s_IdToItemTable = new Dictionary<int, ItemObject>();
29         private static Dictionary<IntPtr, ItemObject> s_HandleToItemTable = new Dictionary<IntPtr, ItemObject>();
30         private static int s_globalId = 0;
31
32         readonly Dictionary<string, EvasObject> _partContents = new Dictionary<string, EvasObject>();
33         Interop.Evas.SmartCallback _deleteCallback;
34         IntPtr _handle = IntPtr.Zero;
35         Dictionary<SignalData, Interop.Elementary.Elm_Object_Item_Signal_Cb> _signalDatas = new Dictionary<SignalData, Interop.Elementary.Elm_Object_Item_Signal_Cb>();
36         EvasObject _trackObject = null;
37
38         /// <summary>
39         /// Gets the parent object for ItemObject.
40         /// </summary>
41         /// <since_tizen> preview </since_tizen>
42         public EvasObject Parent { get; internal set; }
43
44         /// <summary>
45         /// Creates and initializes a new instance of the ItemObject class.
46         /// </summary>
47         /// <param name="handle">IntPtr</param>
48         /// <since_tizen> preview </since_tizen>
49         protected ItemObject(IntPtr handle)
50         {
51             _deleteCallback = DeleteCallbackHandler;
52             Id = GetNextId();
53             s_IdToItemTable[Id] = this;
54             Parent = null;
55             Handle = handle;
56         }
57
58         /// <summary>
59         /// Creates and initializes a new instance of the ItemObject class with parent object.
60         /// </summary>
61         /// <param name="handle">IntPtr</param>
62         /// <param name="parent">Parent EvasObject</param>
63         /// <since_tizen> preview </since_tizen>
64         protected ItemObject(IntPtr handle, EvasObject parent)
65         {
66             _deleteCallback = DeleteCallbackHandler;
67             Id = GetNextId();
68             s_IdToItemTable[Id] = this;
69             Parent = parent;
70             Handle = handle;
71         }
72
73         // C# Finalizer was called on GC thread
74         // So, We can't access to EFL object
75         // And When Finalizer was called, Field can be already released.
76         //~ItemObject()
77         //{
78         //    if (Handle != IntPtr.Zero)
79         //        Interop.Elementary.elm_object_item_del(Handle);
80         //}
81
82         /// <summary>
83         /// Gets the ID of the item object.
84         /// </summary>
85         /// <since_tizen> preview </since_tizen>
86         public int Id { get; private set; }
87
88         /// <summary>
89         /// Sets or gets whether the item object is enabled.
90         /// </summary>
91         /// <since_tizen> preview </since_tizen>
92         public bool IsEnabled
93         {
94             get { return !Interop.Elementary.elm_object_item_disabled_get(Handle); }
95             set { Interop.Elementary.elm_object_item_disabled_set(Handle, !value); }
96         }
97
98         /// <summary>
99         /// Gets the track object of the item.
100         /// </summary>
101         /// <since_tizen> preview </since_tizen>
102         public EvasObject TrackObject
103         {
104             get
105             {
106                 if (_trackObject == null || Interop.Elementary.elm_object_item_track_get(Handle) == 0)
107                 {
108                     _trackObject = new ItemEvasObject(Handle);
109                 }
110                 return _trackObject;
111             }
112         }
113
114         /// <summary>
115         /// Sets or gets the style of the item.
116         /// </summary>
117         /// <since_tizen> preview </since_tizen>
118         public virtual string Style
119         {
120             get
121             {
122                 return Interop.Elementary.elm_object_item_style_get(Handle);
123             }
124             set
125             {
126                 Interop.Elementary.elm_object_item_style_set(Handle, value);
127             }
128         }
129
130         internal IntPtr Handle
131         {
132             get
133             {
134                 return _handle;
135             }
136             set
137             {
138                 if (_handle == value)
139                     return;
140
141                 if (_handle != IntPtr.Zero)
142                 {
143                     UnsetDeleteCallback();
144                 }
145                 _handle = value;
146                 SetDeleteCallback();
147                 s_HandleToItemTable[Handle] = this;
148                 if (_handle != IntPtr.Zero)
149                 {
150                     Elementary.SendItemObjectRealized(this);
151                 }
152             }
153         }
154
155         /// <summary>
156         /// Deleted will be triggered when the item object is deleted.
157         /// </summary>
158         /// <since_tizen> preview </since_tizen>
159         public event EventHandler Deleted;
160
161         /// <summary>
162         /// Deletes the item object.
163         /// </summary>
164         /// <since_tizen> preview </since_tizen>
165         public void Delete()
166         {
167             Interop.Elementary.elm_object_item_del(Handle);
168             _handle = IntPtr.Zero;
169         }
170
171         /// <summary>
172         /// Sets a content of an object item and deletes the old content.
173         /// </summary>
174         /// <param name="part">The content part name (null for the default content).</param>
175         /// <param name="content">The content of the object item.</param>
176         /// <since_tizen> preview </since_tizen>
177         public void SetPartContent(string part, EvasObject content)
178         {
179             SetPartContent(part, content, false);
180         }
181
182         /// <summary>.
183         /// Sets a content of the object item.
184         /// </summary>
185         /// <param name="part">The content part name (null for the default content)</param>
186         /// <param name="content">The content of the object item.</param>
187         /// <param name="preserveOldContent">Judge whether to delete the old content.</param>
188         /// <since_tizen> preview </since_tizen>
189         public void SetPartContent(string part, EvasObject content, bool preserveOldContent)
190         {
191             IntPtr oldContent = Interop.Elementary.elm_object_item_part_content_unset(Handle, part);
192             if (oldContent != IntPtr.Zero && !preserveOldContent)
193             {
194                 Interop.Evas.evas_object_del(oldContent);
195             }
196             Interop.Elementary.elm_object_item_part_content_set(Handle, part, content);
197             _partContents[part ?? "__default__"] = content;
198         }
199
200         /// <summary>
201         /// Sets the label of the object item.
202         /// </summary>
203         /// <param name="part">The text part name (null for the default label).</param>
204         /// <param name="text">Text of the label.</param>
205         /// <since_tizen> preview </since_tizen>
206         public void SetPartText(string part, string text)
207         {
208             Interop.Elementary.elm_object_item_part_text_set(Handle, part, text);
209         }
210
211         /// <summary>
212         /// Gets the label of the object item.
213         /// </summary>
214         /// <param name="part">The text part name (null for the default label).</param>
215         /// <returns></returns>
216         /// <since_tizen> preview </since_tizen>
217         public string GetPartText(string part)
218         {
219             return Interop.Elementary.elm_object_item_part_text_get(Handle, part);
220         }
221
222         /// <summary>
223         /// Sets the color of the object item.
224         /// </summary>
225         /// <param name="part">The text part name (null for the default label).</param>
226         /// <param name="color">The color.</param>
227         /// <since_tizen> preview </since_tizen>
228         public void SetPartColor(string part, Color color)
229         {
230             Interop.Elementary.elm_object_item_color_class_color_set(Handle, part, color.R * color.A / 255,
231                                                                               color.G * color.A / 255,
232                                                                               color.B * color.A / 255,
233                                                                               color.A);
234         }
235
236         /// <summary>
237         /// Gets the color of the object item.
238         /// </summary>
239         /// <param name="part">The text part name (null for the default label).</param>
240         /// <returns>The color of an object item.</returns>
241         /// <since_tizen> preview </since_tizen>
242         public Color GetPartColor(string part)
243         {
244             int r, g, b, a;
245             Interop.Elementary.elm_object_item_color_class_color_get(Handle, part, out r, out g, out b, out a);
246             return new Color((int)(r / (a / 255.0)), (int)(g / (a / 255.0)), (int)(b / (a / 255.0)), a);
247         }
248
249         /// <summary>
250         /// Deletes the color of the object item.
251         /// </summary>
252         /// <param name="part">The text part name.</param>
253         /// <since_tizen> preview </since_tizen>
254         public void DeletePartColor(string part)
255         {
256             Interop.Elementary.elm_object_item_color_class_del(Handle, part);
257         }
258
259         /// <summary>
260         /// Adds a function for a signal emitted by the object item edje.
261         /// </summary>
262         /// <param name="emission">The signal's name.</param>
263         /// <param name="source">The signal's source.</param>
264         /// <param name="func">The function to be executed when the signal is emitted.</param>
265         /// <since_tizen> preview </since_tizen>
266         public void AddSignalHandler(string emission, string source, Func<string, string, bool> func)
267         {
268             if (emission != null && source != null && func != null)
269             {
270                 var signalData = new SignalData(emission, source, func);
271                 if (!_signalDatas.ContainsKey(signalData))
272                 {
273                     var signalCallback = new Interop.Elementary.Elm_Object_Item_Signal_Cb((d, o, e, s) =>
274                     {
275                         return func(e, s);
276                     });
277                     Interop.Elementary.elm_object_item_signal_callback_add(Handle, emission, source, signalCallback, IntPtr.Zero);
278                 }
279             }
280         }
281
282         /// <summary>
283         /// Removes a signal-triggered function from the object item edje object.
284         /// </summary>
285         /// <param name="emission">The signal's name.</param>
286         /// <param name="source">The signal's source.</param>
287         /// <param name="func">The function to be executed when the signal is emitted.</param>
288         /// <since_tizen> preview </since_tizen>
289         public void RemoveSignalHandler(string emission, string source, Func<string, string, bool> func)
290         {
291             if (emission != null && source != null && func != null)
292             {
293                 var signalData = new SignalData(emission, source, func);
294
295                 Interop.Elementary.Elm_Object_Item_Signal_Cb signalCallback = null;
296                 _signalDatas.TryGetValue(signalData, out signalCallback);
297
298                 if (signalCallback != null)
299                 {
300                     Interop.Elementary.elm_object_item_signal_callback_del(Handle, emission, source, signalCallback);
301                     _signalDatas.Remove(signalData);
302                 }
303             }
304         }
305
306         /// <summary>
307         /// Send a signal to the edje object of the widget item.
308         /// </summary>
309         /// <param name="emission">The signal's name.</param>
310         /// <param name="source">The signal's source.</param>
311         /// <since_tizen> preview </since_tizen>
312         public void EmitSignal(string emission, string source)
313         {
314             Interop.Elementary.elm_object_item_signal_emit(Handle, emission, source);
315         }
316
317         /// <summary>
318         /// Gets the handle of the object item.
319         /// </summary>
320         /// <param name="obj">ItemObject</param>
321         /// <since_tizen> preview </since_tizen>
322         public static implicit operator IntPtr(ItemObject obj)
323         {
324             if (obj == null)
325                 return IntPtr.Zero;
326             return obj.Handle;
327         }
328
329         /// <summary>
330         /// OnInvalidate of the object item.
331         /// </summary>
332         /// <since_tizen> preview </since_tizen>
333         protected virtual void OnInvalidate() { }
334
335         internal static ItemObject GetItemById(int id)
336         {
337             ItemObject value;
338             s_IdToItemTable.TryGetValue(id, out value);
339             return value;
340         }
341
342         internal static ItemObject GetItemByHandle(IntPtr handle)
343         {
344             ItemObject value;
345             s_HandleToItemTable.TryGetValue(handle, out value);
346             return value;
347         }
348
349         void DeleteCallbackHandler(IntPtr data, IntPtr obj, IntPtr info)
350         {
351             Deleted?.Invoke(this, EventArgs.Empty);
352             Parent = null;
353             OnInvalidate();
354             if (s_IdToItemTable.ContainsKey(Id))
355             {
356                 s_IdToItemTable.Remove(Id);
357             }
358             if (s_HandleToItemTable.ContainsKey(_handle))
359             {
360                 s_HandleToItemTable.Remove(_handle);
361             }
362             _partContents.Clear();
363             _handle = IntPtr.Zero;
364         }
365
366         void UnsetDeleteCallback()
367         {
368             Interop.Elementary.elm_object_item_del_cb_set(Handle, null);
369         }
370
371         void SetDeleteCallback()
372         {
373             if (Handle != IntPtr.Zero)
374                 Interop.Elementary.elm_object_item_del_cb_set(Handle, _deleteCallback);
375         }
376
377         static int GetNextId()
378         {
379             return s_globalId++;
380         }
381
382         class SignalData : IEquatable<SignalData>
383         {
384             public string Emission { get; set; }
385             public string Source { get; set; }
386             public Func<string, string, bool> Func { get; set; }
387
388             public SignalData(string emission, string source, Func<string, string, bool> func)
389             {
390                 Emission = emission;
391                 Source = source;
392                 Func = func;
393             }
394
395             public override bool Equals(object other)
396             {
397                 return Equals(other as SignalData);
398             }
399
400             public bool Equals(SignalData other) {
401                 if (other == null)
402                 {
403                     return false;
404                 }
405                 return (Emission == other.Emission) && (Source == other.Source) && (Func == other.Func);
406             }
407
408             public override int GetHashCode()
409             {
410                 int hashCode = Emission.GetHashCode();
411                 hashCode ^= Source.GetHashCode();
412                 hashCode ^= Func.GetHashCode();
413                 return hashCode;
414             }
415         }
416
417         class ItemEvasObject : EvasObject
418         {
419             IntPtr _trackHandle = IntPtr.Zero;
420
421             public ItemEvasObject(IntPtr parent)
422             {
423                 _trackHandle = Interop.Elementary.elm_object_item_track(parent);
424                 if (_trackHandle != IntPtr.Zero)
425                 {
426                     Realize(null);
427                 }
428             }
429
430             protected override IntPtr CreateHandle(EvasObject parent)
431             {
432                 return _trackHandle;
433             }
434         }
435     }
436 }