Update default favicon drawable
This commit is contained in:
@@ -5,45 +5,67 @@ import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.ColorFilter
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Path
|
||||
import android.graphics.PixelFormat
|
||||
import android.graphics.Rect
|
||||
import android.graphics.RectF
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.annotation.StyleRes
|
||||
import androidx.core.content.withStyledAttributes
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.graphics.withClip
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import org.koitharu.kotatsu.R
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
class FaviconFallbackDrawable(
|
||||
class FaviconDrawable(
|
||||
context: Context,
|
||||
@StyleRes styleResId: Int,
|
||||
name: String,
|
||||
) : Drawable() {
|
||||
|
||||
private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
|
||||
private var colorBackground = Color.WHITE
|
||||
private var colorStroke = Color.LTGRAY
|
||||
private val letter = name.take(1).uppercase()
|
||||
private val color = MaterialColors.harmonizeWithPrimary(context, colorOfString(name))
|
||||
private var cornerSize = 0f
|
||||
private var colorForeground = Color.DKGRAY
|
||||
private val textBounds = Rect()
|
||||
private val tempRect = Rect()
|
||||
private val boundsF = RectF()
|
||||
private val clipPath = Path()
|
||||
|
||||
init {
|
||||
paint.style = Paint.Style.FILL
|
||||
context.withStyledAttributes(styleResId, R.styleable.FaviconFallbackDrawable) {
|
||||
colorBackground = getColor(R.styleable.FaviconFallbackDrawable_backgroundColor, colorBackground)
|
||||
colorStroke = getColor(R.styleable.FaviconFallbackDrawable_strokeColor, colorStroke)
|
||||
cornerSize = getDimension(R.styleable.FaviconFallbackDrawable_cornerSize, cornerSize)
|
||||
paint.strokeWidth = getDimension(R.styleable.FaviconFallbackDrawable_strokeWidth, 0f) * 2f
|
||||
}
|
||||
paint.textAlign = Paint.Align.CENTER
|
||||
paint.isFakeBoldText = true
|
||||
colorForeground = MaterialColors.harmonize(colorOfString(name), colorBackground)
|
||||
}
|
||||
|
||||
override fun draw(canvas: Canvas) {
|
||||
val cx = bounds.exactCenterX()
|
||||
paint.color = color
|
||||
canvas.drawPaint(paint)
|
||||
paint.color = Color.WHITE
|
||||
val ty = bounds.height() / 2f + textBounds.height() / 2f - textBounds.bottom
|
||||
canvas.drawText(letter, cx, ty, paint)
|
||||
if (cornerSize > 0f) {
|
||||
canvas.withClip(clipPath) {
|
||||
doDraw(canvas)
|
||||
}
|
||||
} else {
|
||||
doDraw(canvas)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBoundsChange(bounds: Rect) {
|
||||
super.onBoundsChange(bounds)
|
||||
boundsF.set(bounds)
|
||||
val innerWidth = bounds.width() - (paint.strokeWidth * 2f)
|
||||
paint.textSize = getTextSizeForWidth(innerWidth, letter) * 0.5f
|
||||
paint.getTextBounds(letter, 0, letter.length, textBounds)
|
||||
invalidateSelf()
|
||||
clipPath.reset()
|
||||
clipPath.addRoundRect(boundsF, cornerSize, cornerSize, Path.Direction.CW)
|
||||
clipPath.close()
|
||||
}
|
||||
|
||||
override fun setAlpha(alpha: Int) {
|
||||
@@ -58,6 +80,24 @@ class FaviconFallbackDrawable(
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun getOpacity() = PixelFormat.TRANSPARENT
|
||||
|
||||
private fun doDraw(canvas: Canvas) {
|
||||
// background
|
||||
paint.color = colorBackground
|
||||
paint.style = Paint.Style.FILL
|
||||
canvas.drawPaint(paint)
|
||||
// letter
|
||||
paint.color = colorForeground
|
||||
val cx = (boundsF.left + boundsF.right) * 0.6f
|
||||
val ty = boundsF.bottom * 0.7f + textBounds.height() * 0.5f - textBounds.bottom
|
||||
canvas.drawText(letter, cx, ty, paint)
|
||||
if (paint.strokeWidth > 0f) {
|
||||
// stroke
|
||||
paint.color = colorStroke
|
||||
paint.style = Paint.Style.STROKE
|
||||
canvas.drawPath(clipPath, paint)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getTextSizeForWidth(width: Float, text: String): Float {
|
||||
val testTextSize = 48f
|
||||
paint.textSize = testTextSize
|
||||
@@ -8,7 +8,7 @@ import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegate
|
||||
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.parser.favicon.faviconUri
|
||||
import org.koitharu.kotatsu.core.ui.image.FaviconFallbackDrawable
|
||||
import org.koitharu.kotatsu.core.ui.image.FaviconDrawable
|
||||
import org.koitharu.kotatsu.core.ui.list.AdapterDelegateClickListenerAdapter
|
||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.core.util.ext.disposeImageRequest
|
||||
@@ -76,7 +76,7 @@ fun exploreSourceListItemAD(
|
||||
|
||||
bind {
|
||||
binding.textViewTitle.text = item.source.title
|
||||
val fallbackIcon = FaviconFallbackDrawable(context, item.source.name)
|
||||
val fallbackIcon = FaviconDrawable(context, R.style.FaviconDrawable_Small, item.source.name)
|
||||
binding.imageViewIcon.newImageRequest(lifecycleOwner, item.source.faviconUri())?.run {
|
||||
fallback(fallbackIcon)
|
||||
placeholder(fallbackIcon)
|
||||
@@ -107,7 +107,7 @@ fun exploreSourceGridItemAD(
|
||||
|
||||
bind {
|
||||
binding.textViewTitle.text = item.source.title
|
||||
val fallbackIcon = FaviconFallbackDrawable(context, item.source.name)
|
||||
val fallbackIcon = FaviconDrawable(context, R.style.FaviconDrawable_Large, item.source.name)
|
||||
binding.imageViewIcon.newImageRequest(lifecycleOwner, item.source.faviconUri())?.run {
|
||||
fallback(fallbackIcon)
|
||||
placeholder(fallbackIcon)
|
||||
|
||||
@@ -3,8 +3,9 @@ package org.koitharu.kotatsu.search.ui.suggestion.adapter
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import coil.ImageLoader
|
||||
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.parser.favicon.faviconUri
|
||||
import org.koitharu.kotatsu.core.ui.image.FaviconFallbackDrawable
|
||||
import org.koitharu.kotatsu.core.ui.image.FaviconDrawable
|
||||
import org.koitharu.kotatsu.core.util.ext.disposeImageRequest
|
||||
import org.koitharu.kotatsu.core.util.ext.enqueueWith
|
||||
import org.koitharu.kotatsu.core.util.ext.newImageRequest
|
||||
@@ -31,7 +32,7 @@ fun searchSuggestionSourceAD(
|
||||
bind {
|
||||
binding.textViewTitle.text = item.source.title
|
||||
binding.switchLocal.isChecked = item.isEnabled
|
||||
val fallbackIcon = FaviconFallbackDrawable(context, item.source.name)
|
||||
val fallbackIcon = FaviconDrawable(context, R.style.FaviconDrawable_Small, item.source.name)
|
||||
binding.imageViewCover.newImageRequest(lifecycleOwner, item.source.faviconUri())?.run {
|
||||
fallback(fallbackIcon)
|
||||
placeholder(fallbackIcon)
|
||||
|
||||
@@ -9,7 +9,7 @@ import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegate
|
||||
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.parser.favicon.faviconUri
|
||||
import org.koitharu.kotatsu.core.ui.image.FaviconFallbackDrawable
|
||||
import org.koitharu.kotatsu.core.ui.image.FaviconDrawable
|
||||
import org.koitharu.kotatsu.core.ui.list.OnTipCloseListener
|
||||
import org.koitharu.kotatsu.core.util.ext.crossfade
|
||||
import org.koitharu.kotatsu.core.util.ext.disposeImageRequest
|
||||
@@ -66,7 +66,7 @@ fun sourceConfigItemCheckableDelegate(
|
||||
binding.textViewTitle.text = item.source.title
|
||||
binding.switchToggle.isChecked = item.isEnabled
|
||||
binding.textViewDescription.textAndVisible = item.summary
|
||||
val fallbackIcon = FaviconFallbackDrawable(context, item.source.name)
|
||||
val fallbackIcon = FaviconDrawable(context, R.style.FaviconDrawable_Small, item.source.name)
|
||||
binding.imageViewIcon.newImageRequest(lifecycleOwner, item.source.faviconUri())?.run {
|
||||
crossfade(context)
|
||||
error(fallbackIcon)
|
||||
@@ -107,7 +107,7 @@ fun sourceConfigItemDelegate2(
|
||||
binding.imageViewRemove.isVisible = item.isEnabled
|
||||
binding.imageViewConfig.isVisible = item.isEnabled
|
||||
binding.textViewDescription.textAndVisible = item.summary
|
||||
val fallbackIcon = FaviconFallbackDrawable(context, item.source.name)
|
||||
val fallbackIcon = FaviconDrawable(context, R.style.FaviconDrawable_Small, item.source.name)
|
||||
binding.imageViewIcon.newImageRequest(lifecycleOwner, item.source.faviconUri())?.run {
|
||||
crossfade(context)
|
||||
error(fallbackIcon)
|
||||
|
||||
@@ -18,8 +18,11 @@
|
||||
android:layout_height="72dp"
|
||||
android:background="?colorControlHighlight"
|
||||
android:labelFor="@id/textView_title"
|
||||
android:padding="1dp"
|
||||
android:scaleType="fitCenter"
|
||||
app:shapeAppearance="?shapeAppearanceCornerMedium"
|
||||
app:strokeColor="?colorOutline"
|
||||
app:strokeWidth="1dp"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -116,9 +116,16 @@
|
||||
<attr name="shapeAppearance" />
|
||||
<attr name="shapeAppearanceOverlay" />
|
||||
<attr name="cardBackgroundColor" />
|
||||
<attr name="strokeWidth"/>
|
||||
<attr name="strokeWidth" />
|
||||
<attr name="strokeColor" />
|
||||
<attr name="elevation" />
|
||||
</declare-styleable>
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="FaviconFallbackDrawable">
|
||||
<attr name="backgroundColor" />
|
||||
<attr name="strokeColor" />
|
||||
<attr name="strokeWidth" />
|
||||
<attr name="cornerSize" />
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -287,7 +287,7 @@
|
||||
<item name="android:selectable">false</item>
|
||||
</style>
|
||||
|
||||
<!-- Progress drawable -->
|
||||
<!-- Drawable -->
|
||||
|
||||
<style name="ProgressDrawable">
|
||||
<item name="android:fillAlpha">1</item>
|
||||
@@ -299,4 +299,19 @@
|
||||
<item name="autoFitTextSize">true</item>
|
||||
</style>
|
||||
|
||||
<style name="FaviconDrawable">
|
||||
<item name="backgroundColor">?colorBackgroundFloating</item>
|
||||
<item name="strokeColor">?colorOutline</item>
|
||||
</style>
|
||||
|
||||
<style name="FaviconDrawable.Small">
|
||||
<item name="strokeWidth">1dp</item>
|
||||
<item name="cornerSize">8dp</item>
|
||||
</style>
|
||||
|
||||
<style name="FaviconDrawable.Large">
|
||||
<item name="strokeWidth">1dp</item>
|
||||
<item name="cornerSize">12dp</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user