# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1619829713 0 # Node ID e2ca6c1a4661682387f8f79847fed5d90952bf96 # Parent bf4fe6bb512babd27d42b52c7c4394bc4bcd3cd1 Android: Implement: slider, percent, scrollbar, checkbox_set/get box_unpack_at_index(), and entryfield_set_limit(). diff -r bf4fe6bb512b -r e2ca6c1a4661 android/DWindows.kt --- a/android/DWindows.kt Fri Apr 30 20:21:05 2021 +0000 +++ b/android/DWindows.kt Sat May 01 00:41:53 2021 +0000 @@ -10,6 +10,8 @@ import android.os.Bundle import android.os.Handler import android.os.Looper +import android.text.InputFilter +import android.text.InputFilter.LengthFilter import android.text.method.PasswordTransformationMethod import android.util.Log import android.view.Gravity @@ -17,6 +19,7 @@ import android.view.View import android.view.ViewGroup import android.widget.* +import android.widget.SeekBar.OnSeekBarChangeListener import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.collection.SimpleArrayMap @@ -68,10 +71,8 @@ * These are the Android calls to actually create the UI... * forwarded from the C Dynamic Windows API */ - fun windowNew(title: String, style: Int): LinearLayout? - { - if(firstWindow) - { + fun windowNew(title: String, style: Int): LinearLayout? { + if (firstWindow) { var windowLayout: LinearLayout = LinearLayout(this) var dataArrayMap = SimpleArrayMap() @@ -86,33 +87,26 @@ return null } - fun windowFromId(window: View, cid: Int): View - { + fun windowFromId(window: View, cid: Int): View { return window.findViewById(cid) } - fun windowSetData(window: View, name: String, data: Long) - { - if(window.tag != null) - { + fun windowSetData(window: View, name: String, data: Long) { + if (window.tag != null) { var dataArrayMap: SimpleArrayMap = window.tag as SimpleArrayMap - if(data != 0L) { + if (data != 0L) { dataArrayMap.put(name, data) - } - else - { + } else { dataArrayMap.remove(name) } } } - fun windowGetData(window: View, name: String): Long - { + fun windowGetData(window: View, name: String): Long { var retval: Long = 0L - if (window.tag != null) - { + if (window.tag != null) { var dataArrayMap: SimpleArrayMap = window.tag as SimpleArrayMap retval = dataArrayMap.get(name)!! @@ -120,78 +114,61 @@ return retval } - fun windowSetEnabled(window: View, state: Boolean) - { + fun windowSetEnabled(window: View, state: Boolean) { window.setEnabled(state) } - fun windowSetText(window: View, text: String) - { - if(window is TextView) - { + fun windowSetText(window: View, text: String) { + if (window is TextView) { var textview: TextView = window textview.text = text - } - else if(window is Button) - { + } else if (window is Button) { var button: Button = window button.text = text - } - else if(window is LinearLayout) - { + } else if (window is LinearLayout) { // TODO: Make sure this is actually the top-level layout, not just a box this.title = text } } - fun windowGetText(window: View): String? - { - if(window is TextView) - { + fun windowGetText(window: View): String? { + if (window is TextView) { var textview: TextView = window return textview.text.toString() - } - else if(window is Button) - { + } else if (window is Button) { var button: Button = window return button.text.toString() - } - else if(window is LinearLayout) - { + } else if (window is LinearLayout) { // TODO: Make sure this is actually the top-level layout, not just a box return this.title.toString() } return null } - fun clipboardGetText(): String - { + fun clipboardGetText(): String { var cm: ClipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager var clipdata = cm.primaryClip - if(clipdata != null && clipdata.itemCount > 0) - { + if (clipdata != null && clipdata.itemCount > 0) { return clipdata.getItemAt(0).coerceToText(this).toString() } return "" } - fun clipboardSetText(text: String) - { + fun clipboardSetText(text: String) { var cm: ClipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager var clipdata = ClipData.newPlainText("text", text) cm.setPrimaryClip(clipdata) } - fun boxNew(type: Int, pad: Int): LinearLayout - { + fun boxNew(type: Int, pad: Int): LinearLayout { val box = LinearLayout(this) var dataArrayMap = SimpleArrayMap() box.tag = dataArrayMap box.layoutParams = - LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT) + LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT) if (type > 0) { box.orientation = LinearLayout.VERTICAL } else { @@ -201,13 +178,12 @@ return box } - fun boxPack(box: LinearLayout, item: View, index: Int, width: Int, height: Int, hsize: Int, vsize: Int, pad: Int) - { + fun boxPack(box: LinearLayout, item: View, index: Int, width: Int, height: Int, hsize: Int, vsize: Int, pad: Int) { var w: Int = LinearLayout.LayoutParams.WRAP_CONTENT var h: Int = LinearLayout.LayoutParams.WRAP_CONTENT - if(item is LinearLayout) { - if(box.orientation == LinearLayout.VERTICAL) { + if (item is LinearLayout) { + if (box.orientation == LinearLayout.VERTICAL) { if (hsize > 0) { w = LinearLayout.LayoutParams.MATCH_PARENT } @@ -219,20 +195,20 @@ } var params: LinearLayout.LayoutParams = LinearLayout.LayoutParams(w, h) - if(item !is LinearLayout && (width != -1 || height != -1)) { + if (item !is LinearLayout && (width != -1 || height != -1)) { item.measure(0, 0) if (width > 0) { w = width - } else if(width == -1) { + } else if (width == -1) { w = item.getMeasuredWidth() } if (height > 0) { h = height - } else if(height == -1) { + } else if (height == -1) { h = item.getMeasuredHeight() } } - if(box.orientation == LinearLayout.VERTICAL) { + if (box.orientation == LinearLayout.VERTICAL) { if (vsize > 0) { if (w > 0) { params.weight = w.toFloat() @@ -249,29 +225,36 @@ } } } - if(pad > 0) { + if (pad > 0) { params.setMargins(pad, pad, pad, pad) } var grav: Int = Gravity.CLIP_HORIZONTAL or Gravity.CLIP_VERTICAL - if(hsize > 0 && vsize > 0) { + if (hsize > 0 && vsize > 0) { params.gravity = Gravity.FILL or grav - } else if(hsize > 0) { + } else if (hsize > 0) { params.gravity = Gravity.FILL_HORIZONTAL or grav - } else if(vsize > 0) { + } else if (vsize > 0) { params.gravity = Gravity.FILL_VERTICAL or grav } item.layoutParams = params box.addView(item, index) } - fun boxUnpack(item: View) - { + fun boxUnpack(item: View) { var box: LinearLayout = item.parent as LinearLayout box.removeView(item) } - fun buttonNew(text: String, cid: Int): Button - { + fun boxUnpackAtIndex(box: LinearLayout, index: Int): View? { + var item: View = box.getChildAt(index) + + if (item != null) { + box.removeView(item) + } + return item + } + + fun buttonNew(text: String, cid: Int): Button { val button = Button(this) var dataArrayMap = SimpleArrayMap() @@ -284,23 +267,24 @@ return button } - fun entryfieldNew(text: String, cid: Int, password: Int): EditText - { + fun entryfieldNew(text: String, cid: Int, password: Int): EditText { val entryfield = EditText(this) var dataArrayMap = SimpleArrayMap() entryfield.tag = dataArrayMap entryfield.id = cid - if(password > 0) - { + if (password > 0) { entryfield.transformationMethod = PasswordTransformationMethod.getInstance() } entryfield.setText(text) return entryfield } - fun radioButtonNew(text: String, cid: Int): RadioButton - { + fun entryfieldSetLimit(entryfield: EditText, limit: Long) { + entryfield.filters = arrayOf(LengthFilter(limit.toInt())) + } + + fun radioButtonNew(text: String, cid: Int): RadioButton { val radiobutton = RadioButton(this) var dataArrayMap = SimpleArrayMap() @@ -313,8 +297,7 @@ return radiobutton } - fun checkboxNew(text: String, cid: Int): CheckBox - { + fun checkboxNew(text: String, cid: Int): CheckBox { val checkbox = CheckBox(this) var dataArrayMap = SimpleArrayMap() @@ -327,16 +310,37 @@ return checkbox } - fun textNew(text: String, cid: Int, status: Int): TextView + fun checkOrRadioSetChecked(control: View, state: Int) { + if(control is CheckBox) { + var checkbox: CheckBox = control + checkbox.isChecked = state != 0 + } else if(control is RadioButton) { + var radiobutton: RadioButton = control + radiobutton.isChecked = state != 0 + } + } + + fun checkOrRadioGetChecked(control: View): Boolean + { + if(control is CheckBox) { + var checkbox: CheckBox = control + return checkbox.isChecked + } else if(control is RadioButton) { + var radiobutton: RadioButton = control + return radiobutton.isChecked + } + return false + } + + fun textNew(text: String, cid: Int, status: Int): TextView { val textview = TextView(this) var dataArrayMap = SimpleArrayMap() textview.tag = dataArrayMap textview.id = cid textview.text = text - if(status != 0) - { + if (status != 0) { val border = GradientDrawable() // Set a black border on white background... @@ -349,8 +353,7 @@ return textview } - fun notebookNew(cid: Int, top: Int) - { + fun notebookNew(cid: Int, top: Int) { val notebook = RelativeLayout(this) val pager = ViewPager2(this) val tabs = TabLayout(this) @@ -368,13 +371,62 @@ var params: RelativeLayout.LayoutParams = RelativeLayout.LayoutParams(w, h) tabs.layoutParams = params notebook.addView(tabs) - if(top != 0) { + if (top != 0) { notebook.addView(pager, 0) } else { notebook.addView(pager) } } + fun sliderNew(vertical: Int, increments: Int, cid: Int): SeekBar + { + val slider = SeekBar(this) + var dataArrayMap = SimpleArrayMap() + + slider.tag = dataArrayMap + slider.id = cid + slider.max = increments + if(vertical != 0) { + slider.rotation = 270F + } + slider.setOnSeekBarChangeListener(object : OnSeekBarChangeListener { + override fun onStopTrackingTouch(seekBar: SeekBar) { + } + override fun onStartTrackingTouch(seekBar: SeekBar) { + } + override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { + eventHandler(slider, null, 14, null, null, slider.progress, 0, 0, 0) + } + }) + return slider + } + + fun percentNew(cid: Int): ProgressBar + { + val percent = ProgressBar(this) + var dataArrayMap = SimpleArrayMap() + + percent.tag = dataArrayMap + percent.id = cid + percent.max = 100 + return percent + } + + fun percentGetPos(percent: ProgressBar): Int + { + return percent.progress + } + + fun percentSetPos(percent: ProgressBar, position: Int) + { + percent.progress = position + } + + fun percentSetRange(percent: ProgressBar, range: Int) + { + percent.max = range + } + fun timerConnect(interval: Long, sigfunc: Long, data: Long): Timer { // creating timer task, timer diff -r bf4fe6bb512b -r e2ca6c1a4661 android/dw.cpp --- a/android/dw.cpp Fri Apr 30 20:21:05 2021 +0000 +++ b/android/dw.cpp Sat May 01 00:41:53 2021 +0000 @@ -888,7 +888,19 @@ */ HWND API dw_box_unpack_at_index(HWND box, int index) { - return 0; + JNIEnv *env; + HWND retval = 0; + + if((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 boxUnpackAtIndex = env->GetMethodID(clazz, "boxUnpackAtIndex", + "(Landroid/widget/LinearLayout;I)Landroid/view/View;"); + // Call the method on the object + retval = env->CallObjectMethod(_dw_obj, boxUnpackAtIndex, box, index); + } + return retval; } /* @@ -1024,6 +1036,18 @@ */ void API dw_entryfield_set_limit(HWND handle, ULONG limit) { + JNIEnv *env; + + if((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 entryfieldSetLimit = env->GetMethodID(clazz, "entryfieldSetLimit", + "(Landroid/widget/EditText;J)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, entryfieldSetLimit, handle, (jlong)limit); + } } /* @@ -1156,6 +1180,18 @@ */ HWND API dw_slider_new(int vertical, int increments, ULONG cid) { + JNIEnv *env; + + if((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 sliderNew = env->GetMethodID(clazz, "sliderNew", "(III)Landroid/widget/SeekBar;"); + // Call the method on the object + jobject result = env->NewWeakGlobalRef(env->CallObjectMethod(_dw_obj, sliderNew, vertical, increments, (jint)cid)); + return result; + } return 0; } @@ -1168,6 +1204,18 @@ */ unsigned int API dw_slider_get_pos(HWND handle) { + JNIEnv *env; + + if((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 percentGetPos = env->GetMethodID(clazz, "percentGetPos", + "(Landroid/widget/ProgressBar;)I"); + // Call the method on the object + return env->CallIntMethod(_dw_obj, percentGetPos, handle); + } return 0; } @@ -1179,6 +1227,7 @@ */ void API dw_slider_set_pos(HWND handle, unsigned int position) { + dw_percent_set_pos(handle, position); } /* @@ -1191,7 +1240,7 @@ */ HWND API dw_scrollbar_new(int vertical, ULONG cid) { - return 0; + return dw_slider_new(vertical, 100, cid); } /* @@ -1203,7 +1252,7 @@ */ unsigned int API dw_scrollbar_get_pos(HWND handle) { - return 0; + return dw_slider_get_pos(handle); } /* @@ -1214,6 +1263,7 @@ */ void API dw_scrollbar_set_pos(HWND handle, unsigned int position) { + dw_percent_set_pos(handle, position); } /* @@ -1225,6 +1275,18 @@ */ void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible) { + JNIEnv *env; + + if((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 percentSetRange = env->GetMethodID(clazz, "percentSetRange", + "(Landroid/widget/ProgressBar;I)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, percentSetRange, handle, (jint)range); + } } /* @@ -1236,6 +1298,19 @@ */ HWND API dw_percent_new(ULONG cid) { + JNIEnv *env; + + if((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 percentNew = env->GetMethodID(clazz, "percentNew", + "(I)Landroid/widget/ProgressBar;"); + // Call the method on the object + jobject result = env->NewWeakGlobalRef(env->CallObjectMethod(_dw_obj, percentNew, (jint)cid)); + return result; + } return 0; } @@ -1247,6 +1322,18 @@ */ void API dw_percent_set_pos(HWND handle, unsigned int position) { + JNIEnv *env; + + if((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 percentSetPos = env->GetMethodID(clazz, "percentSetPos", + "(Landroid/widget/ProgressBar;I)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, percentSetPos, handle, (jint)position); + } } /* @@ -1286,6 +1373,19 @@ */ int API dw_checkbox_get(HWND handle) { + JNIEnv *env; + + if((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); + jclass clazz = env->FindClass(DW_CLASS_NAME); + // Get the method that you want to call + jmethodID checkOrRadioGetChecked = env->GetMethodID(clazz, "checkOrRadioGetChecked", + "(Landroid/view/View;)Z"); + // Call the method on the object + return env->CallBooleanMethod(_dw_obj, checkOrRadioGetChecked, handle); + } return FALSE; } @@ -1297,6 +1397,19 @@ */ void API dw_checkbox_set(HWND handle, int value) { + JNIEnv *env; + + if((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); + jclass clazz = env->FindClass(DW_CLASS_NAME); + // Get the method that you want to call + jmethodID checkOrRadioSetChecked = env->GetMethodID(clazz, "checkOrRadioSetChecked", + "(Landroid/view/View;I)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, checkOrRadioSetChecked, handle, value); + } } /*