Browse Source

Color grid selection updates ARGB page. Action button colors match selected color unless it is too light. Part of #1665."

Aidan Follestad 6 years ago
parent
commit
ac160141d0

+ 7 - 4
color/src/main/java/com/afollestad/materialdialogs/color/ColorGridAdapter.kt

@@ -80,7 +80,7 @@ internal class ColorGridAdapter(
       selectedSubIndex = index
       notifyItemChanged(previousSelection)
       notifyItemChanged(selectedSubIndex)
-      invokeCallback()
+      onColorSelected()
       return
     }
 
@@ -100,7 +100,7 @@ internal class ColorGridAdapter(
       }
     }
 
-    invokeCallback()
+    onColorSelected()
     notifyDataSetChanged()
   }
 
@@ -189,10 +189,13 @@ internal class ColorGridAdapter(
     )
   }
 
-  private fun invokeCallback() {
+  private fun onColorSelected() {
+    val selectedColor = selectedColor() ?: 0
     val actualWaitForPositive = waitForPositiveButton && dialog.hasActionButtons()
     if (!actualWaitForPositive) {
-      callback?.invoke(dialog, selectedColor() ?: 0)
+      callback?.invoke(dialog, selectedColor)
     }
+    dialog.updateActionButtonsColor(selectedColor)
+    dialog.setArgbColor(selectedColor)
   }
 }

+ 51 - 10
color/src/main/java/com/afollestad/materialdialogs/color/DialogColorChooserExt.kt

@@ -5,6 +5,7 @@
  */
 package com.afollestad.materialdialogs.color
 
+import android.R.attr
 import android.annotation.SuppressLint
 import android.content.Context.INPUT_METHOD_SERVICE
 import android.graphics.Color
@@ -18,31 +19,34 @@ import android.graphics.Color.green
 import android.graphics.Color.red
 import android.graphics.PorterDuff.Mode.SRC_IN
 import android.view.View
+import android.view.inputmethod.InputMethodManager
 import android.widget.EditText
 import android.widget.SeekBar
 import android.widget.TextView
 import androidx.annotation.CheckResult
 import androidx.annotation.ColorInt
+import androidx.annotation.IntRange
 import androidx.recyclerview.widget.GridLayoutManager
 import androidx.recyclerview.widget.RecyclerView
 import androidx.viewpager.widget.ViewPager
 import com.afollestad.materialdialogs.MaterialDialog
+import com.afollestad.materialdialogs.WhichButton.NEGATIVE
 import com.afollestad.materialdialogs.WhichButton.POSITIVE
+import com.afollestad.materialdialogs.actions.getActionButton
 import com.afollestad.materialdialogs.actions.setActionButtonEnabled
-import com.afollestad.materialdialogs.customview.customView
-import com.afollestad.materialdialogs.customview.getCustomView
-import com.afollestad.viewpagerdots.DotsIndicator
-import android.view.inputmethod.InputMethodManager
-import androidx.annotation.IntRange
-import com.afollestad.materialdialogs.color.utils.clearTopMargin
 import com.afollestad.materialdialogs.color.utils.below
 import com.afollestad.materialdialogs.color.utils.changeHeight
+import com.afollestad.materialdialogs.color.utils.clearTopMargin
 import com.afollestad.materialdialogs.color.utils.onPageSelected
 import com.afollestad.materialdialogs.color.utils.progressChanged
+import com.afollestad.materialdialogs.customview.customView
+import com.afollestad.materialdialogs.customview.getCustomView
 import com.afollestad.materialdialogs.internal.list.DialogRecyclerView
+import com.afollestad.materialdialogs.utils.MDUtil.isColorDark
 import com.afollestad.materialdialogs.utils.MDUtil.isLandscape
 import com.afollestad.materialdialogs.utils.MDUtil.resolveColor
 import com.afollestad.materialdialogs.utils.invalidateDividers
+import com.afollestad.viewpagerdots.DotsIndicator
 
 typealias ColorCallback = ((dialog: MaterialDialog, color: Int) -> Unit)?
 
@@ -89,7 +93,7 @@ fun MaterialDialog.colorChooser(
     viewPager.adapter = ColorPagerAdapter()
     viewPager.onPageSelected { pageIndex ->
       setActionButtonEnabled(POSITIVE, selectedColor(allowCustomArgb) != null)
-      val hexValueView = getPageCustomView().findViewById<EditText>(R.id.hexValueView)
+      val hexValueView = getPageCustomView()!!.findViewById<EditText>(R.id.hexValueView)
 
       if (pageIndex == 0) {
         getCustomView()
@@ -135,6 +139,25 @@ fun MaterialDialog.colorChooser(
   return this
 }
 
+/**
+ * Updates the color displayed in the ARGB page of a color chooser dialog.
+ */
+fun MaterialDialog.setArgbColor(@ColorInt color: Int) {
+  val customPage = getPageCustomView() ?: return
+  val previewFrame =
+    customPage.findViewById<PreviewFrameView>(R.id.preview_frame)
+  previewFrame.setColor(color)
+
+  customPage.findViewById<SeekBar>(R.id.alpha_seeker)
+      .progress = Color.alpha(color)
+  customPage.findViewById<SeekBar>(R.id.red_seeker)
+      .progress = Color.red(color)
+  customPage.findViewById<SeekBar>(R.id.green_seeker)
+      .progress = Color.green(color)
+  customPage.findViewById<SeekBar>(R.id.blue_seeker)
+      .progress = Color.blue(color)
+}
+
 private fun MaterialDialog.updateGridLayout(
   colors: IntArray,
   subColors: Array<IntArray>?,
@@ -171,7 +194,7 @@ private fun MaterialDialog.updateCustomPage(
   waitForPositiveButton: Boolean,
   selection: ColorCallback
 ) {
-  val customPage = getPageCustomView()
+  val customPage = getPageCustomView()!!
   val previewFrame = customPage.findViewById<PreviewFrameView>(R.id.preview_frame)
   val alphaLabel = customPage.findViewById<TextView>(R.id.alpha_label)
   val alphaSeeker = customPage.findViewById<SeekBar>(R.id.alpha_seeker)
@@ -313,13 +336,14 @@ private fun MaterialDialog.onCustomValueChanged(
   if (!waitForPositiveButton && valueChanged) {
     selection?.invoke(this, color)
   }
+  updateActionButtonsColor(color)
 }
 
 private fun MaterialDialog.selectedColor(allowCustomColor: Boolean): Int? {
   if (allowCustomColor) {
     val viewPager = getPager()
     if (viewPager.currentItem == 1) {
-      return getPageCustomView().tag as? Int
+      return getPageCustomView()?.tag as? Int
     }
   }
   return (getPageGridView().adapter as ColorGridAdapter).selectedColor()
@@ -327,7 +351,7 @@ private fun MaterialDialog.selectedColor(allowCustomColor: Boolean): Int? {
 
 private fun MaterialDialog.getPageGridView() = findViewById<RecyclerView>(R.id.colorPresetGrid)
 
-private fun MaterialDialog.getPageCustomView() = findViewById<View>(R.id.colorArgbPage)
+private fun MaterialDialog.getPageCustomView() = findViewById<View?>(R.id.colorArgbPage)
 
 private fun MaterialDialog.getPager() = findViewById<ViewPager>(R.id.colorChooserPager)
 
@@ -335,6 +359,23 @@ internal fun MaterialDialog.setPage(@IntRange(from = 0, to = 1) index: Int) {
   getPager().setCurrentItem(index, true)
 }
 
+internal fun MaterialDialog.updateActionButtonsColor(@ColorInt color: Int) {
+  val adjustedColor = Color.rgb(Color.red(color), Color.green(color), Color.blue(color))
+  val isAdjustedDark = adjustedColor.isColorDark(0.25)
+  val isPrimaryDark =
+    resolveColor(context = context, attr = attr.textColorPrimary).isColorDark()
+
+  val finalColor = if (isPrimaryDark && !isAdjustedDark) {
+    resolveColor(context = context, attr = attr.textColorPrimary)
+  } else if (!isPrimaryDark && isAdjustedDark) {
+    resolveColor(context = context, attr = attr.textColorPrimaryInverse)
+  } else {
+    adjustedColor
+  }
+  getActionButton(POSITIVE).updateTextColor(finalColor)
+  getActionButton(NEGATIVE).updateTextColor(finalColor)
+}
+
 private fun MaterialDialog.getPageIndicator() =
   findViewById<DotsIndicator?>(R.id.colorChooserPagerDots)
 

+ 1 - 2
core/src/main/java/com/afollestad/materialdialogs/actions/DialogActionExt.kt

@@ -5,7 +5,6 @@
  */
 package com.afollestad.materialdialogs.actions
 
-import androidx.appcompat.widget.AppCompatButton
 import com.afollestad.materialdialogs.MaterialDialog
 import com.afollestad.materialdialogs.WhichButton
 
@@ -14,7 +13,7 @@ fun MaterialDialog.hasActionButtons() = view.buttonsLayout.visibleButtons.isNotE
 
 /** Returns the underlying view for an action button in the dialog. */
 fun MaterialDialog.getActionButton(which: WhichButton) =
-  view.buttonsLayout.actionButtons[which.index] as AppCompatButton
+  view.buttonsLayout.actionButtons[which.index]
 
 /** Enables or disables an action button. */
 fun MaterialDialog.setActionButtonEnabled(

+ 8 - 2
core/src/main/java/com/afollestad/materialdialogs/internal/button/DialogActionButton.kt

@@ -8,6 +8,7 @@ package com.afollestad.materialdialogs.internal.button
 import android.content.Context
 import android.util.AttributeSet
 import android.view.Gravity.CENTER
+import androidx.annotation.ColorInt
 import androidx.appcompat.widget.AppCompatButton
 import com.afollestad.materialdialogs.R
 import com.afollestad.materialdialogs.R.attr
@@ -25,7 +26,7 @@ import com.afollestad.materialdialogs.utils.updatePadding
  *
  * @author Aidan Follestad (afollestad)
  */
-internal class DialogActionButton(
+class DialogActionButton(
   context: Context,
   attrs: AttributeSet? = null
 ) : AppCompatButton(context, attrs) {
@@ -41,7 +42,7 @@ internal class DialogActionButton(
     isFocusable = true
   }
 
-  fun update(
+  internal fun update(
     baseContext: Context,
     appContext: Context,
     stacked: Boolean
@@ -71,6 +72,11 @@ internal class DialogActionButton(
     isEnabled = isEnabled
   }
 
+  fun updateTextColor(@ColorInt color: Int) {
+    enabledColor = color
+    isEnabled = isEnabled
+  }
+
   override fun setEnabled(enabled: Boolean) {
     super.setEnabled(enabled)
     setTextColor(if (enabled) enabledColor else disabledColor)

+ 2 - 2
core/src/main/java/com/afollestad/materialdialogs/utils/MDUtil.kt

@@ -98,13 +98,13 @@ object MDUtil {
     return ContextCompat.getColor(context, res ?: 0)
   }
 
-  @RestrictTo(LIBRARY_GROUP) fun Int.isColorDark(): Boolean {
+  @RestrictTo(LIBRARY_GROUP) fun Int.isColorDark(threshold: Double = 0.5): Boolean {
     if (this == Color.TRANSPARENT) {
       return false
     }
     val darkness =
       1 - (0.299 * Color.red(this) + 0.587 * Color.green(this) + 0.114 * Color.blue(this)) / 255
-    return darkness >= 0.5
+    return darkness >= threshold
   }
 
   @RestrictTo(LIBRARY_GROUP) fun <T : View> T.dimenPx(@DimenRes res: Int): Int {