275 lines
9.9 KiB
Kotlin
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
|
|
}
|