SubwayTooter-Android-App/app/src/main/java/jp/juggler/subwaytooter/actmain/ActMainStyle.kt

275 lines
9.9 KiB
Kotlin

package jp.juggler.subwaytooter.actmain
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Typeface
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import jp.juggler.subwaytooter.ActMain
import jp.juggler.subwaytooter.R
import jp.juggler.subwaytooter.api.entity.TootStatus
import jp.juggler.subwaytooter.itemviewholder.ItemViewHolder
import jp.juggler.subwaytooter.pref.PrefB
import jp.juggler.subwaytooter.pref.PrefF
import jp.juggler.subwaytooter.pref.PrefI
import jp.juggler.subwaytooter.pref.PrefS
import jp.juggler.subwaytooter.pref.impl.StringPref
import jp.juggler.subwaytooter.span.MyClickableSpan
import jp.juggler.subwaytooter.stylerBoostAlpha
import jp.juggler.subwaytooter.stylerRoundRatio
import jp.juggler.subwaytooter.util.CustomShare
import jp.juggler.subwaytooter.view.ListDivider
import jp.juggler.util.data.clip
import jp.juggler.util.data.notEmpty
import jp.juggler.util.data.notZero
import jp.juggler.util.log.LogCategory
import jp.juggler.util.ui.attrColor
import jp.juggler.util.ui.getAdaptiveRippleDrawableRound
import org.jetbrains.anko.backgroundDrawable
import java.util.*
import kotlin.math.max
private val log = LogCategory("ActMainStyle")
private fun Float.dpToPx(context: Context) =
(this * context.resources.displayMetrics.density + 0.5f).toInt()
// initUIから呼ばれる
fun reloadFonts() {
ActMain.timelineFont = PrefS.spTimelineFont.value.notEmpty()?.let {
try {
Typeface.createFromFile(it)
} catch (ex: Throwable) {
log.e(ex, "timelineFont load failed")
null
}
} ?: Typeface.DEFAULT
ActMain.timelineFontBold = PrefS.spTimelineFontBold.value.notEmpty()?.let {
try {
Typeface.createFromFile(it)
} catch (ex: Throwable) {
log.e(ex, "timelineFontBold load failed")
null
}
} ?: try {
Typeface.create(ActMain.timelineFont, Typeface.BOLD)
} catch (ex: Throwable) {
log.e(ex, "timelineFontBold create from timelineFont failed")
null
} ?: Typeface.DEFAULT_BOLD
}
private fun ActMain.parseIconSize(stringPref: StringPref, minDp: Float = 1f) =
(try {
stringPref.value
.toFloatOrNull()
?.takeIf { it.isFinite() && it >= minDp }
} catch (ex: Throwable) {
log.e(ex, "parseIconSize failed.")
null
} ?: stringPref.defVal.toFloat()).dpToPx(this)
// initUIから呼ばれる
fun ActMain.reloadIconSize() {
avatarIconSize = parseIconSize(PrefS.spAvatarIconSize)
notificationTlIconSize = parseIconSize(PrefS.spNotificationTlIconSize)
ActMain.boostButtonSize = parseIconSize(PrefS.spBoostButtonSize)
ActMain.replyIconSize = parseIconSize(PrefS.spReplyIconSize)
ActMain.headerIconSize = parseIconSize(PrefS.spHeaderIconSize)
ActMain.stripIconSize = parseIconSize(PrefS.spStripIconSize)
ActMain.screenBottomPadding = parseIconSize(PrefS.spScreenBottomPadding, minDp = 0f)
ActMain.eventFadeAlpha = PrefS.spEventTextAlpha.value
.toFloatOrNull()
?.takeIf { it.isFinite() }
?.clip(0f, 1f)
?: 1f
}
// initUIから呼ばれる
fun reloadRoundRatio() {
val sizeDp = when {
PrefB.bpDontRound.value -> 0f
else -> PrefS.spRoundRatio.value
.toFloatOrNull()
?.takeIf { it.isFinite() }
?: 33f
}
stylerRoundRatio = (sizeDp / 100f).clip(0f, 1f) * 0.5f
}
// initUI から呼ばれる
fun reloadBoostAlpha() {
stylerBoostAlpha = PrefS.spBoostAlpha.value
.toIntOrNull()
?.toFloat()
?.let { (it + 0.5f) / 100f }
?.takeIf { it > 0f && it < 1f }
?: 1f
}
fun ActMain.reloadMediaHeight() {
appState.mediaThumbHeight = (
PrefS.spMediaThumbHeight.value
.toFloatOrNull()
?.takeIf { it >= 32f }
?: 64f
).dpToPx(this)
}
private fun Float.clipFontSize(): Float =
if (isNaN()) this else max(1f, this)
fun ActMain.reloadTextSize() {
timelineFontSizeSp = PrefF.fpTimelineFontSize.value.clipFontSize()
acctFontSizeSp = PrefF.fpAcctFontSize.value.clipFontSize()
notificationTlFontSizeSp = PrefF.fpNotificationTlFontSize.value.clipFontSize()
headerTextSizeSp = PrefF.fpHeaderTextSize.value.clipFontSize()
val fv = PrefS.spTimelineSpacing.value.toFloatOrNull()
timelineSpacing = if (fv != null && fv.isFinite() && fv != 0f) fv else null
}
fun ActMain.loadColumnMin() =
(PrefS.spColumnWidth.value
.toFloatOrNull()
?.takeIf { it.isFinite() && it >= 100f }
?: ActMain.COLUMN_WIDTH_MIN_DP.toFloat()
).dpToPx(this)
fun ActMain.justifyWindowContentPortrait() {
when (PrefI.ipJustifyWindowContentPortrait.value) {
PrefI.JWCP_START -> {
val iconW = (ActMain.stripIconSize * 1.5f + 0.5f).toInt()
val padding = resources.displayMetrics.widthPixels / 2 - iconW
fun ViewGroup.addViewBeforeLast(v: View) = addView(v, childCount - 1)
(svColumnStrip.parent as LinearLayout).addViewBeforeLast(
View(this).apply {
layoutParams = LinearLayout.LayoutParams(padding, 0)
}
)
llQuickPostBar.addViewBeforeLast(
View(this).apply {
layoutParams = LinearLayout.LayoutParams(padding, 0)
}
)
}
PrefI.JWCP_END -> {
val iconW = (ActMain.stripIconSize * 1.5f + 0.5f).toInt()
val borderWidth = 1f.dpToPx(this)
val padding = resources.displayMetrics.widthPixels / 2 - iconW - borderWidth
fun ViewGroup.addViewAfterFirst(v: View) = addView(v, 1)
(svColumnStrip.parent as LinearLayout).addViewAfterFirst(
View(this).apply {
layoutParams = LinearLayout.LayoutParams(padding, 0)
}
)
llQuickPostBar.addViewAfterFirst(
View(this).apply {
layoutParams = LinearLayout.LayoutParams(padding, 0)
}
)
}
}
}
//////////////////////////////////////////////////////
// onStart時に呼ばれる
fun reloadTimeZone() {
try {
var tz = TimeZone.getDefault()
val tzId = PrefS.spTimeZone.value
if (tzId.isNotEmpty()) {
tz = TimeZone.getTimeZone(tzId)
}
log.w("reloadTimeZone: tz=${tz.displayName}")
TootStatus.dateFormatFull.timeZone = tz
} catch (ex: Throwable) {
log.e(ex, "getTimeZone failed.")
}
}
// onStart時に呼ばれる
// カラーカスタマイズを読み直す
fun ActMain.reloadColors() {
ListDivider.color = PrefI.ipListDividerColor.value
TabletColumnDivider.color = PrefI.ipListDividerColor.value
ItemViewHolder.toot_color_unlisted = PrefI.ipTootColorUnlisted.value
ItemViewHolder.toot_color_follower = PrefI.ipTootColorFollower.value
ItemViewHolder.toot_color_direct_user = PrefI.ipTootColorDirectUser.value
ItemViewHolder.toot_color_direct_me = PrefI.ipTootColorDirectMe.value
MyClickableSpan.showLinkUnderline = PrefB.bpShowLinkUnderline.value
MyClickableSpan.defaultLinkColor = PrefI.ipLinkColor.value.notZero()
?: attrColor(R.attr.colorLink)
CustomShare.reloadCache(this)
}
fun ActMain.showFooterColor() {
val footerButtonBgColor = PrefI.ipFooterButtonBgColor.value
val footerButtonFgColor = PrefI.ipFooterButtonFgColor.value
val footerTabBgColor = PrefI.ipFooterTabBgColor.value
val footerTabDividerColor = PrefI.ipFooterTabDividerColor.value
val footerTabIndicatorColor = PrefI.ipFooterTabIndicatorColor.value
val colorColumnStripBackground = footerTabBgColor.notZero()
?: attrColor(R.attr.colorColumnStripBackground)
svColumnStrip.setBackgroundColor(colorColumnStripBackground)
llQuickPostBar.setBackgroundColor(colorColumnStripBackground)
vBottomPadding.setBackgroundColor(colorColumnStripBackground)
val colorButtonBg = footerButtonBgColor.notZero()
?: colorColumnStripBackground
val colorButtonFg = footerButtonFgColor.notZero()
?: attrColor(R.attr.colorRippleEffect)
btnMenu.backgroundDrawable =
getAdaptiveRippleDrawableRound(this, colorButtonBg, colorButtonFg)
btnToot.backgroundDrawable =
getAdaptiveRippleDrawableRound(this, colorButtonBg, colorButtonFg)
btnQuickToot.backgroundDrawable =
getAdaptiveRippleDrawableRound(this, colorButtonBg, colorButtonFg)
ivQuickTootAccount.backgroundDrawable =
getAdaptiveRippleDrawableRound(this, colorButtonBg, colorButtonFg)
btnQuickPostMenu.backgroundDrawable =
getAdaptiveRippleDrawableRound(this, colorButtonBg, colorButtonFg)
var c = footerButtonFgColor.notZero() ?: attrColor(R.attr.colorTextContent)
val d = ContextCompat.getDrawable(this, R.drawable.ic_question)
?.let { DrawableCompat.wrap(it).apply { setTint(c) } }
ivQuickTootAccount.setDefaultImage(d)
val csl = ColorStateList.valueOf(
footerButtonFgColor.notZero() ?: attrColor(R.attr.colorTextContent)
)
btnToot.imageTintList = csl
btnMenu.imageTintList = csl
btnQuickToot.imageTintList = csl
btnQuickPostMenu.imageTintList = csl
c = footerTabDividerColor.notZero() ?: colorColumnStripBackground
vFooterDivider1.setBackgroundColor(c)
vFooterDivider2.setBackgroundColor(c)
llColumnStrip.indicatorColor =
footerTabIndicatorColor.notZero() ?: attrColor(R.attr.colorTextHelp)
}
fun ActMain.closePopup() {
try {
popupStatusButtons?.dismiss()
} catch (ignored: Throwable) {
}
popupStatusButtons = null
}