changeset 2777:7d7eac751f7d

Android: Connect the C API to the Kotlin tree implementation.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 22 Jun 2022 07:13:32 +0000
parents 858155527b05
children 1660b4ecb92f
files android/DWindows.kt android/dw.cpp
diffstat 2 files changed, 254 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/android/DWindows.kt	Tue Jun 21 07:55:53 2022 +0000
+++ b/android/DWindows.kt	Wed Jun 22 07:13:32 2022 +0000
@@ -69,17 +69,15 @@
 
 
 // Tree View section
-class DWTreeItem(value: Any, layoutId: Int) {
-    private var value: Any
+class DWTreeItem(title: String, icon: Drawable?, data: Long, parent: DWTreeItem?) {
+    private var title: String
     private var parent: DWTreeItem?
     private val children: LinkedList<DWTreeItem>
-    private val layoutId: Int
     private var level: Int
     private var isExpanded: Boolean
     private var isSelected: Boolean
-    var itemData: Long = 0
-    var itemIcon: Drawable? = null
-    var parentItem: DWTreeItem? = null
+    private var data: Long = 0
+    private var icon: Drawable? = null
 
     fun addChild(child: DWTreeItem) {
         child.setParent(this)
@@ -88,30 +86,42 @@
         updateNodeChildrenDepth(child)
     }
 
-    fun setValue(value: Any) {
-        this.value = value
-    }
-
-    fun getValue(): Any {
-        return value
+    fun setTitle(title: String) {
+        this.title = title
+    }
+
+    fun getTitle(): String {
+        return title
+    }
+
+    fun setIcon(icon: Drawable?) {
+        this.icon = icon
+    }
+
+    fun getIcon(): Drawable? {
+        return icon
+    }
+
+    fun setData(data: Long) {
+        this.data = data
+    }
+
+    fun getData(): Long {
+        return data
+    }
+
+    fun getParent(): DWTreeItem? {
+        return parent
     }
 
     fun setParent(parent: DWTreeItem?) {
         this.parent = parent
     }
 
-    fun getParent(): DWTreeItem? {
-        return parent
-    }
-
     fun getChildren(): LinkedList<DWTreeItem> {
         return children
     }
 
-    fun getLayoutId(): Int {
-        return layoutId
-    }
-
     fun setLevel(level: Int) {
         this.level = level
     }
@@ -144,15 +154,17 @@
     }
 
     init {
-        this.value = value
-        parent = null
+        this.title = title
+        this.icon = icon
+        this.data = data
+        this.parent = parent
         children = LinkedList()
-        this.layoutId = layoutId
         level = 0
         isExpanded = false
         isSelected = false
     }
 }
+
 class DWTreeItemManager {
     // Collection to save the current tree nodes
     private val rootsNodes: LinkedList<DWTreeItem>
@@ -457,7 +469,8 @@
     }
 
     override fun getItemViewType(position: Int): Int {
-        return treeItemManager.get(position).getLayoutId()
+        // TODO: Fix this with no layoutId
+        return 0
     }
 
     override fun getItemCount(): Int {
@@ -530,6 +543,11 @@
         notifyItemRangeInserted(0, treeItems.size)
     }
 
+    // Clear all the items from the tree
+    fun clear() {
+        treeItemManager.clearItems()
+    }
+
     // Register a callback to be invoked when this DWTreeItem is clicked
     // @param listener The callback that will run
     fun setTreeItemClickListener(listener: OnTreeItemClickListener?) {
@@ -4530,19 +4548,98 @@
         waitOnUiThread {
             var treeViewAdapter = tree.adapter as DWTreeViewAdapter
 
-            treeitem = DWTreeItem(title, 0)
+            treeitem = DWTreeItem(title, icon, itemdata, parent)
             if(parent == null) {
                 tree.roots.add(treeitem!!)
             } else {
                 parent.addChild(treeitem!!)
-                treeitem!!.parentItem = parent
-            }
-            treeitem!!.itemData = itemdata
-            treeitem!!.itemIcon = icon
+            }
         }
         return treeitem
     }
 
+    fun treeGetTitle(tree: DWTree, item: DWTreeItem): String?
+    {
+        var retval: String? = null
+
+        waitOnUiThread {
+            retval = item.getTitle()
+        }
+        return retval
+    }
+
+    fun treeGetParent(tree: DWTree, item: DWTreeItem): DWTreeItem?
+    {
+        var retval: DWTreeItem? = null
+
+        waitOnUiThread {
+            retval = item.getParent()
+        }
+        return retval
+    }
+
+    fun treeItemChange(tree: DWTree, item: DWTreeItem, title: String?, icon: Drawable?)
+    {
+        waitOnUiThread {
+            if(title != null) {
+                item.setTitle(title)
+            }
+            if(icon != null) {
+                item.setIcon(icon)
+            }
+        }
+    }
+
+    fun treeItemSetData(tree: DWTree, item: DWTreeItem, data: Long)
+    {
+        waitOnUiThread {
+            item.setData(data)
+        }
+    }
+
+    fun treeItemGetData(tree: DWTree, item: DWTreeItem): Long
+    {
+        var retval: Long = 0
+
+        waitOnUiThread {
+            retval = item.getData()
+        }
+        return retval
+    }
+
+    fun treeItemSelect(tree: DWTree, item: DWTreeItem)
+    {
+        waitOnUiThread {
+            item.setSelected(true)
+        }
+    }
+
+    fun treeItemExpand(tree: DWTree, item: DWTreeItem, state: Int)
+    {
+        waitOnUiThread {
+            val treeViewAdapter = tree.adapter as DWTreeViewAdapter
+
+            if(state != 0) {
+                treeViewAdapter.expandNode(item)
+            } else {
+                treeViewAdapter.collapseNode(item)
+            }
+        }
+    }
+
+    fun treeItemDelete(tree: DWTree, item: DWTreeItem)
+    {
+        // TODO: Implement this
+    }
+
+    fun treeClear(tree: DWTree)
+    {
+        waitOnUiThread {
+            val treeViewAdapter = tree.adapter as DWTreeViewAdapter
+            treeViewAdapter.clear()
+        }
+    }
+
     fun containerNew(cid: Int, multi: Int): ListView?
     {
         var cont: ListView? = null
--- a/android/dw.cpp	Tue Jun 21 07:55:53 2022 +0000
+++ b/android/dw.cpp	Wed Jun 22 07:13:32 2022 +0000
@@ -3316,7 +3316,7 @@
 {
     JNIEnv *env;
 
-    if((env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    if(handle && title && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
     {
         // Construct the string
         jstring jstr = env->NewStringUTF(title);
@@ -3359,7 +3359,24 @@
  */
 char * API dw_tree_get_title(HWND handle, HTREEITEM item)
 {
-    /* TODO: Implement the tree if possible. */
+    JNIEnv *env;
+
+    if(handle && item && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        const char *utf8 = nullptr;
+
+        // First get the class that contains the method you need to call
+        jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
+        // Get the method that you want to call
+        jmethodID treeGetTitle = env->GetMethodID(clazz, "treeGetTitle",
+                                                   "(Lorg/dbsoft/dwindows/DWTree;Lorg/dbsoft/dwindows/DWTreeItem;)Ljava/lang/String;");
+        // Call the method on the object
+        jstring result = (jstring)_dw_jni_check_result(env, env->CallObjectMethod(_dw_obj, treeGetTitle, handle, item), _DW_REFERENCE_NONE);
+        // Get the UTF8 string result
+        if(result)
+            utf8 = env->GetStringUTFChars(result, nullptr);
+        return utf8 ? strdup(utf8) : nullptr;
+    }
     return nullptr;
 }
 
@@ -3373,7 +3390,19 @@
  */
 HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item)
 {
-    /* TODO: Implement the tree if possible. */
+    JNIEnv *env;
+
+    if(handle && item && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        // First get the class that contains the method you need to call
+        jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
+        // Get the method that you want to call
+        jmethodID treeGetParent = env->GetMethodID(clazz, "treeGetParent",
+                                                  "(Lorg/dbsoft/dwindows/DWTree;Lorg/dbsoft/dwindows/DWTreeItem;)Lorg/dbsoft/dwindows/DWTreeItem;");
+        // Call the method on the object
+        jobject result = _dw_jni_check_result(env, env->CallObjectMethod(_dw_obj, treeGetParent, handle, item), _DW_REFERENCE_WEAK);
+        return result;
+    }
     return nullptr;
 }
 
@@ -3387,7 +3416,20 @@
  */
 void API dw_tree_item_change(HWND handle, HTREEITEM item, const char *title, HICN icon)
 {
-    /* TODO: Implement the tree if possible. */
+    JNIEnv *env;
+
+    if(handle && item && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        // Construct the string
+        jstring jstr = title ? env->NewStringUTF(title) : nullptr;
+        // First get the class that contains the method you need to call
+        jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
+        // Get the method that you want to call
+        jmethodID treeItemChange = env->GetMethodID(clazz, "treeItemChange",
+                                                    "(Lorg/dbsoft/dwindows/DWTree;Lorg/dbsoft/dwindows/DWTreeItem;Ljava/lang/String;Landroid/graphics/drawable/Drawable;)V");
+        // Call the method on the object
+        env->CallVoidMethod(_dw_obj, treeItemChange, handle, item, jstr, icon);
+    }
 }
 
 /*
@@ -3399,7 +3441,19 @@
  */
 void API dw_tree_item_set_data(HWND handle, HTREEITEM item, void *itemdata)
 {
-    /* TODO: Implement the tree if possible. */
+    JNIEnv *env;
+
+    if(handle && item && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        jlong data = (jlong)itemdata;
+        // First get the class that contains the method you need to call
+        jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
+        // Get the method that you want to call
+        jmethodID treeItemSetData = env->GetMethodID(clazz, "treeItemSetData",
+                                                     "(Lorg/dbsoft/dwindows/DWTree;Lorg/dbsoft/dwindows/DWTreeItem;J)V");
+        // Call the method on the object
+        env->CallVoidMethod(_dw_obj, treeItemSetData, handle, item, data);
+    }
 }
 
 /*
@@ -3412,8 +3466,20 @@
  */
 void * API dw_tree_item_get_data(HWND handle, HTREEITEM item)
 {
-    /* TODO: Implement the tree if possible. */
-    return nullptr;
+    JNIEnv *env;
+    void *retval = nullptr;
+
+    if(handle && item && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        // First get the class that contains the method you need to call
+        jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
+        // Get the method that you want to call
+        jmethodID treeItemGetData = env->GetMethodID(clazz, "treeItemGetData",
+                                                     "(Lorg/dbsoft/dwindows/DWTree;Lorg/dbsoft/dwindows/DWTreeItem;)J");
+        // Call the method on the object
+        retval = (void *)env->CallLongMethod(_dw_obj, treeItemGetData, handle, item);
+    }
+    return retval;
 }
 
 /*
@@ -3424,7 +3490,18 @@
  */
 void API dw_tree_item_select(HWND handle, HTREEITEM item)
 {
-    /* TODO: Implement the tree if possible. */
+    JNIEnv *env;
+
+    if(handle && item && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        // First get the class that contains the method you need to call
+        jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
+        // Get the method that you want to call
+        jmethodID treeItemSelect = env->GetMethodID(clazz, "treeItemSelect",
+                                                    "(Lorg/dbsoft/dwindows/DWTree;Lorg/dbsoft/dwindows/DWTreeItem;)V");
+        // Call the method on the object
+        env->CallVoidMethod(_dw_obj, treeItemSelect, handle, item);
+    }
 }
 
 /*
@@ -3434,7 +3511,35 @@
  */
 void API dw_tree_clear(HWND handle)
 {
-    /* TODO: Implement the tree if possible. */
+    JNIEnv *env;
+
+    if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        // First get the class that contains the method you need to call
+        jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
+        // Get the method that you want to call
+        jmethodID treeClear = env->GetMethodID(clazz, "treeClear",
+                                               "(Lorg/dbsoft/dwindows/DWTree;)V");
+        // Call the method on the object
+        env->CallVoidMethod(_dw_obj, treeClear, handle);
+    }
+}
+
+/* Internal function to set the expanded state */
+void _dw_tree_item_set_expanded(HWND handle, HTREEITEM item, jint state)
+{
+    JNIEnv *env;
+
+    if(handle && item && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        // First get the class that contains the method you need to call
+        jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
+        // Get the method that you want to call
+        jmethodID treeItemExpand = env->GetMethodID(clazz, "treeItemExpand",
+                                                    "(Lorg/dbsoft/dwindows/DWTree;Lorg/dbsoft/dwindows/DWTreeItem;I)V");
+        // Call the method on the object
+        env->CallVoidMethod(_dw_obj, treeItemExpand, handle, item, state);
+    }
 }
 
 /*
@@ -3445,7 +3550,7 @@
  */
 void API dw_tree_item_expand(HWND handle, HTREEITEM item)
 {
-    /* TODO: Implement the tree if possible. */
+    _dw_tree_item_set_expanded(handle, item, TRUE);
 }
 
 /*
@@ -3456,7 +3561,7 @@
  */
 void API dw_tree_item_collapse(HWND handle, HTREEITEM item)
 {
-    /* TODO: Implement the tree if possible. */
+    _dw_tree_item_set_expanded(handle, item, FALSE);
 }
 
 /*
@@ -3467,6 +3572,18 @@
  */
 void API dw_tree_item_delete(HWND handle, HTREEITEM item)
 {
+    JNIEnv *env;
+
+    if(handle && item && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        // First get the class that contains the method you need to call
+        jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
+        // Get the method that you want to call
+        jmethodID treeItemDelete = env->GetMethodID(clazz, "treeItemDelete",
+                                                    "(Lorg/dbsoft/dwindows/DWTree;Lorg/dbsoft/dwindows/DWTreeItem;)V");
+        // Call the method on the object
+        env->CallVoidMethod(_dw_obj, treeItemDelete, handle, item);
+    }
 }
 
 /*