changeset 2560:3da35cd91ca7

Android: Implement querying containers and ENTER and CONTEXT callbacks.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Tue, 18 May 2021 18:41:35 +0000
parents b5e8a319fde6
children f28d7d0ca5ed
files android/DWindows.kt android/dw.cpp dwtest.c
diffstat 3 files changed, 252 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/android/DWindows.kt	Tue May 18 07:55:59 2021 +0000
+++ b/android/DWindows.kt	Tue May 18 18:41:35 2021 +0000
@@ -467,6 +467,7 @@
     var data = mutableListOf<Any?>()
     var rowdata = mutableListOf<Long>()
     var rowtitle = mutableListOf<String?>()
+    var querypos: Int = -1
 
     fun numberOfColumns(): Int
     {
@@ -1976,18 +1977,188 @@
 
         waitOnUiThread {
             var dataArrayMap = SimpleArrayMap<String, Long>()
+            var adapter = DWContainerAdapter(this)
 
             cont = ListView(this)
             cont!!.tag = dataArrayMap
             cont!!.id = cid
-            cont!!.adapter = DWContainerAdapter(this)
+            cont!!.adapter = adapter
             if(multi != 0) {
                 cont!!.choiceMode = ListView.CHOICE_MODE_MULTIPLE;
             }
+            cont!!.setOnItemClickListener { parent, view, position, id ->
+                val title = adapter.model.getRowTitle(position)
+                val data = adapter.model.getRowData(position)
+
+                eventHandlerContainer(cont!!, 9, title, 0, 0, data)
+            }
+            cont!!.setOnItemLongClickListener { parent, view, position, id ->
+                val title = adapter.model.getRowTitle(position)
+                val data = adapter.model.getRowData(position)
+
+                eventHandlerContainer(cont!!, 10, title, 0, 0, data)
+                true
+            }
         }
         return cont
     }
 
+    fun containerGetTitleStart(cont: ListView, flags: Int): String?
+    {
+        var retval: String? = null
+
+        waitOnUiThread {
+            val adapter: DWContainerAdapter = cont.adapter as DWContainerAdapter
+
+            // Handle DW_CRA_SELECTED
+            if((flags and 1) != 0) {
+                val checked: SparseBooleanArray = cont.getCheckedItemPositions()
+                val position = checked.keyAt(0)
+
+                if(position != null) {
+                    adapter.model.querypos = position
+                    retval = adapter.model.getRowTitle(position)
+                } else {
+                    adapter.model.querypos = -1
+                }
+            } else {
+                if(adapter.model.rowdata.size == 0) {
+                    adapter.model.querypos = -1
+                } else {
+                    retval = adapter.model.getRowTitle(0)
+                    adapter.model.querypos = 0
+                }
+            }
+        }
+        return retval
+    }
+
+    fun containerGetTitleNext(cont: ListView, flags: Int): String?
+    {
+        var retval: String? = null
+
+        waitOnUiThread {
+            val adapter: DWContainerAdapter = cont.adapter as DWContainerAdapter
+
+            if(adapter.model.querypos != -1) {
+                // Handle DW_CRA_SELECTED
+                if ((flags and 1) != 0) {
+                    val checked: SparseBooleanArray = cont.getCheckedItemPositions()
+
+                    // Otherwise loop until we find our current place
+                    for (i in 0 until checked.size()) {
+                        // Item position in adapter
+                        val position: Int = checked.keyAt(i)
+
+                        if (position != null) {
+                            // If we are at our current point... check to see
+                            // if there is another one, and return it...
+                            // otherwise we will return -1 to indicated we are done.
+                            if (adapter.model.querypos == position && (i + 1) < checked.size()) {
+                                val newpos = checked.keyAt(i + 1)
+
+                                if (newpos != null) {
+                                    adapter.model.querypos = newpos
+                                    retval = adapter.model.getRowTitle(newpos)
+                                } else {
+                                    adapter.model.querypos = -1
+                                }
+                            }
+                        } else {
+                            adapter.model.querypos = -1
+                        }
+                    }
+                } else {
+                    if (adapter.model.rowtitle.size > adapter.model.querypos) {
+                        adapter.model.querypos += 1
+                        retval = adapter.model.getRowTitle(adapter.model.querypos)
+                    } else {
+                        adapter.model.querypos = -1
+                    }
+                }
+            }
+        }
+        return retval
+    }
+
+    fun containerGetDataStart(cont: ListView, flags: Int): Long
+    {
+        var retval: Long = 0
+
+        waitOnUiThread {
+            val adapter: DWContainerAdapter = cont.adapter as DWContainerAdapter
+
+            // Handle DW_CRA_SELECTED
+            if((flags and 1) != 0) {
+                val checked: SparseBooleanArray = cont.getCheckedItemPositions()
+                val position = checked.keyAt(0)
+
+                if(position != null) {
+                    adapter.model.querypos = position
+                    retval = adapter.model.getRowData(position)
+                } else {
+                    adapter.model.querypos = -1
+                }
+            } else {
+                if(adapter.model.rowdata.size == 0) {
+                    adapter.model.querypos = -1
+                } else {
+                    retval = adapter.model.getRowData(0)
+                    adapter.model.querypos = 0
+                }
+            }
+        }
+        return retval
+    }
+
+    fun containerGetDataNext(cont: ListView, flags: Int): Long
+    {
+        var retval: Long = 0
+
+        waitOnUiThread {
+            val adapter: DWContainerAdapter = cont.adapter as DWContainerAdapter
+
+            if(adapter.model.querypos != -1) {
+                // Handle DW_CRA_SELECTED
+                if ((flags and 1) != 0) {
+                    val checked: SparseBooleanArray = cont.getCheckedItemPositions()
+
+                    // Otherwise loop until we find our current place
+                    for (i in 0 until checked.size()) {
+                        // Item position in adapter
+                        val position: Int = checked.keyAt(i)
+
+                        if (position != null) {
+                            // If we are at our current point... check to see
+                            // if there is another one, and return it...
+                            // otherwise we will return -1 to indicated we are done.
+                            if (adapter.model.querypos == position && (i + 1) < checked.size()) {
+                                val newpos = checked.keyAt(i + 1)
+
+                                if (newpos != null) {
+                                    adapter.model.querypos = newpos
+                                    retval = adapter.model.getRowData(newpos)
+                                } else {
+                                    adapter.model.querypos = -1
+                                }
+                            }
+                        } else {
+                            adapter.model.querypos = -1
+                        }
+                    }
+                } else {
+                    if (adapter.model.rowdata.size > adapter.model.querypos) {
+                        adapter.model.querypos += 1
+                        retval = adapter.model.getRowData(adapter.model.querypos)
+                    } else {
+                        adapter.model.querypos = -1
+                    }
+                }
+            }
+        }
+        return retval
+    }
+
     fun containerAddColumn(cont: ListView, title: String, flags: Int)
     {
         waitOnUiThread {
@@ -3076,6 +3247,7 @@
     external fun eventHandlerNotebook(obj1: View, message: Int, pageID: Long)
     external fun eventHandlerTimer(sigfunc: Long, data: Long): Int
     external fun eventHandlerHTMLResult(obj1: View, message: Int, result: String, data: Long)
+    external fun eventHandlerContainer(obj1: View, message: Int, title: String?, x: Int, y: Int, data: Long)
 
     companion object
     {
--- a/android/dw.cpp	Tue May 18 07:55:59 2021 +0000
+++ b/android/dw.cpp	Tue May 18 18:41:35 2021 +0000
@@ -519,6 +519,17 @@
     _dw_event_handler(obj, params, message);
 }
 
+JNIEXPORT void JNICALL
+Java_org_dbsoft_dwindows_DWindows_eventHandlerContainer(JNIEnv* env, jobject obj, jobject obj1,
+                                                  jint message, jstring jtitle, jint x, jint y, jlong data) {
+    const char *title = jtitle ? env->GetStringUTFChars(jtitle, nullptr) : nullptr;
+    void *params[8] = { nullptr, (void *)title, nullptr,
+                        DW_INT_TO_POINTER(x), DW_INT_TO_POINTER(y),
+                        nullptr, nullptr, (void *)data };
+
+    _dw_event_handler(obj1, params, message);
+}
+
 /* Handler for Timer events */
 JNIEXPORT jint JNICALL
 Java_org_dbsoft_dwindows_DWindows_eventHandlerTimer(JNIEnv* env, jobject obj, jlong sigfunc, jlong data) {
@@ -3352,6 +3363,14 @@
  */
 void API dw_container_set_row_title(void *pointer, int row, const char *title)
 {
+    HWND handle = (HWND)pointer;
+
+    if(handle)
+    {
+        int rowstart = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_rowstart"));
+
+        dw_container_change_row_title(handle, row + rowstart, title);
+    }
 }
 
 
@@ -3467,6 +3486,33 @@
  */
 char * API dw_container_query_start(HWND handle, unsigned long flags)
 {
+    JNIEnv *env;
+    char *retval = nullptr;
+
+    if((env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        if(flags & DW_CR_RETDATA) {
+            // 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 containerGetDataStart = env->GetMethodID(clazz, "containerGetDataStart",
+                                                               "(Landroid/widget/ListView;I)J");
+            // Call the method on the object
+            jlong data = env->CallLongMethod(_dw_obj, containerGetDataStart, handle, (int)flags);
+            if(!_dw_jni_check_exception(env))
+                retval = (char *)data;
+        } else {
+            // 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 containerGetDataStart = env->GetMethodID(clazz, "containerGetTitleStart",
+                                                               "(Landroid/widget/ListView;I)Ljava/lang/String;");
+            // Call the method on the object
+            jstring jstr = (jstring)_dw_jni_check_result(env, env->CallObjectMethod(_dw_obj, containerGetDataStart, handle, (int)flags), _DW_REFERENCE_NONE);
+            if(jstr)
+                retval = (char *)env->GetStringUTFChars(jstr, nullptr);
+        }
+    }
     return nullptr;
 }
 
@@ -3482,6 +3528,33 @@
  */
 char * API dw_container_query_next(HWND handle, unsigned long flags)
 {
+    JNIEnv *env;
+    char *retval = nullptr;
+
+    if((env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
+    {
+        if(flags & DW_CR_RETDATA) {
+            // 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 containerGetDataStart = env->GetMethodID(clazz, "containerGetDataNext",
+                                                               "(Landroid/widget/ListView;I)J");
+            // Call the method on the object
+            jlong data = env->CallLongMethod(_dw_obj, containerGetDataStart, handle, (int)flags);
+            if(!_dw_jni_check_exception(env))
+                retval = (char *)data;
+        } else {
+            // 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 containerGetDataStart = env->GetMethodID(clazz, "containerGetTitleNext",
+                                                               "(Landroid/widget/ListView;I)Ljava/lang/String;");
+            // Call the method on the object
+            jstring jstr = (jstring)_dw_jni_check_result(env, env->CallObjectMethod(_dw_obj, containerGetDataStart, handle, (int)flags), _DW_REFERENCE_NONE);
+            if(jstr)
+                retval = (char *)env->GetStringUTFChars(jstr, nullptr);
+        }
+    }
     return nullptr;
 }
 
--- a/dwtest.c	Tue May 18 07:55:59 2021 +0000
+++ b/dwtest.c	Tue May 18 18:41:35 2021 +0000
@@ -907,15 +907,15 @@
     else
     {
         column_type = dw_filesystem_get_column_type(window, column_num-1);
-        if( column_type == DW_CFA_STRING)
+        if(column_type == DW_CFA_STRING)
             strcpy(buf1,"String");
-        else if( column_type == DW_CFA_ULONG)
+        else if(column_type == DW_CFA_ULONG)
             strcpy(buf1,"ULong");
-        else if( column_type == DW_CFA_DATE)
+        else if(column_type == DW_CFA_DATE)
             strcpy(buf1,"Date");
-        else if( column_type == DW_CFA_TIME)
+        else if(column_type == DW_CFA_TIME)
             strcpy(buf1,"Time");
-        else if( column_type == DW_CFA_BITMAPORICON)
+        else if(column_type == DW_CFA_BITMAPORICON)
             strcpy(buf1,"BitmapOrIcon");
         else
             strcpy(buf1,"Unknown");
@@ -1106,7 +1106,7 @@
 
     /* create a box to pack into the notebook page */
     pagebox = dw_box_new(DW_HORZ, 2);
-    dw_box_pack_start( notebookbox2, pagebox, 0, 0, TRUE, TRUE, 0);
+    dw_box_pack_start(notebookbox2, pagebox, 0, 0, TRUE, TRUE, 0);
     /* now a status area under this box */
     hbox = dw_box_new(DW_HORZ, 1 );
     dw_box_pack_start(notebookbox2, hbox, 100, 20, TRUE, FALSE, 1);