# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1619758612 0 # Node ID 62e124eecd82d9a73f174d741392ee2be0de59ce # Parent 6c01b013281320338b6fdbcc25b9613727107bf3 Android: Implement timers and beep. Some general code cleanup. diff -r 6c01b0132813 -r 62e124eecd82 android/DWindows.kt --- a/android/DWindows.kt Fri Apr 30 02:33:21 2021 +0000 +++ b/android/DWindows.kt Fri Apr 30 04:56:52 2021 +0000 @@ -4,26 +4,27 @@ import android.content.ClipboardManager import android.content.DialogInterface import android.content.pm.ActivityInfo +import android.graphics.drawable.GradientDrawable +import android.media.AudioManager +import android.media.ToneGenerator import android.os.Bundle import android.os.Looper import android.text.method.PasswordTransformationMethod import android.util.Log -import android.view.* +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup import android.widget.* import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.collection.SimpleArrayMap -import androidx.core.content.res.TypedArrayUtils.getText -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentActivity -import androidx.fragment.app.FragmentManager -import androidx.fragment.app.FragmentStatePagerAdapter import androidx.recyclerview.widget.RecyclerView -import androidx.viewpager.widget.ViewPager -import androidx.viewpager2.adapter.FragmentStateAdapter import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator +import java.util.* + class TabViewPagerAdapter : RecyclerView.Adapter() { val eventList = listOf("0", "1", "2") @@ -127,12 +128,12 @@ { if(window is TextView) { - var textview: TextView = window as TextView + var textview: TextView = window textview.text = text } else if(window is Button) { - var button: Button = window as Button + var button: Button = window button.text = text } else if(window is LinearLayout) @@ -146,12 +147,12 @@ { if(window is TextView) { - var textview: TextView = window as TextView + var textview: TextView = window return textview.text.toString() } else if(window is Button) { - var button: Button = window as Button + var button: Button = window return button.text.toString() } else if(window is LinearLayout) @@ -195,6 +196,7 @@ } else { box.orientation = LinearLayout.HORIZONTAL } + box.setPadding(pad, pad, pad, pad) return box } @@ -288,7 +290,8 @@ entryfield.tag = dataArrayMap entryfield.id = cid - if(password > 0) { + if(password > 0) + { entryfield.transformationMethod = PasswordTransformationMethod.getInstance() } entryfield.setText(text) @@ -331,6 +334,17 @@ textview.tag = dataArrayMap textview.id = cid textview.text = text + if(status != 0) + { + val border = GradientDrawable() + + // Set a black border on white background... + // might need to change this to invisible... + // or the color from windowSetColor + border.setColor(-0x1) + border.setStroke(1, -0x1000000) + textview.background = border + } return textview } @@ -353,7 +367,37 @@ var params: RelativeLayout.LayoutParams = RelativeLayout.LayoutParams(w, h) tabs.layoutParams = params notebook.addView(tabs) - notebook.addView(pager) + if(top != 0) { + notebook.addView(pager, 0) + } else { + notebook.addView(pager) + } + } + + fun timerConnect(interval: Long, sigfunc: Long, data: Long): Timer + { + // creating timer task, timer + val t = Timer() + val tt: TimerTask = object : TimerTask() { + override fun run() { + if(eventHandlerTimer(sigfunc, data) == 0) { + t.cancel() + } + } + } + t.scheduleAtFixedRate(tt, interval, interval) + return t + } + + fun timerDisconnect(timer: Timer) + { + timer.cancel() + } + + fun doBeep(duration: Int) + { + val toneGen = ToneGenerator(AudioManager.STREAM_MUSIC, 100) + toneGen.startTone(ToneGenerator.TONE_CDMA_PIP, duration) } fun debugMessage(text: String) @@ -415,6 +459,7 @@ external fun dwindowsInit(dataDir: String): String external fun eventHandler(obj1: View, obj2: View?, message: Int, str1: String?, str2: String?, int1: Int, int2: Int, int3: Int, int4: Int): Int external fun eventHandlerSimple(obj1: View, message: Int) + external fun eventHandlerTimer(sigfunc: Long, data: Long): Int companion object { diff -r 6c01b0132813 -r 62e124eecd82 android/dw.cpp --- a/android/dw.cpp Fri Apr 30 02:33:21 2021 +0000 +++ b/android/dw.cpp Fri Apr 30 04:56:52 2021 +0000 @@ -361,6 +361,15 @@ _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) { + int (*timerfunc)(void *) = (int (* API)(void *))sigfunc; + + pthread_setspecific(_dw_env_key, env); + return timerfunc((void *)data); +} + /* This function adds a signal handler callback into the linked list. */ void _dw_new_signal(ULONG message, HWND window, int msgid, void *signalfunction, void *discfunc, void *data) @@ -3453,6 +3462,17 @@ */ void API dw_beep(int freq, int dur) { + 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 doBeep = env->GetMethodID(clazz, "doBeep", "(I)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, doBeep, dur); + } } /* Call this after drawing to the screen to make sure @@ -3526,7 +3546,23 @@ */ int API dw_timer_connect(int interval, void *sigfunc, void *data) { - return 0; + JNIEnv *env; + int retval = 0; + + if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + { + // Use a long paramater + jlong longinterval = (jlong)interval; + // 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 timerConnect = env->GetMethodID(clazz, "timerConnect", + "(JJJ)Ljava/util/Timer;"); + // Call the method on the object + retval = DW_POINTER_TO_INT(env->NewGlobalRef(env->CallObjectMethod(_dw_obj, + timerConnect, longinterval, (jlong)sigfunc, (jlong)data))); + } + return retval; } /* @@ -3536,6 +3572,20 @@ */ void API dw_timer_disconnect(int timerid) { + JNIEnv *env; + + if(timerid && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + { + // Use a long paramater + jobject timer = (jobject)timerid; + // 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 timerDisconnect = env->GetMethodID(clazz, "timerDisconnect", + "(Ljava/util/Timer;)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, timerDisconnect, timer); + } } /*