# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1639015072 0 # Node ID 9ce1649b0fbdb8c746a0bc16ded732077b0c3b09 # Parent 6754e8f7014290beb7e82a3ba44ba68afa0750fe Android: Fix vertical sliders/scrollbars by creating a DWSlider class to encapsulate the SeekBar... then override the measurements and adjust the width. The width on the SeekBar needs to be set to the height after rotation... Since that is not the actually correct width, we need to wrap it in a frame. diff -r 6754e8f70142 -r 9ce1649b0fbd android/DWindows.kt --- a/android/DWindows.kt Wed Dec 08 12:54:25 2021 +0000 +++ b/android/DWindows.kt Thu Dec 09 01:57:52 2021 +0000 @@ -65,8 +65,7 @@ import android.util.Base64 import kotlin.math.* import android.content.ContentUris - - +import androidx.appcompat.widget.AppCompatSeekBar // Color Wheel section @@ -943,6 +942,32 @@ external fun eventHandlerHTMLChanged(obj1: View, message: Int, URI: String, status: Int) } +class DWSlider +@JvmOverloads constructor(context: Context): FrameLayout(context) { + val slider: SeekBar = SeekBar(context) + + init { + slider.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.WRAP_CONTENT, Gravity.CENTER) + addView(slider) + } + + @Synchronized + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { + if(slider.rotation == 90F || slider.rotation == 270F) { + val layoutHeight = MeasureSpec.getSize(heightMeasureSpec) + // set slider width to layout heigth + slider.layoutParams.width = layoutHeight + } + super.onMeasure(widthMeasureSpec, heightMeasureSpec) + if(slider.rotation == 90F || slider.rotation == 270F) { + // update layout width to the rotated height of the slider + // otherwise the layout remains quadratic + setMeasuredDimension(slider.measuredHeight, measuredHeight) + } + } +} + class DWSpinButton(context: Context) : AppCompatEditText(context), OnTouchListener { var value: Long = 0 var minimum: Long = 0 @@ -3552,23 +3577,23 @@ } } - fun scrollBarNew(vertical: Int, cid: Int): SeekBar? + fun scrollBarNew(vertical: Int, cid: Int): DWSlider? { - var slider: SeekBar? = null + var scrollbar: DWSlider? = null waitOnUiThread { val dataArrayMap = SimpleArrayMap() - slider = SeekBar(this) - slider!!.tag = dataArrayMap - slider!!.id = cid - slider!!.max = 1 - slider!!.progressTintList = null - slider!!.progressBackgroundTintList = null + scrollbar = DWSlider(this) + scrollbar!!.tag = dataArrayMap + scrollbar!!.id = cid + scrollbar!!.slider.max = 1 + scrollbar!!.slider.progressTintList = null + scrollbar!!.slider.progressBackgroundTintList = null if (vertical != 0) { - slider!!.rotation = 90F + scrollbar!!.slider.rotation = 90F } - slider!!.setOnSeekBarChangeListener(object : OnSeekBarChangeListener { + scrollbar!!.slider.setOnSeekBarChangeListener(object : OnSeekBarChangeListener { override fun onStopTrackingTouch(seekBar: SeekBar) { } @@ -3576,28 +3601,28 @@ } override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { - eventHandlerInt(slider as View, DWEvent.VALUE_CHANGED, slider!!.progress, 0, 0, 0) + eventHandlerInt(scrollbar as View, DWEvent.VALUE_CHANGED, scrollbar!!.slider.progress, 0, 0, 0) } }) } - return slider - } - - fun sliderNew(vertical: Int, increments: Int, cid: Int): SeekBar? + return scrollbar + } + + fun sliderNew(vertical: Int, increments: Int, cid: Int): DWSlider? { - var slider: SeekBar? = null + var slider: DWSlider? = null waitOnUiThread { val dataArrayMap = SimpleArrayMap() - slider = SeekBar(this) + slider = DWSlider(this) slider!!.tag = dataArrayMap slider!!.id = cid - slider!!.max = increments + slider!!.slider.max = increments if (vertical != 0) { - slider!!.rotation = 90F + slider!!.slider.rotation = 90F } - slider!!.setOnSeekBarChangeListener(object : OnSeekBarChangeListener { + slider!!.slider.setOnSeekBarChangeListener(object : OnSeekBarChangeListener { override fun onStopTrackingTouch(seekBar: SeekBar) { } @@ -3605,7 +3630,7 @@ } override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { - eventHandlerInt(slider as View, DWEvent.VALUE_CHANGED, slider!!.progress, 0, 0, 0) + eventHandlerInt(slider as View, DWEvent.VALUE_CHANGED, slider!!.slider.progress, 0, 0, 0) } }) } @@ -3627,27 +3652,51 @@ return percent } - fun percentGetPos(percent: ProgressBar): Int + fun percentGetPos(percent: View): Int { var retval = 0 waitOnUiThread { - retval = percent.progress + var progress: ProgressBar + + if(percent is ProgressBar) { + progress = percent as ProgressBar + } else { + val slider = percent as DWSlider + progress = slider.slider + } + retval = progress.progress } return retval } - fun percentSetPos(percent: ProgressBar, position: Int) + fun percentSetPos(percent: View, position: Int) { waitOnUiThread { - percent.progress = position - } - } - - fun percentSetRange(percent: ProgressBar, range: Int) + var progress: ProgressBar + + if(percent is ProgressBar) { + progress = percent as ProgressBar + } else { + val slider = percent as DWSlider + progress = slider.slider + } + progress.progress = position + } + } + + fun percentSetRange(percent: View, range: Int) { waitOnUiThread { - percent.max = range + var progress: ProgressBar + + if(percent is ProgressBar) { + progress = percent as ProgressBar + } else { + val slider = percent as DWSlider + progress = slider.slider + } + progress.max = range } } diff -r 6754e8f70142 -r 9ce1649b0fbd android/dw.cpp --- a/android/dw.cpp Wed Dec 08 12:54:25 2021 +0000 +++ b/android/dw.cpp Thu Dec 09 01:57:52 2021 +0000 @@ -1929,7 +1929,8 @@ // 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;"); + jmethodID sliderNew = env->GetMethodID(clazz, "sliderNew", + "(III)Lorg/dbsoft/dwindows/DWSlider;"); // Call the method on the object jobject result = _dw_jni_check_result(env, env->CallObjectMethod(_dw_obj, sliderNew, vertical, increments, (jint)cid), _DW_REFERENCE_WEAK); return result; @@ -1955,7 +1956,7 @@ 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"); + "(Landroid/view/View;)I"); // Call the method on the object retval = env->CallIntMethod(_dw_obj, percentGetPos, handle); if(_dw_jni_check_exception(env)) @@ -1992,7 +1993,8 @@ // 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 scrollBarNew = env->GetMethodID(clazz, "scrollBarNew", "(II)Landroid/widget/SeekBar;"); + jmethodID scrollBarNew = env->GetMethodID(clazz, "scrollBarNew", + "(II)Lorg/dbsoft/dwindows/DWSlider;"); // Call the method on the object jobject result = _dw_jni_check_result(env, env->CallObjectMethod(_dw_obj, scrollBarNew, vertical, (jint)cid), _DW_REFERENCE_WEAK); return result; @@ -2040,7 +2042,7 @@ 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"); + "(Landroid/view/View;I)V"); // Call the method on the object env->CallVoidMethod(_dw_obj, percentSetRange, handle, (jint)range); _dw_jni_check_exception(env); @@ -2088,7 +2090,7 @@ 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"); + "(Landroid/view/View;I)V"); // Call the method on the object env->CallVoidMethod(_dw_obj, percentSetPos, handle, (jint)position); _dw_jni_check_exception(env);