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