changeset 2551:127779860ac1

Android: Implement DW_CLR_DEFAULT and some basic dark mode support.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sat, 15 May 2021 00:44:24 +0000
parents a8d90e2896bc
children 303f544d14fa
files android/DWindows.kt android/dw.cpp
diffstat 2 files changed, 89 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/android/DWindows.kt	Fri May 14 19:12:39 2021 +0000
+++ b/android/DWindows.kt	Sat May 15 00:44:24 2021 +0000
@@ -25,6 +25,7 @@
 import android.util.Base64
 import android.util.Log
 import android.util.SparseBooleanArray
+import android.util.TypedValue
 import android.view.*
 import android.view.View.OnTouchListener
 import android.view.inputmethod.EditorInfo
@@ -33,6 +34,7 @@
 import android.widget.*
 import android.widget.AdapterView.OnItemClickListener
 import android.widget.SeekBar.OnSeekBarChangeListener
+import androidx.annotation.RequiresApi
 import androidx.appcompat.app.AlertDialog
 import androidx.appcompat.app.AppCompatActivity
 import androidx.appcompat.widget.AppCompatEditText
@@ -462,6 +464,7 @@
     var threadLock = ReentrantLock()
     var threadCond = threadLock.newCondition()
     var notificationID: Int = 0
+    var darkMode: Int = -1
     private var paint = Paint()
     private var bgcolor: Int = 0
     private var menuBar: DWMenu? = null
@@ -510,6 +513,12 @@
     override fun onConfigurationChanged(newConfig: Configuration) {
         super.onConfigurationChanged(newConfig)
 
+        val currentNightMode = newConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK
+        when (currentNightMode) {
+            Configuration.UI_MODE_NIGHT_NO -> { darkMode = 0 } // Night mode is not active, we're using the light theme
+            Configuration.UI_MODE_NIGHT_YES -> { darkMode = 1 } // Night mode is active, we're using dark theme
+        }
+
         // Send a DW_SIGNAL_CONFIGURE on orientation change
         if(windowLayout != null) {
             var width: Int = windowLayout!!.width
@@ -537,6 +546,11 @@
         return super.onPrepareOptionsMenu(menu)
     }
 
+    fun darkModeDetected(): Int
+    {
+        return darkMode
+    }
+
     fun menuBarNew(location: View): DWMenu?
     {
         // TODO: Make sure location is this activity
@@ -752,21 +766,50 @@
         }
     }
 
-    fun windowSetColor(window: View, falpha: Int, fred: Int, fgreen: Int, fblue: Int,
-                       balpha: Int, bred: Int, bgreen: Int, bblue: Int) {
+    fun windowSetColor(window: View, fore: Int, falpha: Int, fred: Int, fgreen: Int, fblue: Int,
+                       back: Int, balpha: Int, bred: Int, bgreen: Int, bblue: Int) {
+        var colorfore: Int = Color.rgb(fred, fgreen, fblue)
+        var colorback: Int = Color.rgb(bred, bgreen, bblue)
+
+        // DW_CLR_DEFAULT on background sets it transparent...
+        // so the background drawable shows through
+        if(back == 16) {
+            colorback = Color.TRANSPARENT
+        }
 
         waitOnUiThread {
             if (window is TextView) {
                 var textview: TextView = window
-                textview.setTextColor(Color.rgb(fred, fgreen, fblue))
-                textview.setBackgroundColor(Color.rgb(bred, bgreen, bblue))
+
+                // Handle DW_CLR_DEFAULT
+                if(fore == 16) {
+                    val value = TypedValue()
+                    this.theme.resolveAttribute(R.attr.editTextColor, value, true)
+                    colorfore = value.data
+                }
+                textview.setTextColor(colorfore)
+                textview.setBackgroundColor(colorback)
             } else if (window is Button) {
                 var button: Button = window
-                button.setTextColor(Color.rgb(fred, fgreen, fblue))
-                button.setBackgroundColor(Color.rgb(bred, bgreen, bblue))
+
+                // Handle DW_CLR_DEFAULT
+                if(fore == 16) {
+                    val value = TypedValue()
+                    // colorButtonNormal requires API 21... use the editTextColor...
+                    // on older versions as a placeholder... this is probably wrong
+                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+                        this.theme.resolveAttribute(R.attr.colorButtonNormal, value, true)
+                    } else {
+                        this.theme.resolveAttribute(R.attr.editTextColor, value, true)
+                    }
+                    colorfore = value.data
+                }
+                button.setTextColor(colorfore)
+                button.setBackgroundColor(colorback)
             } else if(window is LinearLayout) {
                 var box: LinearLayout = window
-                box.setBackgroundColor(Color.rgb(bred, bgreen, bblue))
+
+                box.setBackgroundColor(colorback)
             }
         }
     }
--- a/android/dw.cpp	Fri May 14 19:12:39 2021 +0000
+++ b/android/dw.cpp	Sat May 15 00:44:24 2021 +0000
@@ -589,6 +589,23 @@
     return 0;
 }
 
+int _dw_dark_mode_detected()
+{
+    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 darkModeDetected = env->GetMethodID(clazz, "darkModeDetected",
+                                                      "()I");
+        // Call the method on the object
+        return env->CallIntMethod(_dw_obj, darkModeDetected);
+    }
+    return DW_ERROR_UNKNOWN;
+}
+
 /*
  * Runs a message loop for Dynamic Windows.
  */
@@ -4450,11 +4467,11 @@
         jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
         // Get the method that you want to call
         jmethodID windowSetColor = env->GetMethodID(clazz, "windowSetColor",
-                                                    "(Landroid/view/View;IIIIIIII)V");
+                                                    "(Landroid/view/View;IIIIIIIIII)V");
         // Call the method on the object
         env->CallVoidMethod(_dw_obj, windowSetColor, handle,
-                            0, (jint)DW_RED_VALUE(_fore), (jint)DW_GREEN_VALUE(_fore), (jint)DW_BLUE_VALUE(_fore),
-                            0, (jint)DW_RED_VALUE(_back), (jint)DW_GREEN_VALUE(_back), (jint)DW_BLUE_VALUE(_back));
+                            (jint)fore, 0, (jint)DW_RED_VALUE(_fore), (jint)DW_GREEN_VALUE(_fore), (jint)DW_BLUE_VALUE(_fore),
+                            (jint)back, 0, (jint)DW_RED_VALUE(_back), (jint)DW_GREEN_VALUE(_back), (jint)DW_BLUE_VALUE(_back));
         return DW_ERROR_NONE;
     }
     return DW_ERROR_GENERAL;
@@ -6428,12 +6445,19 @@
     {
         case DW_FEATURE_HTML:                    /* Supports the HTML Widget */
         case DW_FEATURE_HTML_RESULT:             /* Supports the DW_SIGNAL_HTML_RESULT callback */
-        case DW_FEATURE_DARK_MODE:               /* Supports Dark Mode user interface */
         case DW_FEATURE_NOTIFICATION:            /* Supports sending system notifications */
         case DW_FEATURE_UTF8_UNICODE:            /* Supports UTF8 encoded Unicode text */
         case DW_FEATURE_MLE_WORD_WRAP:           /* Supports word wrapping in Multi-line Edit boxes */
         case DW_FEATURE_CONTAINER_STRIPE:        /* Supports striped line display in container widgets */
             return DW_FEATURE_ENABLED;
+        case DW_FEATURE_DARK_MODE:               /* Supports Dark Mode user interface */
+        {
+            /* Dark Mode on Android requires Android 10 (API 29) */
+            if(_dw_android_api >= 29) {
+                return _dw_dark_mode_detected();
+            }
+            return DW_FEATURE_UNSUPPORTED;
+        }
         default:
             return DW_FEATURE_UNSUPPORTED;
     }
@@ -6459,13 +6483,23 @@
         /* These features are supported but not configurable */
         case DW_FEATURE_HTML:                    /* Supports the HTML Widget */
         case DW_FEATURE_HTML_RESULT:             /* Supports the DW_SIGNAL_HTML_RESULT callback */
-        case DW_FEATURE_DARK_MODE:               /* Supports Dark Mode user interface */
         case DW_FEATURE_NOTIFICATION:            /* Supports sending system notifications */
         case DW_FEATURE_UTF8_UNICODE:            /* Supports UTF8 encoded Unicode text */
         case DW_FEATURE_MLE_WORD_WRAP:           /* Supports word wrapping in Multi-line Edit boxes */
         case DW_FEATURE_CONTAINER_STRIPE:        /* Supports striped line display in container widgets */
             return DW_ERROR_GENERAL;
         /* These features are supported and configurable */
+        case DW_FEATURE_DARK_MODE:               /* Supports Dark Mode user interface */
+        {
+            /* Dark Mode on Android requires 10 (API 29) */
+            if(_dw_android_api >= 29) {
+                /* While technically configurable....
+                 * for now just return DW_ERROR_GENERAL
+                 */
+                return DW_ERROR_GENERAL;
+            }
+            return DW_FEATURE_UNSUPPORTED;
+        }
         default:
             return DW_FEATURE_UNSUPPORTED;
     }