Merge "[GenGrid|GenGridItem|GenItem|GenItemClass]Add Comments." into tizen
[platform/core/csapi/tizenfx.git] / src / ElmSharp / ElmSharp / GenItemClass.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 using System.Runtime.InteropServices;
20
21 namespace ElmSharp
22 {
23     /// <summary>
24     /// It represents the GenGrid or GenList item class definition field details.
25     /// It has some display styles, such as "default", "full" and "group_index".
26     /// </summary>
27     public class GenItemClass : IDisposable
28     {
29         private static Dictionary<IntPtr, EvasObject> s_HandleToEvasObject = new Dictionary<IntPtr, EvasObject>();
30
31         /// <summary>
32         /// The delegate to define <see cref="GetTextHandler"/>.
33         /// </summary>
34         /// <param name="data">The item data.</param>
35         /// <param name="part">The part where the data should be shown.</param>
36         /// <returns>Return string that should be shown.</returns>
37         public delegate string GetTextDelegate(object data, string part);
38
39         /// <summary>
40         /// The delegate to define <see cref="GetContentHandler"/>.
41         /// </summary>
42         /// <param name="data">The item data.</param>
43         /// <param name="part">The part where the data should be shown.</param>
44         /// <returns>Return content that should be shown.</returns>
45         public delegate EvasObject GetContentDelegate(object data, string part);
46
47         /// <summary>
48         /// The delegate to define <see cref="DeleteHandler"/>.
49         /// </summary>
50         /// <param name="data">The item data.</param>
51         public delegate void DeleteDelegate(object data);
52
53         /// <summary>
54         /// The delegate to define <see cref="ReusableContentHandler"/>.
55         /// </summary>
56         /// <param name="data">The item data.</param>
57         /// <param name="part">The part where the data should be shown.</param>
58         /// <param name="old">The content has been added in gengrid.</param>
59         /// <returns>Return content that should be shown.</returns>
60         public delegate EvasObject GetReusableContentDelegate(object data, string part, EvasObject old);
61
62         private ItemClass _itemClass;
63         private IntPtr _unmanagedPtr = IntPtr.Zero;
64         private string _style;
65
66         /// <summary>
67         /// Creates and initializes a new instance of the GenItemClass.
68         /// </summary>
69         /// <param name="style">The item display style.</param>
70         public GenItemClass(string style)
71         {
72             _style = style;
73             IntPtr unmanaged = Interop.Elementary.elm_genlist_item_class_new();
74             _itemClass = Marshal.PtrToStructure<ItemClass>(unmanaged);
75             _itemClass.itemStyle = style;
76             _itemClass.textCallback = GetTextCallback;
77             _itemClass.contentCallback = GetContentCallback;
78             _itemClass.stateCallback = null;
79             _itemClass.delCallback = DelCallback;
80             _itemClass.reusableContentCallback = GetReusableContentCallback;
81
82             Interop.Elementary.elm_genlist_item_class_free(unmanaged);
83         }
84
85         ~GenItemClass()
86         {
87             Dispose(false);
88         }
89
90         /// <summary>
91         /// Gets the item style.
92         /// </summary>
93         public string ItemStyle { get { return _style; } }
94
95         /// <summary>
96         /// Gets or sets the callback that defines how to display item text.
97         /// If get, return <see cref="GetTextDelegate"/>.
98         /// </summary>
99         public GetTextDelegate GetTextHandler { get; set; }
100
101         /// <summary>
102         /// Gets or sets the callback that defines how to display item content.
103         /// If get, return <see cref="GetContentDelegate"/>.
104         /// </summary>
105         public GetContentDelegate GetContentHandler { get; set; }
106
107         /// <summary>
108         /// Gets or sets the callback that defines how to delete item text and content.
109         /// If get, return <see cref="DeleteDelegate"/>.
110         /// </summary>
111         public DeleteDelegate DeleteHandler { get; set; }
112
113         /// <summary>
114         /// Gets or sets the callback that defines how to reuse item content.
115         /// If get, return <see cref="GetReusableContentDelegate"/>.
116         /// </summary>
117         public GetReusableContentDelegate ReusableContentHandler { get; set; }
118
119         internal IntPtr UnmanagedPtr
120         {
121             get
122             {
123                 if (_unmanagedPtr == IntPtr.Zero)
124                 {
125                     _unmanagedPtr = Marshal.AllocHGlobal(Marshal.SizeOf(_itemClass));
126                     Marshal.StructureToPtr(_itemClass, _unmanagedPtr, false);
127                 }
128                 return _unmanagedPtr;
129             }
130         }
131
132         protected virtual void Dispose(bool disposing)
133         {
134             if (_unmanagedPtr != IntPtr.Zero)
135             {
136                 Marshal.FreeHGlobal(_unmanagedPtr);
137                 _unmanagedPtr = IntPtr.Zero;
138             }
139         }
140
141         public void Dispose()
142         {
143             Dispose(true);
144             GC.SuppressFinalize(this);
145         }
146
147         internal void SendItemDeleted(object data)
148         {
149             // data is user inserted value with GenItem
150             DeleteHandler?.Invoke(data);
151         }
152
153         private string GetTextCallback(IntPtr data, IntPtr obj, IntPtr part)
154         {
155             GenItem item = ItemObject.GetItemById((int)data) as GenItem;
156             return GetTextHandler?.Invoke(item?.Data, Marshal.PtrToStringAnsi(part));
157         }
158         private IntPtr GetContentCallback(IntPtr data, IntPtr obj, IntPtr part)
159         {
160             GenItem item = ItemObject.GetItemById((int)data) as GenItem;
161             EvasObject evasObject = GetContentHandler?.Invoke(item?.Data, Marshal.PtrToStringAnsi(part));
162             if (evasObject != null)
163             {
164                 s_HandleToEvasObject[evasObject.Handle] = evasObject;
165                 evasObject.Deleted += EvasObjectDeleted;
166             }
167             return evasObject;
168         }
169
170         private void EvasObjectDeleted(object sender, EventArgs e)
171         {
172             IntPtr handle = (sender as EvasObject).Handle;
173             s_HandleToEvasObject.Remove(handle);
174         }
175
176         private IntPtr GetReusableContentCallback(IntPtr data, IntPtr obj, IntPtr part, IntPtr old)
177         {
178             IntPtr reusedHandle = IntPtr.Zero;
179             GenItem item = ItemObject.GetItemById((int)data) as GenItem;
180             if (s_HandleToEvasObject.ContainsKey(old))
181             {
182                 reusedHandle = ReusableContentHandler?.Invoke(item?.Data, Marshal.PtrToStringAnsi(part), s_HandleToEvasObject[old]);
183             }
184             return reusedHandle;
185         }
186         private void DelCallback(IntPtr data, IntPtr obj)
187         {
188             // We can't use this callback
189             // because, when item was deleted
190             // First, ItemObject deleted callback was called
191             // and We need to clean up ItemObject related objects
192             // This callback was called after ItemObject deleted callback was completed.
193             // So, We can't get resource reletated with ItemObject
194         }
195     }
196
197     [StructLayout(LayoutKind.Sequential)]
198     internal class ItemClass
199     {
200         public delegate string GetTextCallback(IntPtr data, IntPtr obj, IntPtr part);
201         public delegate IntPtr GetContentCallback(IntPtr data, IntPtr obj, IntPtr part);
202         public delegate int GetStateCallback(IntPtr data, IntPtr obj, IntPtr part);
203         public delegate void DelCallback(IntPtr data, IntPtr obj);
204         public delegate int FilterCallback(IntPtr data, IntPtr obj, IntPtr key);
205         public delegate IntPtr GetReusableContentCallback(IntPtr data, IntPtr obj, IntPtr part, IntPtr old);
206
207         public int version;
208         public uint refCount;
209         public int deleteMe;
210         public string itemStyle;
211         public readonly string decorateItemStyle;
212         public readonly string decorateAllItemStyle;
213         public GetTextCallback textCallback;
214         public GetContentCallback contentCallback;
215         public GetStateCallback stateCallback;
216         public DelCallback delCallback;
217         public FilterCallback filterCallback;
218         public GetReusableContentCallback reusableContentCallback;
219     }
220
221 }