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

308 lines
9.0 KiB
Kotlin
Raw Normal View History

package jp.juggler.subwaytooter
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.drawable.*
import android.graphics.drawable.shapes.RectShape
import android.os.Build
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.ImageView
import jp.juggler.subwaytooter.api.entity.TootAccount
import jp.juggler.subwaytooter.api.entity.TootVisibility
import jp.juggler.subwaytooter.span.EmojiImageSpan
import jp.juggler.subwaytooter.table.UserRelation
2018-12-01 00:02:18 +01:00
import jp.juggler.util.*
object Styler {
2018-11-18 03:38:52 +01:00
fun getVisibilityIconAttr(isMisskeyData : Boolean, visibility : TootVisibility) : Int {
val isMisskey = when(Pref.ipVisibilityStyle(App1.pref)) {
Pref.VS_MASTODON -> false
2018-11-18 03:38:52 +01:00
Pref.VS_MISSKEY -> true
else -> isMisskeyData
}
2018-11-18 03:38:52 +01:00
return when {
isMisskey -> when(visibility) {
TootVisibility.Public -> R.attr.ic_public
TootVisibility.UnlistedHome -> R.attr.btn_home
TootVisibility.PrivateFollowers -> R.attr.ic_lock_open
TootVisibility.DirectSpecified -> R.attr.ic_mail
TootVisibility.DirectPrivate -> R.attr.ic_lock
TootVisibility.WebSetting -> R.attr.ic_question
2018-11-18 03:38:52 +01:00
TootVisibility.LocalPublic -> R.attr.ic_local_ltl
TootVisibility.LocalHome -> R.attr.ic_local_home
TootVisibility.LocalFollowers -> R.attr.ic_local_lock_open
}
2018-11-18 03:38:52 +01:00
else -> when(visibility) {
TootVisibility.Public -> R.attr.ic_public
TootVisibility.UnlistedHome -> R.attr.ic_lock_open
TootVisibility.PrivateFollowers -> R.attr.ic_lock
TootVisibility.DirectSpecified -> R.attr.ic_mail
TootVisibility.DirectPrivate -> R.attr.ic_mail
TootVisibility.WebSetting -> R.attr.ic_question
2018-11-18 03:38:52 +01:00
TootVisibility.LocalPublic -> R.attr.ic_local_ltl
TootVisibility.LocalHome -> R.attr.ic_local_lock_open
TootVisibility.LocalFollowers -> R.attr.ic_local_lock
}
2018-01-11 10:31:25 +01:00
}
}
2018-11-18 03:38:52 +01:00
fun getVisibilityIcon(
context : Context,
isMisskeyData : Boolean,
visibility : TootVisibility
) : Int {
return getAttributeResourceId(context, getVisibilityIconAttr(isMisskeyData, visibility))
}
2018-11-18 03:38:52 +01:00
fun getVisibilityString(
context : Context,
isMisskeyData : Boolean,
visibility : TootVisibility
) : String {
val isMisskey = when(Pref.ipVisibilityStyle(App1.pref)) {
Pref.VS_MASTODON -> false
2018-11-18 03:38:52 +01:00
Pref.VS_MISSKEY -> true
else -> isMisskeyData
}
2018-11-18 03:38:52 +01:00
return context.getString(
when {
isMisskey -> when(visibility) {
TootVisibility.Public -> R.string.visibility_public
TootVisibility.UnlistedHome -> R.string.visibility_home
TootVisibility.PrivateFollowers -> R.string.visibility_followers
TootVisibility.DirectSpecified -> R.string.visibility_direct
TootVisibility.DirectPrivate -> R.string.visibility_private
TootVisibility.WebSetting -> R.string.visibility_web_setting
TootVisibility.LocalPublic -> R.string.visibility_local_public
TootVisibility.LocalHome -> R.string.visibility_local_home
TootVisibility.LocalFollowers -> R.string.visibility_local_followers
}
else -> when(visibility) {
TootVisibility.Public -> R.string.visibility_public
TootVisibility.UnlistedHome -> R.string.visibility_unlisted
TootVisibility.PrivateFollowers -> R.string.visibility_followers
TootVisibility.DirectSpecified -> R.string.visibility_direct
TootVisibility.DirectPrivate -> R.string.visibility_direct
TootVisibility.WebSetting -> R.string.visibility_web_setting
TootVisibility.LocalPublic -> R.string.visibility_local_public
TootVisibility.LocalHome -> R.string.visibility_local_unlisted
TootVisibility.LocalFollowers -> R.string.visibility_local_followers
}
}
2018-11-18 03:38:52 +01:00
)
}
// アイコン付きの装飾テキストを返す
2018-11-18 03:38:52 +01:00
fun getVisibilityCaption(
context : Context,
isMisskeyData : Boolean,
visibility : TootVisibility
) : CharSequence {
val icon_id = getVisibilityIcon(context, isMisskeyData, visibility)
val sv = getVisibilityString(context, isMisskeyData, visibility)
val sb = SpannableStringBuilder()
2018-11-18 03:38:52 +01:00
// アイコン部分
val start = sb.length
sb.append(" ")
val end = sb.length
sb.setSpan(EmojiImageSpan(context, icon_id), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
// 文字列部分
sb.append(' ')
sb.append(sv)
return sb
}
fun setFollowIcon(
context : Context
, ibFollow : ImageButton
, ivDot : ImageView
, relation : UserRelation
, who : TootAccount
2018-11-18 03:38:52 +01:00
, defaultColor : Int
, alphaMultiplier : Float? = null
) {
2018-12-01 00:02:18 +01:00
fun colorError() = getAttributeColor(context, R.attr.colorRegexFilterError)
fun colorAccent() = getAttributeColor(context, R.attr.colorImageButtonAccent)
2018-11-18 03:38:52 +01:00
// 被フォロー状態
when {
relation.blocked_by -> {
ivDot.visibility = View.VISIBLE
setIconDrawableId(
context,
ivDot,
R.drawable.ic_blocked_by,
color = colorError(),
alphaMultiplier = alphaMultiplier
)
}
relation.requested_by -> {
ivDot.visibility = View.VISIBLE
setIconDrawableId(
context,
ivDot,
R.drawable.ic_requested_by,
color = colorError(),
alphaMultiplier = alphaMultiplier
)
}
2018-11-18 03:38:52 +01:00
relation.followed_by -> {
ivDot.visibility = View.VISIBLE
setIconAttr(
context,
ivDot,
R.attr.ic_followed_by,
color = colorAccent(),
alphaMultiplier = alphaMultiplier
)
// 被フォローリクエスト状態の時に followed_by が 真と偽の両方がありえるようなので
// Relationshipだけを見ても被フォローリクエスト状態は分からないっぽい
// 仕方ないので馬鹿正直に「 followed_byが真ならバッジをつける」しかできない
}
else -> {
ivDot.visibility = View.GONE
}
}
// フォローボタン
// follow button
2018-11-18 03:38:52 +01:00
val color : Int
val icon_attr : Int
val contentDescription : String
when {
relation.blocking -> {
icon_attr = R.attr.ic_block
2018-11-18 03:38:52 +01:00
color = defaultColor
contentDescription = context.getString(R.string.follow)
}
relation.muting -> {
icon_attr = R.attr.ic_mute
2018-11-18 03:38:52 +01:00
color = defaultColor
contentDescription = context.getString(R.string.follow)
}
relation.getFollowing(who) -> {
icon_attr = R.attr.ic_follow_cross
2018-11-18 03:38:52 +01:00
color = colorAccent()
contentDescription = context.getString(R.string.unfollow)
}
relation.getRequested(who) -> {
icon_attr = R.attr.ic_follow_wait
2018-11-18 03:38:52 +01:00
color = colorError()
contentDescription = context.getString(R.string.unfollow)
}
else -> {
icon_attr = R.attr.ic_follow_plus
2018-11-18 03:38:52 +01:00
color = defaultColor
contentDescription = context.getString(R.string.follow)
}
}
setIconAttr(context, ibFollow, icon_attr, color = color, alphaMultiplier = alphaMultiplier)
ibFollow.contentDescription = contentDescription
}
2018-12-01 00:02:18 +01:00
private fun getHorizontalPadding(v : View, delta_dp : Float) : Int {
val form_width_max = 420f
val dm = v.resources.displayMetrics
val screen_w = dm.widthPixels
val content_w = (0.5f + form_width_max * dm.density).toInt()
val pad_lr = (screen_w - content_w) / 2
return (if(pad_lr < 0) 0 else pad_lr) + (0.5f + delta_dp * dm.density).toInt()
}
fun fixHorizontalPadding(v : View) {
val pad_lr = getHorizontalPadding(v, 12f)
val pad_t = v.paddingTop
val pad_b = v.paddingBottom
v.setPaddingRelative(pad_lr, pad_t, pad_lr, pad_b)
}
fun fixHorizontalPadding2(v : View) {
val pad_lr = getHorizontalPadding(v, 0f)
val pad_t = v.paddingTop
val pad_b = v.paddingBottom
v.setPaddingRelative(pad_lr, pad_t, pad_lr, pad_b)
}
fun fixHorizontalMargin(v : View) {
val pad_lr = getHorizontalPadding(v, 0f)
val lp = v.layoutParams
if(lp is ViewGroup.MarginLayoutParams) {
lp.leftMargin = pad_lr
lp.rightMargin = pad_lr
}
}
// ActMainの初期化時に更新される
var round_ratio : Float = 0.33f * 0.5f
var boost_alpha : Float? = null
fun calcIconRound(wh : Int) = wh.toFloat() * round_ratio
fun calcIconRound(lp : ViewGroup.LayoutParams) =
Math.min(lp.width, lp.height).toFloat() * round_ratio
}
fun SpannableStringBuilder.appendColorShadeIcon(
2018-11-18 03:38:52 +01:00
context : Context,
drawable_id : Int,
text : String,
color : Int? = null
2018-11-18 03:38:52 +01:00
) : SpannableStringBuilder {
val start = this.length
this.append(text)
val end = this.length
this.setSpan(
2018-11-18 03:38:52 +01:00
EmojiImageSpan(context, drawable_id, useColorShader = true, color = color),
start,
end,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
return this
}
fun SpannableStringBuilder.appendDrawableIcon(
2018-11-18 03:38:52 +01:00
context : Context,
drawable_id : Int,
text : String
) : SpannableStringBuilder {
val start = this.length
this.append(text)
val end = this.length
this.setSpan(
EmojiImageSpan(context, drawable_id),
start,
end,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
return this
}