Replace TextDrawable with an implementation that supports tint

This commit is contained in:
MM20 2021-12-04 13:51:38 +01:00
parent 0e1ca1c1f9
commit fa22eb4d71
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
12 changed files with 217 additions and 161 deletions

View File

@ -107,7 +107,6 @@ dependencies {
implementation(libs.lottie.core)
implementation(libs.textdrawable)
implementation(libs.bundles.materialdialogs)

View File

@ -0,0 +1,47 @@
package de.mm20.launcher2.graphics
import android.content.res.ColorStateList
import android.graphics.*
import android.graphics.drawable.Drawable
class TextDrawable(
val text: String,
val color: Int = Color.WHITE,
fontSize: Float = 13f,
typeface: Typeface = Typeface.DEFAULT
): Drawable() {
private val paint = Paint()
private val rect = Rect()
init {
paint.textAlign = Paint.Align.CENTER
paint.textSize = fontSize
paint.color = color
paint.isAntiAlias = true
paint.typeface = typeface
paint.style = Paint.Style.FILL
}
override fun draw(canvas: Canvas) {
val bounds = bounds
paint.getTextBounds(text, 0, text.length, rect)
canvas.drawText(text, bounds.exactCenterX(), bounds.exactCenterY() + rect.height() / 2f, paint)
}
override fun setAlpha(alpha: Int) {
paint.alpha = alpha
}
override fun setColorFilter(colorFilter: ColorFilter?) {
paint.colorFilter = colorFilter
}
override fun getOpacity(): Int {
return PixelFormat.TRANSLUCENT
}
override fun setTintList(tint: ColorStateList?) {
paint.color = tint?.defaultColor ?: color
}
}

View File

@ -77,14 +77,6 @@ val OpenSourceLicenses = arrayOf(
copyrightNote = "Copyright (c) 2009-2021 Jonathan Hedley <https://jsoup.org/>",
url = "https://jsoup.org/"
),
OpenSourceLibrary(
name = "TextDrawable",
description = "A light-weight library providing images with letter/text like the Gmail app",
licenseName = R.string.mit_license_name,
licenseText = R.raw.license_mit,
copyrightNote = "Copyright (c) 2014 Amulya Khare",
url = "https://github.com/amulyakhare/TextDrawable"
),
OpenSourceLibrary(
name = "Glide",
description = "A fast and efficient open source media management and image loading framework for Android",

View File

@ -40,7 +40,6 @@ dependencies {
implementation(libs.androidx.core)
implementation(libs.androidx.appcompat)
implementation(libs.textdrawable)
implementation(libs.koin.android)

View File

@ -4,7 +4,6 @@ import android.Manifest
import android.content.ContentUris
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.Typeface
import android.graphics.drawable.ColorDrawable
@ -16,15 +15,13 @@ import androidx.core.graphics.ColorUtils
import androidx.core.graphics.blue
import androidx.core.graphics.green
import androidx.core.graphics.red
import com.amulyakhare.textdrawable.TextDrawable
import de.mm20.launcher2.calendar.R
import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.graphics.TextDrawable
import de.mm20.launcher2.icons.LauncherIcon
import de.mm20.launcher2.ktx.checkPermission
import de.mm20.launcher2.ktx.dp
import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.preferences.LauncherPreferences
import org.json.JSONObject
import java.lang.NullPointerException
import java.text.SimpleDateFormat
import java.util.*
@ -51,26 +48,22 @@ class CalendarEvent(
df.applyPattern("MMM")
val month = df.format(startTime)
val fgLayers = arrayOf(
TextDrawable
.builder()
.beginConfig()
.textColor(Color.WHITE)
.useFont(Typeface.DEFAULT_BOLD)
.fontSize((36 * context.dp).toInt())
.endConfig()
.buildRect(day, 0),
TextDrawable
.builder()
.beginConfig()
.textColor(Color.WHITE)
.bold()
.fontSize((26 * context.dp).toInt())
.endConfig()
.buildRect(month, 0)
TextDrawable(
day,
color = Color.WHITE,
fontSize = 40 * context.dp,
typeface = Typeface.DEFAULT_BOLD
),
TextDrawable(
month,
color = Color.WHITE,
fontSize = 26 * context.dp,
typeface = Typeface.DEFAULT_BOLD
)
)
val foreground = LayerDrawable(fgLayers)
foreground.setLayerInset(0, 0, 0, 0, (26 * context.dp).toInt())
foreground.setLayerInset(1, 0, (36 * context.dp).toInt(), 0, 0)
foreground.setLayerInset(1, 0, (40 * context.dp).toInt(), 0, 0)
val background = ColorDrawable(getDisplayColor(context, color))
return LauncherIcon(
foreground = foreground,
@ -84,7 +77,8 @@ class CalendarEvent(
}
companion object {
fun search(context: Context,
fun search(
context: Context,
query: String,
intervalStart: Long,
intervalEnd: Long,
@ -120,8 +114,15 @@ class CalendarEvent(
if (unselectedCalendars.isNotEmpty()) selection.add("${CalendarContract.Instances.CALENDAR_ID} NOT IN (${unselectedCalendars.joinToString()})")
if (hideAllDayEvents) selection.add("${CalendarContract.Instances.ALL_DAY} = 0")
val selArgs = if (query.isBlank()) null else arrayOf("%$query%")
val sort = "${CalendarContract.Instances.BEGIN} ASC" + if (limit > -1) " LIMIT $limit" else ""
val cursor = context.contentResolver.query(uri, projection, selection.joinToString(separator = " AND "), selArgs, sort)
val sort =
"${CalendarContract.Instances.BEGIN} ASC" + if (limit > -1) " LIMIT $limit" else ""
val cursor = context.contentResolver.query(
uri,
projection,
selection.joinToString(separator = " AND "),
selArgs,
sort
)
?: return mutableListOf()
val proj = arrayOf(
CalendarContract.Attendees.EVENT_ID,
@ -185,12 +186,14 @@ class CalendarEvent(
?: return emptyList()
while (cursor.moveToNext()) {
try {
calendars.add(UserCalendar(
calendars.add(
UserCalendar(
id = cursor.getLong(0),
name = cursor.getString(5) ?: cursor.getString(1) ?: "",
owner = cursor.getString(2),
color = cursor.getInt(3)
))
)
)
} catch (e: NullPointerException) {
continue
}
@ -206,7 +209,13 @@ class CalendarEvent(
it
}
return if (context.resources.getBoolean(R.bool.is_dark_theme)) {
if (ColorUtils.calculateContrast(ContextCompat.getColor(context, R.color.calendar_foreground_color), color) < 2.5 || true) {
if (ColorUtils.calculateContrast(
ContextCompat.getColor(
context,
R.color.calendar_foreground_color
), color
) < 2.5 || true
) {
if (color.red == color.green && color.red == color.blue) {
val level = 0xFF - ((0xFF - color.red) * 0.7f).toInt()
Color.rgb(level, level, level)
@ -217,7 +226,13 @@ class CalendarEvent(
}
} else return color
} else {
if (ColorUtils.calculateContrast(ContextCompat.getColor(context, R.color.calendar_foreground_color), color) < 1.8) {
if (ColorUtils.calculateContrast(
ContextCompat.getColor(
context,
R.color.calendar_foreground_color
), color
) < 1.8
) {
if (color.red == color.green && color.red == color.blue) {
val level = (color.red * 0.7f).toInt()
Color.rgb(level, level, level)

View File

@ -40,7 +40,6 @@ dependencies {
implementation(libs.androidx.core)
implementation(libs.androidx.appcompat)
implementation(libs.textdrawable)
implementation(libs.koin.android)

View File

@ -1,21 +1,21 @@
package de.mm20.launcher2.search.data
import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.Typeface
import android.graphics.drawable.ColorDrawable
import android.provider.ContactsContract
import androidx.core.content.ContextCompat
import androidx.core.database.getStringOrNull
import androidx.core.graphics.drawable.toDrawable
import com.amulyakhare.textdrawable.TextDrawable
import de.mm20.launcher2.contacts.R
import de.mm20.launcher2.ktx.asBitmap
import de.mm20.launcher2.ktx.jsonObjectOf
import de.mm20.launcher2.graphics.TextDrawable
import de.mm20.launcher2.icons.LauncherIcon
import de.mm20.launcher2.ktx.asBitmap
import de.mm20.launcher2.ktx.sp
import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.preferences.LauncherPreferences
import org.json.JSONObject
class Contact(
val id: Long,
@ -40,16 +40,19 @@ class Contact(
}
override fun getPlaceholderIcon(context: Context): LauncherIcon {
val iconText = if (firstName.isNotEmpty()) firstName[0].toString() else "" + if (lastName.isNotEmpty()) lastName[0].toString() else ""
val iconText =
if (firstName.isNotEmpty()) firstName[0].toString() else "" + if (lastName.isNotEmpty()) lastName[0].toString() else ""
return LauncherIcon(
foreground = TextDrawable.builder().buildRect(iconText, ContextCompat.getColor(context, R.color.blue))
foreground = TextDrawable(iconText, Color.WHITE, fontSize = 40 * context.sp, typeface = Typeface.DEFAULT_BOLD),
background = ColorDrawable(ContextCompat.getColor(context, R.color.blue))
)
}
override suspend fun loadIconAsync(context: Context, size: Int): LauncherIcon? {
val contentResolver = context.contentResolver
val uri = ContactsContract.Contacts.getLookupUri(id, lookupKey) ?: return null
val bmp = ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, uri, false)?.asBitmap()
val bmp = ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, uri, false)
?.asBitmap()
?: return null
return LauncherIcon(
foreground = bmp.toDrawable(context.resources)
@ -76,7 +79,8 @@ class Contact(
val sel = "${ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY} LIKE ?"
val selArgs = arrayOf("%$query%")
val cursor = context.contentResolver.query(
ContactsContract.RawContacts.CONTENT_URI, proj, sel, selArgs, null) ?: return mutableListOf()
ContactsContract.RawContacts.CONTENT_URI, proj, sel, selArgs, null
) ?: return mutableListOf()
//Maps raw contact ids to contact ids
val contactMap = mutableMapOf<Long, MutableSet<Long>>()
while (cursor.moveToNext()) {
@ -113,12 +117,18 @@ class Contact(
var lastName = ""
var displayName = ""
val mimeTypeColumn = dataCursor.getColumnIndex(ContactsContract.Data.MIMETYPE)
val emailAddressColumn = dataCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS)
val numberColumn = dataCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
val addressColumn = dataCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS)
val displayNameColumn = dataCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME)
val givenNameColumn = dataCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME)
val familyNameColumn = dataCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME)
val emailAddressColumn =
dataCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS)
val numberColumn =
dataCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
val addressColumn =
dataCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS)
val displayNameColumn =
dataCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME)
val givenNameColumn =
dataCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME)
val familyNameColumn =
dataCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME)
val data1Column = dataCursor.getColumnIndex(ContactsContract.Data.DATA1)
val data3Column = dataCursor.getColumnIndex(ContactsContract.Data.DATA3)
val idColumn = dataCursor.getColumnIndex(ContactsContract.Data._ID)

View File

@ -291,10 +291,6 @@ dependencyResolutionManagement {
.to("org.jsoup", "jsoup")
.version("1.14.2")
alias("textdrawable")
.to("com.amulyakhare", "com.amulyakhare.textdrawable")
.version("1.0.1")
alias("glide")
.to("com.github.bumptech.glide", "glide")
.version("4.12.0")

View File

@ -68,7 +68,6 @@ dependencies {
implementation(libs.androidx.transition)
implementation(libs.materialcomponents)
implementation(libs.viewpropertyobjectanimator)
implementation(libs.textdrawable)
implementation(libs.glide)
implementation(libs.draglinearlayout)
implementation(libs.lottie.core)

View File

@ -1,12 +1,12 @@
package de.mm20.launcher2.ui.legacy.data
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import androidx.core.content.ContextCompat
import com.amulyakhare.textdrawable.TextDrawable
import de.mm20.launcher2.graphics.TextDrawable
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.icons.LauncherIcon
import de.mm20.launcher2.ktx.sp
import de.mm20.launcher2.search.data.Searchable
/**
@ -22,8 +22,7 @@ class InformationText(
override fun getPlaceholderIcon(context: Context): LauncherIcon {
return LauncherIcon(
foreground = TextDrawable.builder()
.buildRect("i", Color.WHITE),
foreground = TextDrawable("i", fontSize = 40 * context.sp),
background = ColorDrawable(ContextCompat.getColor(context, R.color.grey))
)
}

View File

@ -46,7 +46,6 @@ dependencies {
implementation(libs.okhttp)
implementation(libs.glide)
implementation(libs.textdrawable)
implementation(libs.jsoup)
implementation(libs.koin.android)

View File

@ -3,6 +3,7 @@ package de.mm20.launcher2.search.data
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.Typeface
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.util.Log
@ -10,11 +11,12 @@ import android.webkit.URLUtil
import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.toColorInt
import androidx.palette.graphics.Palette
import com.amulyakhare.textdrawable.TextDrawable
import com.bumptech.glide.Glide
import de.mm20.launcher2.graphics.TextDrawable
import de.mm20.launcher2.helper.NetworkUtils
import de.mm20.launcher2.icons.LauncherIcon
import de.mm20.launcher2.ktx.jsonObjectOf
import de.mm20.launcher2.ktx.sp
import de.mm20.launcher2.preferences.LauncherPreferences
import de.mm20.launcher2.preferences.WebsiteProtocols
import de.mm20.launcher2.websites.R
@ -67,7 +69,7 @@ class Website(
override fun getPlaceholderIcon(context: Context): LauncherIcon {
val drawable = if (label.isNotEmpty()) {
TextDrawable.builder().buildRect(label[0].toString(), 0)
TextDrawable(label[0].toString(), typeface = Typeface.DEFAULT_BOLD, fontSize = 40 * context.sp)
} else context.getDrawable(R.drawable.ic_website)!!
return LauncherIcon(
foreground = drawable,