Release 4.0.0-preview1-00051
[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         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         ItemClass _itemClass;
63         IntPtr _unmanagedPtr = IntPtr.Zero;
64         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 = CreateItemClass();
74
75             _itemClass = Marshal.PtrToStructure<ItemClass>(unmanaged);
76             _itemClass.itemStyle = style;
77             _itemClass.textCallback = GetTextCallback;
78             _itemClass.contentCallback = GetContentCallback;
79             _itemClass.stateCallback = null;
80             _itemClass.delCallback = DelCallback;
81             _itemClass.reusableContentCallback = GetReusableContentCallback;
82
83             ReleaseItemClass(unmanaged);
84         }
85
86         ~GenItemClass()
87         {
88             Dispose(false);
89         }
90
91         /// <summary>
92         /// Gets the item style.
93         /// </summary>
94         public string ItemStyle { get { return _style; } }
95
96         /// <summary>
97         /// Gets or sets the callback that defines how to display item text.
98         /// If get, return <see cref="GetTextDelegate"/>.
99         /// </summary>
100         public GetTextDelegate GetTextHandler { get; set; }
101
102         /// <summary>
103         /// Gets or sets the callback that defines how to display item content.
104         /// If get, return <see cref="GetContentDelegate"/>.
105         /// </summary>
106         public GetContentDelegate GetContentHandler { get; set; }
107
108         /// <summary>
109         /// Gets or sets the callback that defines how to delete item text and content.
110         /// If get, return <see cref="DeleteDelegate"/>.
111         /// </summary>
112         public DeleteDelegate DeleteHandler { get; set; }
113
114         /// <summary>
115         /// Gets or sets the callback that defines how to reuse item content.
116         /// If get, return <see cref="GetReusableContentDelegate"/>.
117         /// </summary>
118         public GetReusableContentDelegate ReusableContentHandler { get; set; }
119
120         internal IntPtr UnmanagedPtr
121         {
122             get
123             {
124                 if (_unmanagedPtr == IntPtr.Zero)
125                 {
126                     _unmanagedPtr = Marshal.AllocHGlobal(Marshal.SizeOf(_itemClass));
127                     Marshal.StructureToPtr(_itemClass, _unmanagedPtr, false);
128                 }
129                 return _unmanagedPtr;
130             }
131         }
132
133         protected virtual void Dispose(bool disposing)
134         {
135             if (_unmanagedPtr != IntPtr.Zero)
136             {
137                 Marshal.FreeHGlobal(_unmanagedPtr);
138                 _unmanagedPtr = IntPtr.Zero;
139             }
140         }
141
142         public void Dispose()
143         {
144             Dispose(true);
145             GC.SuppressFinalize(this);
146         }
147
148         internal void SendItemDeleted(object data)
149         {
150             // data is user inserted value with GenItem
151             DeleteHandler?.Invoke(data);
152         }
153
154         protected virtual IntPtr CreateItemClass()
155         {
156             return Interop.Elementary.elm_genlist_item_class_new();
157         }
158
159         protected virtual void ReleaseItemClass(IntPtr unmanagedPtr)
160         {
161             Interop.Elementary.elm_genlist_item_class_free(unmanagedPtr);
162         }
163
164         string GetTextCallback(IntPtr data, IntPtr obj, IntPtr part)
165         {
166             GenItem item = ItemObject.GetItemById((int)data) as GenItem;
167             return GetTextHandler?.Invoke(item?.Data, Marshal.PtrToStringAnsi(part));
168         }
169
170         IntPtr GetContentCallback(IntPtr data, IntPtr obj, IntPtr part)
171         {
172             GenItem item = ItemObject.GetItemById((int)data) as GenItem;
173             EvasObject evasObject = GetContentHandler?.Invoke(item?.Data, Marshal.PtrToStringAnsi(part));
174             if (evasObject != null)
175             {
176                 s_HandleToEvasObject[evasObject.Handle] = evasObject;
177                 evasObject.Deleted += EvasObjectDeleted;
178             }
179             return evasObject;
180         }
181
182         void EvasObjectDeleted(object sender, EventArgs e)
183         {
184             IntPtr handle = (sender as EvasObject).Handle;
185             s_HandleToEvasObject.Remove(handle);
186         }
187
188         IntPtr GetReusableContentCallback(IntPtr data, IntPtr obj, IntPtr part, IntPtr old)
189         {
190             IntPtr reusedHandle = IntPtr.Zero;
191             GenItem item = ItemObject.GetItemById((int)data) as GenItem;
192             if (s_HandleToEvasObject.ContainsKey(old))
193             {
194                 reusedHandle = ReusableContentHandler?.Invoke(item?.Data, Marshal.PtrToStringAnsi(part), s_HandleToEvasObject[old]);
195             }
196             return reusedHandle;
197         }
198
199         void DelCallback(IntPtr data, IntPtr obj)
200         {
201             // We can't use this callback
202             // because, when item was deleted
203             // First, ItemObject deleted callback was called
204             // and We need to clean up ItemObject related objects
205             // This callback was called after ItemObject deleted callback was completed.
206             // So, We can't get resource reletated with ItemObject
207         }
208     }
209
210     public class GenGridItemClass : GenItemClass
211     {
212         public GenGridItemClass(string style) : base(style)
213         {
214         }
215
216         protected override IntPtr CreateItemClass()
217         {
218             return Interop.Elementary.elm_gengrid_item_class_new();
219         }
220
221         protected override void ReleaseItemClass(IntPtr unmanagedPtr)
222         {
223             Interop.Elementary.elm_gengrid_item_class_free(unmanagedPtr);
224         }
225     }
226
227     [StructLayout(LayoutKind.Sequential)]
228     internal class ItemClass
229     {
230         public delegate string GetTextCallback(IntPtr data, IntPtr obj, IntPtr part);
231
232         public delegate IntPtr GetContentCallback(IntPtr data, IntPtr obj, IntPtr part);
233
234         public delegate int GetStateCallback(IntPtr data, IntPtr obj, IntPtr part);
235
236         public delegate void DelCallback(IntPtr data, IntPtr obj);
237
238         public delegate int FilterCallback(IntPtr data, IntPtr obj, IntPtr key);
239
240         public delegate IntPtr GetReusableContentCallback(IntPtr data, IntPtr obj, IntPtr part, IntPtr old);
241
242         public int version;
243         public uint refCount;
244         public int deleteMe;
245         public string itemStyle;
246         public readonly string decorateItemStyle;
247         public readonly string decorateAllItemStyle;
248         public GetTextCallback textCallback;
249         public GetContentCallback contentCallback;
250         public GetStateCallback stateCallback;
251         public DelCallback delCallback;
252         public FilterCallback filterCallback;
253         public GetReusableContentCallback reusableContentCallback;
254     }
255 }