feat(Zinnia): refactor and add like, a bunch of stuff
- refactor: move colour utilities to APCAUtil, for sharing with settings preview - feat: speaking of which, a nice preview in settings!! featuring hsv bars for all your previewing needs - feat: changed apca threshold to 45, I found this to be nicer than 75 - feat: added transparency option, alongside "unchanged" colour option which pairs nicely together for a translucent glass effect
This commit is contained in:
parent
bc4aa09fff
commit
e0b86e0fb4
3 changed files with 271 additions and 121 deletions
|
|
@ -0,0 +1,105 @@
|
|||
package moe.lava.awoocord.zinnia
|
||||
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.widget.TextView
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import com.aliucord.utils.DimenUtils.dp
|
||||
import com.discord.stores.StoreStream
|
||||
import kotlin.math.abs
|
||||
|
||||
internal object APCAUtil {
|
||||
private val settings = ZinniaSettings
|
||||
|
||||
internal fun configureOn(view: TextView, colour: Int?) {
|
||||
when (settings.mode) {
|
||||
Mode.Block -> configureBlock(view, colour ?: Color.BLACK)
|
||||
Mode.RoleDot -> configureRoleDot(view, colour ?: Color.BLACK)
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureRoleDot(view: TextView, colour: Int) { }
|
||||
|
||||
private fun configureBlock(view: TextView, colourP: Int) {
|
||||
val isLight = StoreStream.getUserSettingsSystem().theme == "light"
|
||||
var colour = colourP
|
||||
val bcol = GradientDrawable()
|
||||
bcol.cornerRadius = 4.dp.toFloat()
|
||||
view.background = bcol
|
||||
|
||||
if (colour == Color.BLACK) {
|
||||
if (settings.blockAlsoDefault) {
|
||||
colour = if (isLight && !settings.blockInverted) Color.WHITE else Color.BLACK
|
||||
} else {
|
||||
view.background = null
|
||||
view.setPadding(0, 0, 0, 0)
|
||||
return
|
||||
}
|
||||
}
|
||||
view.setPadding(4.dp, 0, 4.dp, 0)
|
||||
|
||||
var (preferred, other) = if (isLight) {
|
||||
Color.WHITE to Color.BLACK
|
||||
} else {
|
||||
Color.BLACK to Color.WHITE
|
||||
}
|
||||
when (settings.blockMode) {
|
||||
BlockMode.InvertedThemeOnly -> preferred = other
|
||||
BlockMode.WhiteOnly -> preferred = Color.WHITE
|
||||
BlockMode.BlackOnly -> preferred = Color.BLACK
|
||||
BlockMode.Unchanged -> preferred = colourP
|
||||
else -> {}
|
||||
}
|
||||
|
||||
val colours = if (!settings.blockInverted) {
|
||||
Colours(
|
||||
fgP = preferred,
|
||||
fgO = other,
|
||||
bgP = colour,
|
||||
bgO = colour,
|
||||
)
|
||||
} else {
|
||||
Colours(
|
||||
fgP = colour,
|
||||
fgO = colour,
|
||||
bgP = preferred,
|
||||
bgO = other,
|
||||
)
|
||||
}
|
||||
|
||||
val usePreferred = when (settings.blockMode) {
|
||||
BlockMode.ApcaOnly -> isApca(colours)
|
||||
BlockMode.WcagOnly -> isWcag(colours)
|
||||
BlockMode.ApcaLightWcagDark -> if (isLight) isApca(colours) else isWcag(colours)
|
||||
BlockMode.WcagLightApcaDark -> if (isLight) isWcag(colours) else isApca(colours)
|
||||
BlockMode.ThemeOnly,
|
||||
BlockMode.InvertedThemeOnly,
|
||||
BlockMode.WhiteOnly,
|
||||
BlockMode.BlackOnly,
|
||||
BlockMode.Unchanged -> true
|
||||
}
|
||||
|
||||
if (usePreferred) {
|
||||
view.setTextColor(colours.fgP)
|
||||
bcol.setColor(ColorUtils.setAlphaComponent(colours.bgP, settings.alpha))
|
||||
bcol.alpha = settings.alpha
|
||||
} else {
|
||||
view.setTextColor(colours.fgO)
|
||||
bcol.setColor(ColorUtils.setAlphaComponent(colours.bgO, settings.alpha))
|
||||
bcol.alpha = settings.alpha
|
||||
}
|
||||
}
|
||||
|
||||
private fun isApca(c: Colours): Boolean {
|
||||
val cPref = abs(APCA.contrast(c.fgP, c.bgP))
|
||||
val cOth = abs(APCA.contrast(c.fgO, c.bgO))
|
||||
return cPref > settings.blockApcaThreshold || cPref > cOth
|
||||
}
|
||||
|
||||
private fun isWcag(c: Colours): Boolean {
|
||||
val cPref = ColorUtils.calculateContrast(c.fgP, c.bgP)
|
||||
val cOth = ColorUtils.calculateContrast(c.fgO, c.bgO)
|
||||
return cPref > settings.blockWcagThreshold || cPref > cOth
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,26 +1,24 @@
|
|||
package moe.lava.awoocord.zinnia
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import com.aliucord.annotations.AliucordPlugin
|
||||
import com.aliucord.entities.Plugin
|
||||
import com.aliucord.patcher.*
|
||||
import com.aliucord.patcher.after
|
||||
import com.aliucord.patcher.component1
|
||||
import com.aliucord.patcher.component2
|
||||
import com.aliucord.patcher.component3
|
||||
import com.aliucord.utils.DimenUtils.dp
|
||||
import com.aliucord.utils.ViewUtils.findViewById
|
||||
import com.aliucord.utils.accessField
|
||||
import com.discord.databinding.WidgetChannelMembersListItemUserBinding
|
||||
import com.discord.stores.StoreStream
|
||||
import com.discord.widgets.channels.memberlist.adapter.ChannelMembersListAdapter
|
||||
import com.discord.widgets.channels.memberlist.adapter.ChannelMembersListViewHolderMember
|
||||
import com.discord.widgets.chat.list.adapter.WidgetChatListAdapterItemMessage
|
||||
import com.discord.widgets.chat.list.entries.ChatListEntry
|
||||
import com.discord.widgets.chat.list.entries.MessageEntry
|
||||
import kotlin.math.abs
|
||||
|
||||
private val ChannelMembersListViewHolderMember.binding
|
||||
by accessField<WidgetChannelMembersListItemUserBinding>()
|
||||
|
|
@ -36,8 +34,6 @@ data class Colours(
|
|||
class Zinnia : Plugin() {
|
||||
companion object { const val NAME = "RoleBlocks" }
|
||||
|
||||
private val localSettings = ZinniaSettings
|
||||
|
||||
init {
|
||||
settingsTab = SettingsTab(ZinniaSettings.Page::class.java, SettingsTab.Type.PAGE)
|
||||
}
|
||||
|
|
@ -49,93 +45,6 @@ class Zinnia : Plugin() {
|
|||
|
||||
override fun stop(context: Context) { patcher.unpatchAll() }
|
||||
|
||||
private fun configureOn(view: TextView, colour: Int?) {
|
||||
when (localSettings.mode) {
|
||||
Mode.Block -> configureBlock(view, colour ?: Color.BLACK)
|
||||
Mode.RoleDot -> configureRoleDot(view, colour ?: Color.BLACK)
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureRoleDot(view: TextView, colour: Int) { }
|
||||
|
||||
private fun configureBlock(view: TextView, colourP: Int) {
|
||||
val isLight = StoreStream.getUserSettingsSystem().theme == "light"
|
||||
var colour = colourP
|
||||
val bcol = GradientDrawable()
|
||||
bcol.cornerRadius = 4.dp.toFloat()
|
||||
view.background = bcol
|
||||
|
||||
if (colour == Color.BLACK) {
|
||||
if (localSettings.blockAlsoDefault) {
|
||||
colour = if (isLight && !localSettings.blockInverted) Color.WHITE else Color.BLACK
|
||||
} else {
|
||||
view.background = null
|
||||
view.setPadding(0, 0, 0, 0)
|
||||
return
|
||||
}
|
||||
}
|
||||
view.setPadding(4.dp, 0, 4.dp, 0)
|
||||
|
||||
var (preferred, other) = if (isLight) {
|
||||
Color.WHITE to Color.BLACK
|
||||
} else {
|
||||
Color.BLACK to Color.WHITE
|
||||
}
|
||||
when (localSettings.blockMode) {
|
||||
BlockMode.InvertedThemeOnly -> preferred = other
|
||||
BlockMode.WhiteOnly -> preferred = Color.WHITE
|
||||
BlockMode.BlackOnly -> preferred = Color.BLACK
|
||||
else -> {}
|
||||
}
|
||||
|
||||
val colours = if (!localSettings.blockInverted) {
|
||||
Colours(
|
||||
fgP = preferred,
|
||||
fgO = other,
|
||||
bgP = colour,
|
||||
bgO = colour,
|
||||
)
|
||||
} else {
|
||||
Colours(
|
||||
fgP = colour,
|
||||
fgO = colour,
|
||||
bgP = preferred,
|
||||
bgO = other,
|
||||
)
|
||||
}
|
||||
|
||||
val usePreferred = when (localSettings.blockMode) {
|
||||
BlockMode.ApcaOnly -> isApca(colours)
|
||||
BlockMode.WcagOnly -> isWcag(colours)
|
||||
BlockMode.ApcaLightWcagDark -> if (isLight) isApca(colours) else isWcag(colours)
|
||||
BlockMode.WcagLightApcaDark -> if (isLight) isWcag(colours) else isApca(colours)
|
||||
BlockMode.ThemeOnly,
|
||||
BlockMode.InvertedThemeOnly,
|
||||
BlockMode.WhiteOnly,
|
||||
BlockMode.BlackOnly -> true
|
||||
}
|
||||
|
||||
if (usePreferred) {
|
||||
view.setTextColor(colours.fgP)
|
||||
bcol.setColor(colours.bgP)
|
||||
} else {
|
||||
view.setTextColor(colours.fgO)
|
||||
bcol.setColor(colours.bgO)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isApca(c: Colours): Boolean {
|
||||
val cPref = abs(APCA.contrast(c.fgP, c.bgP))
|
||||
val cOth = abs(APCA.contrast(c.fgO, c.bgO))
|
||||
return cPref > localSettings.blockApcaThreshold || cPref > cOth
|
||||
}
|
||||
|
||||
private fun isWcag(c: Colours): Boolean {
|
||||
val cPref = ColorUtils.calculateContrast(c.fgP, c.bgP)
|
||||
val cOth = ColorUtils.calculateContrast(c.fgO, c.bgO)
|
||||
return cPref > localSettings.blockWcagThreshold || cPref > cOth
|
||||
}
|
||||
|
||||
private fun patchMemberList() {
|
||||
// Patches the method that configures the username in members list
|
||||
patcher.after<ChannelMembersListViewHolderMember>(
|
||||
|
|
@ -153,7 +62,7 @@ class Zinnia : Plugin() {
|
|||
}
|
||||
}
|
||||
|
||||
configureOn(usernameTextView, member.color)
|
||||
APCAUtil.configureOn(usernameTextView, member.color)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -166,7 +75,7 @@ class Zinnia : Plugin() {
|
|||
) { (_, _: Int, entry: MessageEntry) ->
|
||||
val username = itemView.findViewById<TextView?>("chat_list_adapter_item_text_name")
|
||||
?: return@after
|
||||
configureOn(username, entry.author?.color)
|
||||
APCAUtil.configureOn(username, entry.author?.color)
|
||||
}
|
||||
|
||||
// Configures for reply preview username
|
||||
|
|
@ -177,7 +86,7 @@ class Zinnia : Plugin() {
|
|||
val referencedAuthor = entry.replyData?.messageEntry?.author
|
||||
val replyUsername = itemView.findViewById<TextView?>("chat_list_adapter_item_text_decorator_reply_name")
|
||||
?: return@after
|
||||
configureOn(replyUsername, referencedAuthor?.color)
|
||||
APCAUtil.configureOn(replyUsername, referencedAuthor?.color)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,26 @@
|
|||
package moe.lava.awoocord.zinnia
|
||||
|
||||
import android.graphics.Color
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.SeekBar
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import com.aliucord.Constants
|
||||
import com.aliucord.Utils
|
||||
import com.aliucord.api.SettingsAPI
|
||||
import com.aliucord.fragments.SettingsPage
|
||||
import com.aliucord.settings.delegate
|
||||
import com.aliucord.utils.DimenUtils.dp
|
||||
import com.aliucord.wrappers.users.globalName
|
||||
import com.discord.stores.StoreStream
|
||||
import com.discord.utilities.color.ColorCompat
|
||||
import com.discord.views.CheckedSetting
|
||||
import com.discord.views.RadioManager
|
||||
import com.lytefast.flexinput.R
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
|
|
@ -25,6 +38,7 @@ enum class BlockMode {
|
|||
InvertedThemeOnly,
|
||||
WhiteOnly,
|
||||
BlackOnly,
|
||||
Unchanged,
|
||||
}
|
||||
|
||||
class SettingsDelegateEnum<T : Enum<T>>(
|
||||
|
|
@ -49,18 +63,47 @@ private inline fun <T : View> T.addTo(parent: ViewGroup, block: T.() -> Unit = {
|
|||
parent.addView(this)
|
||||
}
|
||||
|
||||
private typealias Delegate<Type> = ReadWriteProperty<Any, Type>
|
||||
|
||||
fun <T> basicDelegate(initial: T) = object : Delegate<T> {
|
||||
private var current = initial
|
||||
override fun getValue(self: Any?, prop: KProperty<*>): T = current
|
||||
override fun setValue(self: Any?, prop: KProperty<*>, value: T) { current = value }
|
||||
}
|
||||
|
||||
private class StateDelegate<T>(
|
||||
private val inner: Delegate<T>,
|
||||
private val update: (T) -> Unit,
|
||||
) : Delegate<T> {
|
||||
override fun getValue(self: Any?, prop: KProperty<*>): T = inner.getValue(self, prop)
|
||||
|
||||
override fun setValue(self: Any?, prop: KProperty<*>, value: T) {
|
||||
inner.setValue(self, prop, value)
|
||||
update(value)
|
||||
}
|
||||
}
|
||||
|
||||
object ZinniaSettings {
|
||||
private val api = SettingsAPI(Zinnia.NAME)
|
||||
|
||||
var mode by api.delegateEnum(Mode.Block)
|
||||
private var onStateUpdate = {}
|
||||
|
||||
var dotKeepNameColour by api.delegate(false)
|
||||
private inline fun <T> reactive(backing: () -> Delegate<T>): StateDelegate<T> {
|
||||
return StateDelegate(backing()) { onStateUpdate() }
|
||||
}
|
||||
|
||||
var blockAlsoDefault by api.delegate(true)
|
||||
var blockInverted by api.delegate(false)
|
||||
var blockMode by api.delegateEnum(BlockMode.ApcaLightWcagDark)
|
||||
var blockApcaThreshold by api.delegate(75.0)
|
||||
var blockWcagThreshold by api.delegate(4.5)
|
||||
var mode by reactive { api.delegateEnum(Mode.Block) }
|
||||
|
||||
var dotKeepNameColour by reactive { api.delegate(false) }
|
||||
|
||||
var blockAlsoDefault by reactive { api.delegate(true) }
|
||||
var blockInverted by reactive { api.delegate(false) }
|
||||
var blockMode by reactive { api.delegateEnum(BlockMode.ApcaLightWcagDark) }
|
||||
var blockApcaThreshold by reactive { api.delegate(45.0f) }
|
||||
var blockWcagThreshold by reactive { api.delegate(4.5f) }
|
||||
|
||||
private val _alpha = reactive { api.delegate("alpha", 255) }
|
||||
var alpha by _alpha
|
||||
|
||||
class Page : SettingsPage() {
|
||||
private lateinit var manager: RadioManager
|
||||
|
|
@ -69,6 +112,13 @@ object ZinniaSettings {
|
|||
|
||||
private val checks = mutableListOf<CheckedSetting>()
|
||||
|
||||
private val _previewH = reactive { basicDelegate(0) }
|
||||
private var previewH by _previewH
|
||||
private val _previewS = reactive { basicDelegate(100) }
|
||||
private var previewS by _previewS
|
||||
private val _previewV = reactive { basicDelegate(100) }
|
||||
private var previewV by _previewV
|
||||
|
||||
private fun createRadio(newMode: BlockMode, text: String, subtext: String? = null): CheckedSetting {
|
||||
return Utils.createCheckedSetting(requireContext(), CheckedSetting.ViewType.RADIO, text, subtext).addTo(linearLayout) {
|
||||
isChecked = blockMode == newMode
|
||||
|
|
@ -81,6 +131,60 @@ object ZinniaSettings {
|
|||
}
|
||||
}
|
||||
|
||||
private fun createSlider(
|
||||
min: Int,
|
||||
max: Int,
|
||||
initial: Int = min,
|
||||
onChange: (value: Int, commit: Boolean) -> String
|
||||
): LinearLayout {
|
||||
var pendingValue = initial
|
||||
return LinearLayout(requireContext(), null, 0, R.i.UiKit_Settings_Item).addTo(linearLayout) {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
val display = TextView(context, null, 0, R.i.UiKit_TextView).addTo(this) {
|
||||
textSize = 16.0f
|
||||
typeface = ResourcesCompat.getFont(context, Constants.Fonts.whitney_medium)
|
||||
text = onChange(initial, false)
|
||||
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
|
||||
bottomMargin = 4.dp
|
||||
}
|
||||
}
|
||||
SeekBar(context, null, 0, R.i.UiKit_SeekBar).addTo(this) {
|
||||
this.max = max - min
|
||||
progress = initial
|
||||
setPadding(12.dp, 0, 12.dp, 0)
|
||||
setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
|
||||
override fun onProgressChanged(
|
||||
seekBar: SeekBar,
|
||||
progress: Int,
|
||||
fromUser: Boolean,
|
||||
) {
|
||||
pendingValue = min + progress
|
||||
display.text = onChange(pendingValue, false)
|
||||
}
|
||||
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar) {}
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
||||
onChange(pendingValue, true)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSlider(binding: Delegate<Int>, min: Int, max: Int, immediate: Boolean = false, label: (Int) -> String): LinearLayout {
|
||||
var value by binding
|
||||
return createSlider(min, max, value) { newValue, commit ->
|
||||
@Suppress("AssignedValueIsNeverRead") // kt so dumb
|
||||
if (immediate || commit) value = newValue
|
||||
label(newValue)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
onStateUpdate = {}
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onViewBound(view: View) {
|
||||
super.onViewBound(view)
|
||||
setActionBarTitle(Zinnia.NAME)
|
||||
|
|
@ -92,11 +196,12 @@ object ZinniaSettings {
|
|||
val roleDotSettings = mutableListOf<CheckedSetting>()
|
||||
|
||||
addHeader(ctx, "Text colour")
|
||||
createRadio(BlockMode.ApcaLightWcagDark, "Automatic", "Adjusts text colour based on role colour")
|
||||
createRadio(BlockMode.ThemeOnly, "By theme", "Adjusts text colour based on theme")
|
||||
createRadio(BlockMode.ApcaLightWcagDark, "Automatic", "Adjusts text colour based on optimal contrast with role colour")
|
||||
createRadio(BlockMode.ThemeOnly, "By theme", "Adjusts text colour based on system theme (dark/light)")
|
||||
createRadio(BlockMode.InvertedThemeOnly, "By theme (inverted)", "Same as above, but inverted")
|
||||
createRadio(BlockMode.WhiteOnly, "White", "Force text colour to be white")
|
||||
createRadio(BlockMode.BlackOnly, "Black", "Force text colour to be black")
|
||||
createRadio(BlockMode.Unchanged, "Unchanged", "Keep text colour; ideal for using with a translucent block")
|
||||
|
||||
/*
|
||||
addHeader(ctx, "Mode")
|
||||
|
|
@ -129,24 +234,12 @@ object ZinniaSettings {
|
|||
*/
|
||||
|
||||
addHeader(ctx, "Block Settings")
|
||||
Utils.createCheckedSetting(
|
||||
ctx,
|
||||
CheckedSetting.ViewType.SWITCH,
|
||||
"Also block up default colours",
|
||||
"Blocks up usernames that have no role colour",
|
||||
).addTo(this) {
|
||||
isChecked = blockAlsoDefault
|
||||
setOnCheckedListener {
|
||||
blockAlsoDefault = !blockAlsoDefault
|
||||
}
|
||||
blockSettings.add(this)
|
||||
}
|
||||
|
||||
Utils.createCheckedSetting(
|
||||
val invertSwitch = Utils.createCheckedSetting(
|
||||
ctx,
|
||||
CheckedSetting.ViewType.SWITCH,
|
||||
"Invert block colours",
|
||||
"By default, the role colour is applied as the block background. Turning this setting on instead makes the block black or white, and the text stays coloured.",
|
||||
"By default, the role colour is applied as the block background. Turning this setting on inverts this.\nHas no effect with \"Unchanged\" colour option",
|
||||
).addTo(this) {
|
||||
isChecked = blockInverted
|
||||
setOnCheckedListener {
|
||||
|
|
@ -154,7 +247,50 @@ object ZinniaSettings {
|
|||
}
|
||||
blockSettings.add(this)
|
||||
}
|
||||
}
|
||||
|
||||
createSlider(_alpha, 0, 255, true) { "Alpha: ${(it / 2.55f).roundToInt()}%" }
|
||||
|
||||
// createSlider(0, 255, blockApcaThreshold.roundToInt()) { value, commit ->
|
||||
// blockApcaThreshold = value.toFloat()
|
||||
// "Apca Threshold: $value"
|
||||
// }
|
||||
|
||||
addHeader(ctx, "Preview")
|
||||
val preview = TextView(ctx, null, 0, R.i.UiKit_TextView_Large_SingleLine).addTo(this) {
|
||||
val me = StoreStream.getUsers().me
|
||||
text = me.globalName ?: me.username
|
||||
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
|
||||
marginStart = 16.dp
|
||||
marginEnd = 16.dp
|
||||
}
|
||||
}
|
||||
|
||||
val hsv = floatArrayOf(0f, 0f, 0f)
|
||||
Color.colorToHSV(ColorCompat.getThemedColor(this, R.b.color_brand), hsv)
|
||||
previewH = hsv[0].roundToInt()
|
||||
previewS = (hsv[1] * 100).roundToInt()
|
||||
previewV = (hsv[2] * 100).roundToInt()
|
||||
createSlider(_previewH, 0, 360, true) { "Hue: $it" }
|
||||
createSlider(_previewS, 0, 100, true) { "Saturation: $it%" }
|
||||
createSlider(_previewV, 0, 100, true) { "Value: $it%" }
|
||||
|
||||
onStateUpdate = {
|
||||
updatePreview(preview)
|
||||
if (blockMode != BlockMode.Unchanged) {
|
||||
invertSwitch.l.b().isClickable = true
|
||||
invertSwitch.alpha = 1f
|
||||
} else {
|
||||
invertSwitch.l.b().isClickable = false
|
||||
invertSwitch.alpha = 0.3f
|
||||
}
|
||||
}
|
||||
onStateUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
fun updatePreview(preview: TextView) {
|
||||
val colour = Color.HSVToColor(floatArrayOf(previewH.toFloat(), previewS / 100f, previewV / 100f))
|
||||
APCAUtil.configureOn(preview, colour)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue