Add recycle cache feature in genlist
authorSeungkeun Lee <sngn.lee@samsung.com>
Tue, 29 Nov 2016 04:32:35 +0000 (13:32 +0900)
committerKangho Hur <kangho.hur@samsung.com>
Tue, 13 Dec 2016 01:37:50 +0000 (10:37 +0900)
Change-Id: I9da339419dbfadb81ae991f9c97f59d6f1f8ba3a

src/ElmSharp/ElmSharp/GenItemClass.cs
test/ElmSharp.Test/ElmSharp.Test.csproj
test/ElmSharp.Test/TC/GenListTest8.cs [new file with mode: 0644]

index 944b700..0ece261 100644 (file)
  */
 
 using System;
+using System.Collections.Generic;
 using System.Runtime.InteropServices;
 
 namespace ElmSharp
 {
     public class GenItemClass : IDisposable
     {
+        private static Dictionary<IntPtr, EvasObject> s_HandleToEvasObject = new Dictionary<IntPtr, EvasObject>();
         public delegate string GetTextDelegate(object data, string part);
         public delegate EvasObject GetContentDelegate(object data, string part);
         public delegate void DeleteDelegate(object data);
+        public delegate EvasObject GetReusableContentDelegate(object data, string part, EvasObject old);
 
         private ItemClass _itemClass;
         private IntPtr _unmanagedPtr = IntPtr.Zero;
@@ -32,16 +35,16 @@ namespace ElmSharp
         public GenItemClass(string style)
         {
             _style = style;
-            _itemClass = new ItemClass()
-            {
-                refCount = 1,
-                deleteMe = 0,
-                itemStyle = style,
-                textCallback = GetTextCallback,
-                contentCallback = GetContentCallback,
-                stateCallback = null,
-                delCallback = DelCallback,
-            };
+            IntPtr unmanaged = Interop.Elementary.elm_genlist_item_class_new();
+            _itemClass = Marshal.PtrToStructure<ItemClass>(unmanaged);
+            _itemClass.itemStyle = style;
+            _itemClass.textCallback = GetTextCallback;
+            _itemClass.contentCallback = GetContentCallback;
+            _itemClass.stateCallback = null;
+            _itemClass.delCallback = DelCallback;
+            _itemClass.reusableContentCallback = GetReusableContentCallback;
+
+            Interop.Elementary.elm_genlist_item_class_free(unmanaged);
         }
 
         ~GenItemClass()
@@ -53,6 +56,7 @@ namespace ElmSharp
         public GetTextDelegate GetTextHandler { get; set; }
         public GetContentDelegate GetContentHandler { get; set; }
         public DeleteDelegate DeleteHandler { get; set; }
+        public GetReusableContentDelegate ReusableContentHandler { get; set; }
 
         internal IntPtr UnmanagedPtr
         {
@@ -99,7 +103,30 @@ namespace ElmSharp
         private IntPtr GetContentCallback(IntPtr data, IntPtr obj, IntPtr part)
         {
             GenItem item = ItemObject.GetItemById((int)data) as GenItem;
-            return GetContentHandler?.Invoke(item?.Data, Marshal.PtrToStringAnsi(part));
+            EvasObject evasObject = GetContentHandler?.Invoke(item?.Data, Marshal.PtrToStringAnsi(part));
+            if (evasObject != null)
+            {
+                s_HandleToEvasObject[evasObject.Handle] = evasObject;
+                evasObject.Deleted += EvasObjectDeleted;
+            }
+            return evasObject;
+        }
+
+        private void EvasObjectDeleted(object sender, EventArgs e)
+        {
+            IntPtr handle = (sender as EvasObject).Handle;
+            s_HandleToEvasObject.Remove(handle);
+        }
+
+        private IntPtr GetReusableContentCallback(IntPtr data, IntPtr obj, IntPtr part, IntPtr old)
+        {
+            IntPtr reusedHandle = IntPtr.Zero;
+            GenItem item = ItemObject.GetItemById((int)data) as GenItem;
+            if (s_HandleToEvasObject.ContainsKey(old))
+            {
+                reusedHandle = ReusableContentHandler?.Invoke(item?.Data, Marshal.PtrToStringAnsi(part), s_HandleToEvasObject[old]);
+            }
+            return reusedHandle;
         }
         private void DelCallback(IntPtr data, IntPtr obj)
         {
@@ -120,8 +147,9 @@ namespace ElmSharp
         public delegate int GetStateCallback(IntPtr data, IntPtr obj, IntPtr part);
         public delegate void DelCallback(IntPtr data, IntPtr obj);
         public delegate int FilterCallback(IntPtr data, IntPtr obj, IntPtr key);
+        public delegate IntPtr GetReusableContentCallback(IntPtr data, IntPtr obj, IntPtr part, IntPtr old);
 
-        public readonly int version;
+        public int version;
         public uint refCount;
         public int deleteMe;
         public string itemStyle;
@@ -132,6 +160,7 @@ namespace ElmSharp
         public GetStateCallback stateCallback;
         public DelCallback delCallback;
         public FilterCallback filterCallback;
+        public GetReusableContentCallback reusableContentCallback;
     }
 
 }
index b019daa..a532bdc 100644 (file)
@@ -64,6 +64,7 @@
     <Compile Include="TC\GenListTest4.cs" />
     <Compile Include="TC\GenListTest6.cs" />
     <Compile Include="TC\TableTest1.cs" />
+    <Compile Include="TC\GenListTest8.cs" />
     <Compile Include="TC\PerformanceTest.cs" />
     <Compile Include="TC\GenListTest5.cs" />
     <Compile Include="TC\IconTest1.cs" />
       </FlavorProperties>
     </VisualStudio>
   </ProjectExtensions>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/test/ElmSharp.Test/TC/GenListTest8.cs b/test/ElmSharp.Test/TC/GenListTest8.cs
new file mode 100644 (file)
index 0000000..6316235
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using ElmSharp;
+using System.Collections.Generic;
+
+namespace ElmSharp.Test
+{
+    class GenListTest8 : TestCaseBase
+    {
+
+        Dictionary<EvasObject, Button> _cacheMap = new Dictionary<EvasObject, Button>();
+        public override string TestName => "GenListTest8";
+        public override string TestDescription => "To test group operation of GenList";
+
+        public override void Run(Window window)
+        {
+            Background bg = new Background(window)
+            {
+                Color = Color.White,
+                AlignmentX = -1,
+                AlignmentY = -1,
+                WeightX = 1,
+                WeightY = 1
+            };
+            bg.Show();
+            bg.Lower();
+
+            window.AddResizeObject(bg);
+            Conformant conformant = new Conformant(window);
+            conformant.Show();
+            Box box = new Box(window)
+            {
+                AlignmentX = -1,
+                AlignmentY = -1,
+                WeightX = 1,
+                WeightY = 1
+            };
+            Check check = new Check(window);
+            check.Show();
+            check.IsChecked = true;
+            check.Text = "Reuse?";
+
+            GenList list = new GenList(window)
+            {
+                Homogeneous = false,
+                AlignmentX = -1,
+                AlignmentY = -1,
+                WeightX = 1,
+                WeightY = 1
+            };
+
+            GenItemClass fullyCustomizeClass = new GenItemClass("full")
+            {
+                GetContentHandler = (obj, part) =>
+                {
+                    Console.WriteLine("{0} part create requested", part);
+                    var btn = new Button(window)
+                    {
+                        AlignmentX = -1,
+                        WeightX = 1,
+                        Text = (string)obj
+                    };
+                    return btn;
+                },
+                ReusableContentHandler = (object data, string part, EvasObject old) =>
+                {
+                    Console.WriteLine("{0} part reuse requested", part);
+                    if (!check.IsChecked)
+                    {
+                        return null;
+                    }
+                    var btn = old as Button;
+                    btn.Text = (string)data;
+                    return old;
+                }
+            };
+
+            for (int i = 0; i < 100; i++)
+            {
+                list.Append(fullyCustomizeClass, string.Format("{0} Item", i), GenListItemType.Normal);
+            }
+
+            list.Show();
+            list.ItemSelected += List_ItemSelected; ;
+            box.Show();
+            box.PackEnd(check);
+            box.PackEnd(list);
+            conformant.SetContent(box);
+        }
+
+        private void List_ItemSelected(object sender, GenListItemEventArgs e)
+        {
+            Console.WriteLine("{0} Item was selected", (string)(e.Item.Data));
+        }
+    }
+}