Initial commit

This commit is contained in:
MM20
2021-09-18 23:37:52 +02:00
commit 749e4e3073
938 changed files with 50475 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
package de.mm20.launcher2.graphics
import android.content.Context
import android.graphics.*
import android.graphics.drawable.AdaptiveIconDrawable
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import android.os.Build
import androidx.core.graphics.drawable.toBitmap
import de.mm20.launcher2.ktx.dp
import kotlin.math.roundToInt
class BadgeDrawable(context: Context, drawable: Drawable) : Drawable() {
private val drawable: BitmapDrawable
init {
val size = (28.8 * context.dp).roundToInt()
val drw: Drawable = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && drawable is AdaptiveIconDrawable) {
LayerDrawable(arrayOf(
drawable.background,
drawable.foreground
)).apply {
val inset = (-size * 0.25).roundToInt()
setLayerInset(1, inset, inset, inset, inset)
setLayerInset(0, inset, inset, inset, inset)
}
} else {
drawable
}
val bitmap = drw.toBitmap(size, size).run {
if(isMutable) this
else this.copy(config, true)
}
this.drawable = BitmapDrawable(context.resources, bitmap)
}
override fun setAlpha(alpha: Int) {
}
override fun getOpacity(): Int {
return PixelFormat.TRANSLUCENT
}
override fun setColorFilter(colorFilter: ColorFilter?) {
}
override fun draw(canvas: Canvas) {
canvas.clipPath(Path().apply { addOval(
bounds.left.toFloat(),
bounds.top.toFloat(),
bounds.right.toFloat(),
bounds.bottom.toFloat(), Path.Direction.CW) })
drawable.setBounds(bounds.left, bounds.top, bounds.right, bounds.bottom)
drawable.draw(canvas)
}
}

View File

@@ -0,0 +1,17 @@
package de.mm20.launcher2.helper
import android.content.Context
import android.net.ConnectivityManager
object NetworkUtils {
fun isOffline(context: Context, allowMobile: Boolean = true): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val info = connectivityManager.activeNetworkInfo ?: return true
return when {
info.type == ConnectivityManager.TYPE_WIFI -> false
info.type == ConnectivityManager.TYPE_MOBILE && allowMobile -> false
else -> true
}
}
}

View File

@@ -0,0 +1,84 @@
package de.mm20.launcher2.icons
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import androidx.core.graphics.drawable.toBitmap
import androidx.palette.graphics.Palette
import java.lang.ref.WeakReference
open class LauncherIcon(
foreground: Drawable,
background: Drawable? = null,
foregroundScale: Float = 1f,
backgroundScale: Float = 1f,
var autoGenerateBackgroundMode: Int = BACKGROUND_WHITE
) {
var foreground = foreground
set(value) {
field = value
updateBackgroundColor()
notifyCallbacks()
}
private fun updateBackgroundColor() {
if (background == null) {
when (autoGenerateBackgroundMode) {
BACKGROUND_COLOR -> {
val palette = Palette
.from(foreground.toBitmap())
.generate()
this.background = ColorDrawable(palette.getDominantColor(Color.WHITE))
badgeColor = palette.getLightVibrantColor(0xFFF0F0F0.toInt())
}
BACKGROUND_WHITE -> this.background = ColorDrawable(Color.WHITE)
else -> this.foregroundScale = 1f
}
}
}
var background = background
set(value) {
field = value
notifyCallbacks()
}
var foregroundScale = foregroundScale
set(value) {
field = value
notifyCallbacks()
}
var backgroundScale = backgroundScale
set(value) {
field = value
notifyCallbacks()
}
private val callbacks = mutableListOf<WeakReference<(LauncherIcon) -> Unit>>()
fun registerCallback(callback: (LauncherIcon) -> Unit) {
callbacks.add(WeakReference(callback))
}
protected fun notifyCallbacks() {
val iterator = callbacks.iterator()
while(iterator.hasNext()) {
val callback = iterator.next()
callback.get()?.invoke(this) ?: iterator.remove()
}
}
var badgeColor: Int = 0xFFF0F0F0.toInt()
init {
updateBackgroundColor()
}
companion object {
const val BACKGROUND_NONE = 0
const val BACKGROUND_COLOR = 1
const val BACKGROUND_WHITE = 2
}
}

View File

@@ -0,0 +1,135 @@
package de.mm20.launcher2.view
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.Icon
import android.renderscript.Allocation
import android.renderscript.Element
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur
import android.util.AttributeSet
import android.view.View
import com.airbnb.lottie.LottieDrawable
import com.airbnb.lottie.LottieProperty
import com.airbnb.lottie.model.KeyPath
import kotlin.math.max
import kotlin.math.min
class ElevationImageView : androidx.appcompat.widget.AppCompatImageView {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleRes: Int) : super(context, attrs, defStyleRes)
private val secondCanvas = Canvas()
private var shadowBitmap: Bitmap? = null
private var inAllocation: Allocation? = null
private lateinit var renderScript : RenderScript
private lateinit var blur : ScriptIntrinsicBlur
val shadowPaint = Paint().also {
it.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OVER)
it.colorFilter = PorterDuffColorFilter(Color.BLACK, PorterDuff.Mode.SRC_ATOP)
it.alpha = 66
setLayerType(View.LAYER_TYPE_SOFTWARE, null)
}
val clearPaint = Paint().also {
it.color = Color.TRANSPARENT
it.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
blur.destroy()
renderScript.destroy()
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
renderScript = RenderScript.create(context)
blur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript))
}
override fun onDraw(canvas: Canvas) {
secondCanvas.drawRect(0f, 0f, secondCanvas.width.toFloat(), secondCanvas.height.toFloat(), clearPaint)
if (drawable == null) {
return // couldn't resolve the URI
}
val drawableWidth = drawable.intrinsicWidth
val drawableHeight = drawable.intrinsicHeight
if (drawableWidth == 0 || drawableHeight == 0) {
return // nothing to draw (empty bounds)
}
if (shadowBitmap?.width != width || shadowBitmap?.height != height) {
shadowBitmap?.recycle()
inAllocation?.destroy()
if (z > 0f && width > 0 && height > 0) {
shadowBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also {
secondCanvas.setBitmap(it)
}
inAllocation = shadowBitmap?.let { Allocation.createFromBitmap(renderScript, it) }
}
}
val saveCount = canvas.saveCount
val saveCount2 = secondCanvas.saveCount
canvas.save()
secondCanvas.save()
canvas.translate(paddingLeft.toFloat(), paddingTop.toFloat())
secondCanvas.translate(paddingLeft.toFloat(), paddingTop.toFloat() + getShadowTranslation())
if (!imageMatrix.isIdentity) {
canvas.concat(imageMatrix)
secondCanvas.concat(imageMatrix)
}
drawable.draw(canvas)
drawable.draw(secondCanvas)
shadowBitmap = shadowBitmap?.let { blurBitmap(it) }
canvas.restoreToCount(saveCount)
secondCanvas.restoreToCount(saveCount2)
shadowBitmap?.let { canvas.drawBitmap(it, 0f, 0f, shadowPaint) }
}
private fun blurBitmap(bitmap: Bitmap): Bitmap {
val alloc = inAllocation ?: return bitmap
if (z == 0f) return bitmap
alloc.copyFrom(bitmap)
blur.setRadius(max(0f, min(getShadowBlurRadius(), 25f)))
blur.setInput(alloc)
blur.forEach(alloc)
alloc.copyTo(bitmap)
return bitmap
}
override fun setColorFilter(cf: ColorFilter?) {
super.setColorFilter(cf)
val drawable = drawable
if (drawable is LottieDrawable) {
drawable.addValueCallback(KeyPath("**"), LottieProperty.COLOR_FILTER) {
cf
}
}
}
private fun getShadowTranslation(): Float {
return z * 0.5f
}
private fun getShadowBlurRadius(): Float {
return z * 0.5f
}
}