diff --git a/app/build.gradle b/app/build.gradle
index 008fc0fe80951850e5ad1c0485c38189addddacc..0a6d4663afebf6754e0e0244a19345bac3ee63b2 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,10 +1,10 @@
apply plugin: 'com.android.application'
-apply plugin: 'io.fabric'
+apply plugin: 'kotlin-android'
// Manifest version information!
def versionMajor = 1
-def versionMinor = 2
-def versionPatch = 4
+def versionMinor = 3
+def versionPatch = 0
android {
compileSdkVersion rootProject.ext.compileSdkVersion
@@ -16,7 +16,7 @@ android {
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- renderscriptTargetApi 18
+ renderscriptTargetApi 28
renderscriptSupportModeEnabled true
}
buildTypes {
@@ -83,8 +83,6 @@ dependencies {
apiNougatImplementation 'org.cyanogenmod:platform.sdk:6.0'
apiOreoImplementation files('libs/lineage-sdk.jar')
- debugImplementation 'com.crashlytics.sdk.android:crashlytics:2.9.9'
- debugImplementation 'com.google.firebase:firebase-core:16.0.6'
debugImplementation 'com.amitshekhar.android:debug-db:1.0.4'
implementation 'org.greenrobot:eventbus:3.1.1'
@@ -111,6 +109,11 @@ dependencies {
// Rx Relay
implementation "com.jakewharton.rxrelay2:rxrelay:${rootProject.ext.rxRelayVersion}"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+
+ // Blur Library
+ implementation project(':hoko-blur')
+
// Room
implementation "android.arch.persistence.room:runtime:1.1.1"
annotationProcessor "android.arch.persistence.room:compiler:1.1.1"
@@ -140,5 +143,4 @@ dependencies {
androidTestImplementation "com.android.support.test:rules:${rootProject.ext.runnerRulesVersion}"
}
-apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.getkeepsafe.dexcount'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 1f225ac514833c3c77d68fd5331f04dcf44fed5c..2c8f21854ef0294fd1b1b456f5d0ac9deb47f5bd 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -31,12 +31,15 @@
+
+
0) {
+ statusBarHeight = res.getDimensionPixelSize(resourceId);
+ }
+
ComponentName cn = new ComponentName(context.getPackageName(),
this.getClass().getName());
@@ -248,8 +253,6 @@ public class DeviceProfile {
dateTextBottomPadding = (dateTextviewHeight - (int) (0.86 * Utilities.calculateTextHeight(
(float) dateTextSize / 2))) / 2;
- Log.i(TAG, "datepadding: " + dateTextTopPadding + "*" + dateTextBottomPadding);
-
cellHeightWithoutPaddingPx = iconSizePx + Utilities.pxFromDp(4, dm)
+ Utilities.calculateTextHeight(iconTextSizePx);
@@ -304,7 +307,7 @@ public class DeviceProfile {
return pageIndicatorSizePx + pageIndicatorBottomPaddingPx + pageIndicatorTopPaddingPx;
}
- public int getMaxWidgetWidth(){
+ public int getMaxWidgetWidth() {
return maxWidgetWidth;
}
@@ -351,6 +354,34 @@ public class DeviceProfile {
return resizedPath;
}
+ public boolean hasSoftNavigationBar(Context context) {
+ WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ Display display = wm.getDefaultDisplay();
+ DisplayMetrics dm = new DisplayMetrics();
+ display.getMetrics(dm);
+
+ Point smallestSize = new Point();
+ Point largestSize = new Point();
+ display.getCurrentSizeRange(smallestSize, largestSize);
+
+ int availableHeight = largestSize.y;
+
+ Point realSize = new Point();
+ display.getRealSize(realSize);
+ int realHeight = realSize.y;
+ context = getContext(context, Configuration.ORIENTATION_PORTRAIT);
+ Resources res = context.getResources();
+
+ // status bar height
+ statusBarHeight = 0;
+ int resourceId = res.getIdentifier("status_bar_height", "dimen", "android");
+ if (resourceId > 0) {
+ statusBarHeight = res.getDimensionPixelSize(resourceId);
+ }
+
+ return (realHeight - availableHeight - statusBarHeight) > 0;
+ }
+
private int getLauncherIconDensity(int requiredSize) {
// Densities typically defined by an app.
int[] densityBuckets = new int[]{
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/KotlinUtils.kt b/app/src/main/java/foundation/e/blisslauncher/core/KotlinUtils.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e45d2b68824c1cfd0143ccc6e74441211f690a44
--- /dev/null
+++ b/app/src/main/java/foundation/e/blisslauncher/core/KotlinUtils.kt
@@ -0,0 +1,25 @@
+package foundation.e.blisslauncher.core
+
+import android.os.Handler
+import android.os.Looper
+
+val mainHandler by lazy { Handler(Looper.getMainLooper()) }
+
+
+fun runOnMainThread(r: () -> Unit) {
+ runOnThread(mainHandler, r)
+}
+
+fun runOnThread(handler: Handler, r: () -> Unit) {
+ if (handler.looper.thread.id == Looper.myLooper()?.thread?.id) {
+ r()
+ } else {
+ handler.post(r)
+ }
+}
+
+inline fun Iterable.safeForEach(action: (T) -> Unit) {
+ val tmp = ArrayList()
+ tmp.addAll(this)
+ for (element in tmp) action(element)
+}
\ No newline at end of file
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/Utilities.java b/app/src/main/java/foundation/e/blisslauncher/core/Utilities.java
index 48648b6fc5ea4329854267aa9b1110f066980513..52c69eba5760dc045a336acb409b58d2c2b779c0 100755
--- a/app/src/main/java/foundation/e/blisslauncher/core/Utilities.java
+++ b/app/src/main/java/foundation/e/blisslauncher/core/Utilities.java
@@ -2,7 +2,10 @@ package foundation.e.blisslauncher.core;
import android.content.Context;
import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.TextUtils;
import android.util.DisplayMetrics;
@@ -16,6 +19,10 @@ import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -41,6 +48,19 @@ public class Utilities {
public static final boolean ATLEAST_MARSHMALLOW =
Build.VERSION.SDK_INT >= 23;
+
+ // These values are same as that in {@link AsyncTask}.
+ private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
+ private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
+ private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
+ private static final int KEEP_ALIVE = 1;
+ /**
+ * An {@link Executor} to be used with async task with no limit on the queue size.
+ */
+ public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
+ CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
+ TimeUnit.SECONDS, new LinkedBlockingQueue());
+
/**
* Compresses the bitmap to a byte array for serialization.
*/
@@ -159,6 +179,38 @@ public class Utilities {
return result;
}
+ public static Bitmap drawableToBitmap(Drawable drawable) {
+ return Utilities.drawableToBitmap(drawable, true);
+ }
+
+ public static Bitmap drawableToBitmap(Drawable drawable, boolean forceCreate) {
+ return drawableToBitmap(drawable, forceCreate, 0);
+ }
+
+ public static Bitmap drawableToBitmap(Drawable drawable, boolean forceCreate, int fallbackSize) {
+ if (!forceCreate && drawable instanceof BitmapDrawable) {
+ return ((BitmapDrawable) drawable).getBitmap();
+ }
+
+ int width = drawable.getIntrinsicWidth();
+ int height = drawable.getIntrinsicHeight();
+
+ if (width <= 0 || height <= 0) {
+ if (fallbackSize > 0) {
+ width = height = fallbackSize;
+ } else {
+ return null;
+ }
+ }
+
+ Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+
+ Canvas canvas = new Canvas(bitmap);
+ drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ drawable.draw(canvas);
+ return bitmap;
+ }
+
public static boolean isBootCompleted() {
return "1".equals(getSystemProperty("sys.boot_completed", "1"));
}
@@ -177,4 +229,6 @@ public class Utilities {
return defaultValue;
}
+
+
}
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/blur/BlurWallpaperFilter.kt b/app/src/main/java/foundation/e/blisslauncher/core/blur/BlurWallpaperFilter.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0539b85cbbaa4523d7747ca3d773159f724e746f
--- /dev/null
+++ b/app/src/main/java/foundation/e/blisslauncher/core/blur/BlurWallpaperFilter.kt
@@ -0,0 +1,33 @@
+package foundation.e.blisslauncher.core.blur
+
+import android.content.Context
+import android.graphics.Bitmap
+import com.hoko.blur.HokoBlur
+import com.hoko.blur.task.AsyncBlurTask
+
+class BlurWallpaperFilter(private val context: Context) : WallpaperFilter {
+
+ private var blurRadius = 8
+
+ override fun apply(wallpaper: Bitmap): WallpaperFilter.ApplyTask {
+ return WallpaperFilter.ApplyTask.create { emitter ->
+ HokoBlur.with(context)
+ .scheme(HokoBlur.SCHEME_OPENGL)
+ .mode(HokoBlur.MODE_STACK)
+ .radius(blurRadius)
+ .sampleFactor(8f)
+ .forceCopy(false)
+ .needUpscale(true)
+ .processor()
+ .asyncBlur(wallpaper, object : AsyncBlurTask.Callback {
+ override fun onBlurSuccess(bitmap: Bitmap) {
+ emitter.onSuccess(bitmap)
+ }
+
+ override fun onBlurFailed(error: Throwable?) {
+ emitter.onError(error!!)
+ }
+ })
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/blur/BlurWallpaperProvider.kt b/app/src/main/java/foundation/e/blisslauncher/core/blur/BlurWallpaperProvider.kt
new file mode 100644
index 0000000000000000000000000000000000000000..765c27f398efbba063e64d10bf02de05c1e1b766
--- /dev/null
+++ b/app/src/main/java/foundation/e/blisslauncher/core/blur/BlurWallpaperProvider.kt
@@ -0,0 +1,238 @@
+package foundation.e.blisslauncher.core.blur
+
+import android.Manifest
+import android.app.WallpaperManager
+import android.content.Context
+import android.content.pm.PackageManager
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.ColorMatrix
+import android.graphics.ColorMatrixColorFilter
+import android.graphics.Paint
+import android.support.v4.app.ActivityCompat
+import android.util.DisplayMetrics
+import android.util.Log
+import android.view.WindowManager
+import android.widget.Toast
+import foundation.e.blisslauncher.core.Utilities
+import foundation.e.blisslauncher.core.runOnMainThread
+import foundation.e.blisslauncher.core.safeForEach
+import foundation.e.blisslauncher.core.utils.SingletonHolder
+import foundation.e.blisslauncher.core.utils.ensureOnMainThread
+import foundation.e.blisslauncher.core.utils.useApplicationContext
+import java.util.*
+import kotlin.math.max
+
+class BlurWallpaperProvider(val context: Context) {
+
+ private val wallpaperManager: WallpaperManager = WallpaperManager.getInstance(context)
+ private val listeners = ArrayList()
+ private val displayMetrics = DisplayMetrics()
+
+ var wallpaper: Bitmap? = null
+ private set(value) {
+ if (field != value) {
+ field?.recycle()
+ field = value
+ }
+ }
+ var placeholder: Bitmap? = null
+ private set(value) {
+ if (field != value) {
+ field?.recycle()
+ field = value
+ }
+ }
+
+ private val vibrancyPaint = Paint(Paint.FILTER_BITMAP_FLAG or Paint.ANTI_ALIAS_FLAG)
+
+ private val mUpdateRunnable = Runnable { updateWallpaper() }
+
+ private val wallpaperFilter = BlurWallpaperFilter(context)
+ private var applyTask: WallpaperFilter.ApplyTask? = null
+
+ private var updatePending = false
+
+ init {
+ isEnabled = getEnabledStatus()
+ updateAsync()
+ }
+
+ private fun getEnabledStatus() = wallpaperManager.wallpaperInfo == null
+
+ fun updateAsync() {
+ Utilities.THREAD_POOL_EXECUTOR.execute(mUpdateRunnable)
+ }
+
+ private fun updateWallpaper() {
+ if (applyTask != null) {
+ updatePending = true
+ return
+ }
+
+ // Prepare a placeholder before hand so that it can be used in case wallpaper is null
+ val wm =
+ context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
+ val display = wm.defaultDisplay
+ display.getRealMetrics(displayMetrics)
+ val width = displayMetrics.widthPixels
+ val height = displayMetrics.heightPixels
+ placeholder = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
+ val canvas = Canvas(placeholder!!)
+ canvas.drawColor(0x44000000)
+
+ if (ActivityCompat.checkSelfPermission(
+ context,
+ Manifest.permission.READ_EXTERNAL_STORAGE
+ ) != PackageManager.PERMISSION_GRANTED
+ ) {
+ Log.d("BWP", "NO permission granted")
+ return
+ }
+
+ val enabled = getEnabledStatus()
+ if (enabled != isEnabled) {
+ isEnabled = enabled
+ runOnMainThread {
+ listeners.safeForEach(Listener::onEnabledChanged)
+ }
+ }
+
+ if (!isEnabled) {
+ wallpaper = null
+ return
+ }
+
+ var wallpaper = try {
+ Utilities.drawableToBitmap(wallpaperManager.drawable, true) as Bitmap
+ } catch (e: Exception) {
+ runOnMainThread {
+ val msg = "Failed: ${e.message}"
+ Toast.makeText(context, msg, Toast.LENGTH_LONG).show()
+ notifyWallpaperChanged()
+ }
+ return
+ }
+ wallpaper = scaleAndCropToScreenSize(wallpaper)
+ wallpaper = applyVibrancy(wallpaper)
+ applyTask = wallpaperFilter.apply(wallpaper).setCallback {result, error ->
+ if(error == null) {
+ this@BlurWallpaperProvider.wallpaper = result
+ runOnMainThread(::notifyWallpaperChanged)
+ wallpaper.recycle()
+ }else {
+ if (error is OutOfMemoryError) {
+ runOnMainThread {
+ Toast.makeText(context, "Failed", Toast.LENGTH_LONG).show()
+ notifyWallpaperChanged()
+ }
+ }
+ wallpaper.recycle()
+ }
+ }
+ applyTask = null
+ if (updatePending) {
+ updatePending = false
+ updateWallpaper()
+ }
+ }
+
+
+ private fun notifyWallpaperChanged() {
+ listeners.forEach(Listener::onWallpaperChanged)
+ }
+
+ private fun applyVibrancy(wallpaper: Bitmap?): Bitmap {
+ val width = wallpaper!!.width
+ val height = wallpaper.height
+ val bitmap = Bitmap.createBitmap(
+ width,
+ height,
+ Bitmap.Config.ARGB_8888
+ )
+ val canvas = Canvas()
+ canvas.setBitmap(bitmap)
+ val colorMatrix = ColorMatrix()
+ colorMatrix.setSaturation(1.25f)
+ val filter = ColorMatrixColorFilter(colorMatrix)
+ vibrancyPaint.colorFilter = filter
+ canvas.drawBitmap(wallpaper, 0f, 0f, vibrancyPaint)
+ wallpaper.recycle()
+ return bitmap
+ }
+
+ private fun scaleAndCropToScreenSize(wallpaper: Bitmap): Bitmap {
+ val wm =
+ context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
+ val display = wm.defaultDisplay
+ display.getRealMetrics(displayMetrics)
+ val width = displayMetrics.widthPixels
+ val height = displayMetrics.heightPixels
+ val widthFactor = width.toFloat() / wallpaper.width
+ val heightFactor = height.toFloat() / wallpaper.height
+ val upscaleFactor = Math.max(widthFactor, heightFactor)
+ if (upscaleFactor <= 0) {
+ return wallpaper
+ }
+ val scaledWidth =
+ max(width.toFloat(), wallpaper.width * upscaleFactor).toInt()
+ val scaledHeight =
+ max(height.toFloat(), wallpaper.height * upscaleFactor).toInt()
+ val scaledWallpaper =
+ Bitmap.createScaledBitmap(wallpaper, scaledWidth, scaledHeight, false)
+ val navigationBarHeight = 0
+ /*if (BlissLauncher.getApplication(context).getDeviceProfile().hasSoftNavigationBar(context)) {
+
+ int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
+ if (resourceId > 0) {
+ navigationBarHeight = context.getResources().getDimensionPixelSize(resourceId);
+ }
+ }*/
+ val y: Int
+ y = if (scaledWallpaper.height > height) {
+ (scaledWallpaper.height - height) / 2
+ } else 0
+
+ return Bitmap.createBitmap(
+ scaledWallpaper,
+ 0,
+ y,
+ width,
+ height - navigationBarHeight
+ )
+ }
+
+ fun addListener(listener: Listener) {
+ listeners.add(listener)
+ }
+
+ fun removeListener(listener: Listener) {
+ listeners.remove(listener)
+ }
+
+ fun createDrawable(): ShaderBlurDrawable {
+ return ShaderBlurDrawable(this)
+ }
+
+ interface Listener {
+ fun onWallpaperChanged() {}
+ fun onEnabledChanged() {}
+ }
+
+ /*fun clear() {
+ listener = null
+ cancelPreTask(true)
+ sInstance = null
+ }*/
+
+ companion object :
+ SingletonHolder(ensureOnMainThread(useApplicationContext(::BlurWallpaperProvider))) {
+
+ var isEnabled: Boolean = false
+ private var sEnabledFlag: Int = 0
+
+ fun isEnabled(flag: Int): Boolean {
+ return isEnabled && sEnabledFlag and flag != 0
+ }
+ }
+}
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/blur/ShaderBlurDrawable.kt b/app/src/main/java/foundation/e/blisslauncher/core/blur/ShaderBlurDrawable.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e74a2792536bc877b2cb66975b6f30543b1af8d8
--- /dev/null
+++ b/app/src/main/java/foundation/e/blisslauncher/core/blur/ShaderBlurDrawable.kt
@@ -0,0 +1,126 @@
+package foundation.e.blisslauncher.core.blur
+
+import android.graphics.Bitmap
+import android.graphics.BitmapShader
+import android.graphics.Canvas
+import android.graphics.ColorFilter
+import android.graphics.Paint
+import android.graphics.Path
+import android.graphics.PixelFormat
+import android.graphics.RectF
+import android.graphics.Shader
+import android.graphics.drawable.Drawable
+import foundation.e.blisslauncher.core.DeviceProfile
+
+class ShaderBlurDrawable internal constructor(private val blurWallpaperProvider: BlurWallpaperProvider) :
+ Drawable(), BlurWallpaperProvider.Listener {
+
+ private var blurAlpha = 255
+ private val blurPaint = Paint(Paint.FILTER_BITMAP_FLAG or Paint.ANTI_ALIAS_FLAG)
+ private var blurBitmap: Bitmap? = null
+ set(value) {
+ if (field != value) {
+ field = value
+ blurPaint.shader =
+ value?.let { BitmapShader(it, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP) }
+ }
+ }
+
+ private val blurBounds = RectF()
+ private val blurPath = Path()
+ private var blurPathValid = false
+ set(value) {
+ if (field != value) {
+ field = value
+ if (!value) {
+ invalidateSelf()
+ }
+ }
+ }
+
+ var noRadius = true
+
+
+ override fun draw(canvas: Canvas) = draw(canvas, noRadius)
+
+ fun draw(canvas: Canvas, noRadius: Boolean = false) {
+ if (blurAlpha == 0) return
+ blurBitmap = blurWallpaperProvider.wallpaper
+
+ if(blurBitmap == null) {
+ blurBitmap = blurWallpaperProvider.placeholder
+ }
+ blurBitmap =
+ if (blurBitmap!!.height > (blurBounds.bottom.toInt() - blurBounds.top.toInt())) {
+
+ Bitmap.createBitmap(
+ blurBitmap!!,
+ blurBounds.left.toInt(), blurBounds.top.toInt(),
+ blurBounds.right.toInt() - blurBounds.left.toInt(),
+ blurBounds.bottom.toInt() - blurBounds.top.toInt()
+ )
+ } else {
+ blurBitmap
+ }
+
+ //setupBlurPath()
+
+ //canvas.translate(0f, -1500f)
+ if (noRadius) {
+ canvas.drawRect(
+ 0f, 0f,
+ blurBounds.right - blurBounds.left, blurBounds.bottom - blurBounds.top,
+ blurPaint
+ )
+ } else {
+ canvas.drawPath(DeviceProfile.path, blurPaint)
+ }
+ //canvas.translate(0f, 1500f)
+ }
+
+ override fun setAlpha(alpha: Int) {
+ blurAlpha = alpha
+ blurPaint.alpha = alpha
+ }
+
+ override fun getAlpha(): Int {
+ return blurAlpha
+ }
+
+ private fun setupBlurPath() {
+ if (blurPathValid) return
+
+ blurPath.reset()
+ blurPath.addRect(
+ 0f, 0f,
+ blurBounds.right - blurBounds.left, blurBounds.bottom - blurBounds.top, Path.Direction.CW
+ )
+ }
+
+ override fun setBounds(left: Int, top: Int, right: Int, bottom: Int) =
+ setBlurBounds(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat())
+
+ fun setBlurBounds(left: Float, top: Float, right: Float, bottom: Float) {
+ if (blurBounds.left != left ||
+ blurBounds.top != top ||
+ blurBounds.right != right ||
+ blurBounds.bottom != bottom
+ ) {
+ blurBounds.set(left, top, right, bottom)
+ blurPathValid = false
+ }
+ }
+
+ override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
+
+ override fun onWallpaperChanged() {
+ invalidateSelf()
+ }
+
+ override fun setColorFilter(colorFilter: ColorFilter?) {
+ }
+
+ fun startListening() = blurWallpaperProvider.addListener(this)
+
+ fun stopListening() = blurWallpaperProvider.removeListener(this)
+}
\ No newline at end of file
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/blur/WallpaperFilter.kt b/app/src/main/java/foundation/e/blisslauncher/core/blur/WallpaperFilter.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c85321ed76fbc85c543ef392945c6c34e189a6a6
--- /dev/null
+++ b/app/src/main/java/foundation/e/blisslauncher/core/blur/WallpaperFilter.kt
@@ -0,0 +1,57 @@
+package foundation.e.blisslauncher.core.blur
+
+import android.graphics.Bitmap
+
+interface WallpaperFilter {
+
+ fun apply(wallpaper: Bitmap): ApplyTask
+
+ class ApplyTask {
+
+ val emitter = Emitter()
+
+ private var result: Bitmap? = null
+ private var error: Throwable? = null
+
+ private var callback: ((Bitmap?, Throwable?) -> Unit)? = null
+
+ fun setCallback(callback: (Bitmap?, Throwable?) -> Unit): ApplyTask {
+ result?.let {
+ callback(it, null)
+ return this
+ }
+ error?.let {
+ callback(null, it)
+ return this
+ }
+ this.callback = callback
+ return this
+ }
+
+ inner class Emitter {
+
+ fun onSuccess(result: Bitmap) {
+ callback?.let {
+ it(result, null)
+ return
+ }
+ this@ApplyTask.result = result
+ }
+
+ fun onError(error: Throwable) {
+ callback?.let {
+ it(null, error)
+ return
+ }
+ this@ApplyTask.error = error
+ }
+ }
+
+ companion object {
+
+ inline fun create(source: (Emitter) -> Unit): ApplyTask {
+ return ApplyTask().also { source(it.emitter) }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/broadcast/WallpaperChangeReceiver.java b/app/src/main/java/foundation/e/blisslauncher/core/broadcast/WallpaperChangeReceiver.java
new file mode 100644
index 0000000000000000000000000000000000000000..45bebbc83ff6f888b58430c40ac9b81387160260
--- /dev/null
+++ b/app/src/main/java/foundation/e/blisslauncher/core/broadcast/WallpaperChangeReceiver.java
@@ -0,0 +1,50 @@
+package foundation.e.blisslauncher.core.broadcast;
+
+import android.app.WallpaperManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.IBinder;
+import android.view.View;
+
+import foundation.e.blisslauncher.core.blur.BlurWallpaperProvider;
+
+import static android.content.Context.WALLPAPER_SERVICE;
+
+public class WallpaperChangeReceiver extends BroadcastReceiver {
+ private final Context mContext;
+ private IBinder mWindowToken;
+ private boolean mRegistered;
+ private View mWorkspace;
+
+ public WallpaperChangeReceiver(View workspace){
+ this.mWorkspace = workspace;
+ this.mContext = mWorkspace.getContext();
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ BlurWallpaperProvider.Companion.getInstance(context).updateAsync();
+ updateOffset();
+ }
+
+ public void setWindowToken(IBinder token) {
+ mWindowToken = token;
+ if (mWindowToken == null && mRegistered) {
+ mWorkspace.getContext().unregisterReceiver(this);
+ mRegistered = false;
+ } else if (mWindowToken != null && !mRegistered) {
+ mWorkspace.getContext()
+ .registerReceiver(this, new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED));
+ onReceive(mWorkspace.getContext(), null);
+ mRegistered = true;
+ }
+ }
+
+ private void updateOffset() {
+ WallpaperManager wm = (WallpaperManager) mContext.getSystemService(WALLPAPER_SERVICE);
+ wm.setWallpaperOffsets(mWindowToken, 0f, 0.5f);
+ wm.setWallpaperOffsetSteps(0.0f, 0.0f);
+ }
+}
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissFrameLayout.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissFrameLayout.java
index d52bae8cc1e12b4deddbf2da72063678df535e1d..8f6f8d0d928b87c2c647f1a9c1a09b985c2d8c69 100755
--- a/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissFrameLayout.java
+++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissFrameLayout.java
@@ -34,7 +34,6 @@ import foundation.e.blisslauncher.features.notification.DotRenderer;
public class BlissFrameLayout extends FrameLayout {
- private static final String TAG = "BlissFrameLayout";
private final Context mContext;
private boolean hasBadge = false;
@@ -66,16 +65,15 @@ public class BlissFrameLayout extends FrameLayout {
}
public BlissFrameLayout(Context context,
- AttributeSet attrs) {
+ AttributeSet attrs) {
this(context, attrs, 0);
}
public BlissFrameLayout(Context context, AttributeSet attrs,
- int defStyleAttr) {
+ int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
init();
-
}
private void init() {
@@ -86,8 +84,8 @@ public class BlissFrameLayout extends FrameLayout {
}
@Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
}
@Override
@@ -148,7 +146,7 @@ public class BlissFrameLayout extends FrameLayout {
bindApplicationItem((ApplicationItem) launcherItem);
} else if (launcherItem.itemType == Constants.ITEM_TYPE_SHORTCUT) {
bindShortcutItem((ShortcutItem) launcherItem);
- }else if(launcherItem.itemType == Constants.ITEM_TYPE_FOLDER){
+ } else if (launcherItem.itemType == Constants.ITEM_TYPE_FOLDER) {
bindFolderItem((FolderItem) launcherItem);
}
}
@@ -253,6 +251,4 @@ public class BlissFrameLayout extends FrameLayout {
tags.add(applicationItem);
setTag(tags);
}
-
-
}
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissInput.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissInput.java
index 45b4b3c84b47a695643739ee460619f157066199..fe7368df99ff6b3d7c2f7713e194afe5f4590cde 100755
--- a/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissInput.java
+++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissInput.java
@@ -17,7 +17,6 @@ public class BlissInput extends android.support.v7.widget.AppCompatEditText {
super(context, attrs, defStyleAttr);
}
-
@Override
public boolean onDragEvent(DragEvent event) {
// Without this drag/drop apps won't work on API <24.
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlurBackgroundView.kt b/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlurBackgroundView.kt
new file mode 100644
index 0000000000000000000000000000000000000000..717aa39754749f86286a3c340196c6b92ba9d176
--- /dev/null
+++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlurBackgroundView.kt
@@ -0,0 +1,80 @@
+package foundation.e.blisslauncher.core.customviews
+
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.drawable.Drawable
+import android.util.AttributeSet
+import android.view.View
+import android.view.WindowInsets
+import foundation.e.blisslauncher.core.blur.BlurWallpaperProvider
+import foundation.e.blisslauncher.core.blur.ShaderBlurDrawable
+import foundation.e.blisslauncher.core.runOnMainThread
+
+class BlurBackgroundView(context: Context, attrs: AttributeSet?) : View(context, attrs), Insettable,
+ BlurWallpaperProvider.Listener {
+
+ private val blurWallpaperProvider by lazy { BlurWallpaperProvider.getInstance(context) }
+
+ private var fullBlurDrawable: ShaderBlurDrawable? = null
+ private var blurAlpha = 255
+
+ private val blurDrawableCallback by lazy {
+ object : Drawable.Callback {
+ override fun unscheduleDrawable(who: Drawable?, what: Runnable?) {
+ }
+
+ override fun invalidateDrawable(who: Drawable?) {
+ runOnMainThread { invalidate() }
+ }
+
+ override fun scheduleDrawable(who: Drawable?, what: Runnable?, `when`: Long) {
+ }
+ }
+ }
+
+ init {
+ createFullBlurDrawable()
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+
+ BlurWallpaperProvider.getInstance(context).addListener(this)
+ fullBlurDrawable?.startListening()
+ }
+
+ override fun onDetachedFromWindow() {
+ super.onDetachedFromWindow()
+
+ BlurWallpaperProvider.getInstance(context).removeListener(this)
+ fullBlurDrawable?.stopListening()
+ }
+
+ override fun onDraw(canvas: Canvas) {
+ fullBlurDrawable?.apply {
+ alpha = blurAlpha
+ this.draw(canvas)
+ }
+ }
+
+ override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
+ if (changed) {
+ fullBlurDrawable?.setBounds(left, top, right, bottom)
+ }
+ }
+
+ private fun createFullBlurDrawable() {
+ fullBlurDrawable?.let { if (isAttachedToWindow) it.stopListening() }
+ fullBlurDrawable = blurWallpaperProvider.createDrawable().apply {
+ callback = blurDrawableCallback
+ setBounds(left, top, right, bottom)
+ if (isAttachedToWindow) startListening()
+ }
+ }
+
+ override fun onEnabledChanged() {
+ createFullBlurDrawable()
+ }
+
+ override fun setInsets(insets: WindowInsets) {}
+}
\ No newline at end of file
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/DockGridLayout.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/DockGridLayout.java
index 069312688447756a6d1f70c3ce29a7e9a3c0aa38..126079e484c7e274e09b0592e7127dba2a904375 100755
--- a/app/src/main/java/foundation/e/blisslauncher/core/customviews/DockGridLayout.java
+++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/DockGridLayout.java
@@ -1,16 +1,47 @@
package foundation.e.blisslauncher.core.customviews;
import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
import android.util.AttributeSet;
+import android.view.WindowInsets;
import android.widget.GridLayout;
import foundation.e.blisslauncher.BlissLauncher;
import foundation.e.blisslauncher.core.DeviceProfile;
+import foundation.e.blisslauncher.core.KotlinUtilsKt;
+import foundation.e.blisslauncher.core.blur.BlurWallpaperProvider;
+import foundation.e.blisslauncher.core.blur.ShaderBlurDrawable;
-public class DockGridLayout extends GridLayout {
+public class DockGridLayout extends GridLayout implements Insettable, BlurWallpaperProvider.Listener {
private Context mContext;
+ private final BlurWallpaperProvider blurWallpaperProvider;
+ private ShaderBlurDrawable fullBlurDrawable = null;
+ private int blurAlpha = 255;
+
+ private final Drawable.Callback blurDrawableCallback = new Drawable.Callback() {
+ @Override
+ public void invalidateDrawable(@NonNull Drawable who) {
+ KotlinUtilsKt.runOnMainThread(() -> {
+ invalidate();
+ return null;
+ });
+ }
+
+ @Override
+ public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
+
+ }
+
+ @Override
+ public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
+
+ }
+ };
+
public DockGridLayout(Context context) {
this(context, null);
}
@@ -22,15 +53,68 @@ public class DockGridLayout extends GridLayout {
public DockGridLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
+ setWillNotDraw(false);
+ blurWallpaperProvider = BlurWallpaperProvider.Companion.getInstance(context);
+ createBlurDrawable();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ BlurWallpaperProvider.Companion.getInstance(mContext).addListener(this);
+ fullBlurDrawable.startListening();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ BlurWallpaperProvider.Companion.getInstance(mContext).removeListener(this);
+ fullBlurDrawable.stopListening();
}
@Override
- protected void onMeasure(int widthSpec, int heightSpec) {
- super.onMeasure(widthSpec, heightSpec);
+ protected void onDraw(Canvas canvas) {
+ fullBlurDrawable.setAlpha(blurAlpha);
+ fullBlurDrawable.draw(canvas);
+ super.onDraw(canvas);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ if (changed) {
+ fullBlurDrawable.setBounds(left, top, right, bottom);
+ }
+ }
+
+ @Override
+ public void setInsets(WindowInsets insets) {
DeviceProfile deviceProfile = BlissLauncher.getApplication(mContext).getDeviceProfile();
- setMeasuredDimension(deviceProfile.getAvailableWidthPx(),
- deviceProfile.hotseatCellHeightPx);
- this.setPadding(deviceProfile.iconDrawablePaddingPx / 2, 0,
- deviceProfile.iconDrawablePaddingPx / 2, 0);
+ InsettableRelativeLayout.LayoutParams lp = (InsettableRelativeLayout.LayoutParams) getLayoutParams();
+ lp.height = deviceProfile.hotseatCellHeightPx + insets.getSystemWindowInsetBottom();
+ setPadding(deviceProfile.iconDrawablePaddingPx / 2, 0,
+ deviceProfile.iconDrawablePaddingPx / 2, insets.getSystemWindowInsetBottom());
+ setLayoutParams(lp);
+ }
+
+ private void createBlurDrawable() {
+ if (isAttachedToWindow()) {
+ fullBlurDrawable.stopListening();
+ }
+ fullBlurDrawable = blurWallpaperProvider.createDrawable();
+ fullBlurDrawable.setCallback(blurDrawableCallback);
+ fullBlurDrawable.setBounds(getLeft(), getTop(), getRight(), getBottom());
+ if (isAttachedToWindow()) fullBlurDrawable.startListening();
+ }
+
+ @Override
+ public void onEnabledChanged() {
+ createBlurDrawable();
+ }
+
+ @Override
+ public void onWallpaperChanged() {
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/HorizontalPager.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/HorizontalPager.java
index 05b11708a8c478af3e6e85900937952f00b0cd71..c2d52ccfca6f0df6dcbffab0c923e50edf5c62e0 100755
--- a/app/src/main/java/foundation/e/blisslauncher/core/customviews/HorizontalPager.java
+++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/HorizontalPager.java
@@ -16,6 +16,7 @@ import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
+import android.view.WindowInsets;
import android.widget.Scroller;
import java.util.ArrayList;
@@ -27,7 +28,7 @@ import foundation.e.blisslauncher.features.launcher.DetectSwipeGestureListener;
import foundation.e.blisslauncher.features.launcher.LauncherActivity;
import foundation.e.blisslauncher.features.launcher.OnSwipeDownListener;
-public class HorizontalPager extends ViewGroup {
+public class HorizontalPager extends ViewGroup implements Insettable{
private static final String TAG = "HorizontalPager";
private static final int INVALID_SCREEN = -1;
public static final int SPEC_UNDEFINED = -1;
@@ -61,6 +62,7 @@ public class HorizontalPager extends ViewGroup {
private Set mListeners = new HashSet<>();
private boolean mIsUiCreated;
private GestureDetectorCompat gestureDetectorCompat;
+ private WindowInsets insets;
public HorizontalPager(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -147,6 +149,7 @@ public class HorizontalPager extends ViewGroup {
@Override
protected void dispatchDraw(Canvas canvas) {
+ Log.d(TAG, "dispatchDraw() called with: canvas = [" + canvas + "]");
final long drawingTime = getDrawingTime();
// todo be smarter about which children need drawing
final int count = getChildCount();
@@ -156,9 +159,10 @@ public class HorizontalPager extends ViewGroup {
for (OnScrollListener mListener : mListeners) {
int adjustedScrollX = getScrollX() + pageWidthPadding();
- mListener.onScroll(adjustedScrollX);
if (adjustedScrollX % pageWidth == 0) {
mListener.onViewScrollFinished(adjustedScrollX / pageWidth);
+ } else {
+ mListener.onScroll(adjustedScrollX);
}
}
}
@@ -528,6 +532,26 @@ public class HorizontalPager extends ViewGroup {
return mAllowLongPress;
}
+ @Override
+ public void setInsets(WindowInsets insets) {
+ InsettableRelativeLayout.LayoutParams lp = (InsettableRelativeLayout.LayoutParams) getLayoutParams();
+ lp.topMargin = insets.getSystemWindowInsetTop();
+ setLayoutParams(lp);
+ updateInsetsForChildren();
+ this.insets = insets;
+ }
+
+ private void updateInsetsForChildren() {
+ int childCount = getChildCount();
+ for (int index = 0; index < childCount; ++index){
+ View child = getChildAt(index);
+ if(child instanceof Insettable) {
+ Log.d(TAG, "child is instance of insettable");
+ ((Insettable) child).setInsets(insets);
+ }
+ }
+ }
+
public static class SavedState extends BaseSavedState {
int currentScreen = -1;
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/Insettable.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/Insettable.java
new file mode 100644
index 0000000000000000000000000000000000000000..91d686b7790e94b225a93e681041a9443139a4e5
--- /dev/null
+++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/Insettable.java
@@ -0,0 +1,13 @@
+package foundation.e.blisslauncher.core.customviews;
+
+import android.view.View;
+import android.view.WindowInsets;
+
+/**
+ * Allows the implementing {@link View} to not draw underneath system bars.
+ * e.g., notification bar on top and home key area on the bottom.
+ */
+public interface Insettable {
+
+ void setInsets(WindowInsets insets);
+}
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/InsettableRelativeLayout.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/InsettableRelativeLayout.java
new file mode 100644
index 0000000000000000000000000000000000000000..9342c9143f8c16826e978be76a9d40c4a7dac36f
--- /dev/null
+++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/InsettableRelativeLayout.java
@@ -0,0 +1,87 @@
+package foundation.e.blisslauncher.core.customviews;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowInsets;
+import android.widget.RelativeLayout;
+
+import foundation.e.blisslauncher.R;
+
+public class InsettableRelativeLayout extends RelativeLayout {
+
+ protected WindowInsets mInsets;
+
+
+ public InsettableRelativeLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+ updateChildInsets(insets);
+ mInsets = new WindowInsets(insets);
+ return insets;
+ }
+
+ private void updateChildInsets(WindowInsets insets) {
+ if(insets == null) return;
+ int childCount = getChildCount();
+ for (int index = 0; index < childCount; ++index){
+ View child = getChildAt(index);
+ if(child instanceof Insettable) {
+ ((Insettable) child).setInsets(insets);
+ }
+ }
+ }
+
+ @Override
+ public LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new InsettableRelativeLayout.LayoutParams(getContext(), attrs);
+ }
+
+ @Override
+ protected LayoutParams generateDefaultLayoutParams() {
+ return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ }
+
+ // Override to allow type-checking of LayoutParams.
+ @Override
+ protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+ return p instanceof InsettableRelativeLayout.LayoutParams;
+ }
+
+ @Override
+ protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+ return new LayoutParams(p);
+ }
+
+ public static class LayoutParams extends RelativeLayout.LayoutParams {
+ public boolean ignoreInsets = false;
+
+ public LayoutParams(Context c, AttributeSet attrs) {
+ super(c, attrs);
+ TypedArray a = c.obtainStyledAttributes(attrs,
+ R.styleable.InsettableFrameLayout_Layout);
+ ignoreInsets = a.getBoolean(
+ R.styleable.InsettableFrameLayout_Layout_layout_ignoreInsets, false);
+ a.recycle();
+ }
+
+ public LayoutParams(int width, int height) {
+ super(width, height);
+ }
+
+ public LayoutParams(ViewGroup.LayoutParams lp) {
+ super(lp);
+ }
+ }
+
+ @Override
+ public void onViewAdded(View child) {
+ super.onViewAdded(child);
+ updateChildInsets(mInsets);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/InsettableScrollLayout.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/InsettableScrollLayout.java
new file mode 100644
index 0000000000000000000000000000000000000000..438e4b29c9027a5a6fd99321a553e6023896f545
--- /dev/null
+++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/InsettableScrollLayout.java
@@ -0,0 +1,32 @@
+package foundation.e.blisslauncher.core.customviews;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.view.WindowInsets;
+import android.widget.ScrollView;
+
+public class InsettableScrollLayout extends ScrollView implements Insettable {
+
+ public InsettableScrollLayout(@NonNull Context context) {
+ super(context);
+ }
+
+ public InsettableScrollLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public InsettableScrollLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ public void setInsets(WindowInsets insets) {
+ int top = getPaddingTop();
+ int left = getPaddingLeft();
+ int right = getPaddingRight();
+ int bottom = getPaddingBottom();
+ setPadding(left, top, right, bottom + insets.getSystemWindowInsetBottom());
+ }
+}
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareFrameLayout.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareFrameLayout.java
index 85cca4514a3d3c956147a5e388b51dd8a3f67285..6d6ac74198d6275a8013f0824aaed6ccd200749f 100755
--- a/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareFrameLayout.java
+++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareFrameLayout.java
@@ -11,18 +11,20 @@ import android.widget.FrameLayout;
*/
public class SquareFrameLayout extends FrameLayout {
+
public SquareFrameLayout(@NonNull Context context) {
- super(context);
+ this(context, null);
}
public SquareFrameLayout(@NonNull Context context,
@Nullable AttributeSet attrs) {
- super(context, attrs);
+ this(context, attrs, 0);
}
public SquareFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ setWillNotDraw(false);
}
@Override
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareImageView.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareImageView.java
index ef576dcb26563efca0a4263c8551b427da550cac..a13a834178b5f8fcae38fbad9eb90d72d38adaac 100755
--- a/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareImageView.java
+++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareImageView.java
@@ -9,28 +9,20 @@ import android.util.AttributeSet;
public class SquareImageView extends android.support.v7.widget.AppCompatImageView {
-
public SquareImageView(Context context) {
- super(context);
- }
-
- public SquareImageView(Context context, AttributeSet attrs) {
- super(context, attrs);
+ this(context, null);
}
- public SquareImageView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
+ public SquareImageView(Context context, AttributeSet attributeSet) {
+ super(context, attributeSet);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
int width = getMeasuredWidth();
int height = getMeasuredHeight();
int size = width < height ? width : height;
setMeasuredDimension(size, size);
}
-
-
}
\ No newline at end of file
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/executors/MainThreadExecutor.java b/app/src/main/java/foundation/e/blisslauncher/core/executors/MainThreadExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..367db09fb02ce557b50b68bc88a760fb47a77a07
--- /dev/null
+++ b/app/src/main/java/foundation/e/blisslauncher/core/executors/MainThreadExecutor.java
@@ -0,0 +1,52 @@
+package foundation.e.blisslauncher.core.executors;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.NonNull;
+
+import java.util.List;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.TimeUnit;
+
+public class MainThreadExecutor extends AbstractExecutorService {
+
+ private final Handler mHandler;
+
+ public MainThreadExecutor() {
+ mHandler = new Handler(Looper.getMainLooper());
+ }
+ @Override
+ public void shutdown() {
+ throw new UnsupportedOperationException();
+ }
+
+ @NonNull
+ @Override
+ public List shutdownNow() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isShutdown() {
+ return false;
+ }
+
+ @Override
+ public boolean isTerminated() {
+ return false;
+ }
+
+ @Override
+ public boolean awaitTermination(long timeout, @NonNull TimeUnit unit) throws InterruptedException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void execute(@NonNull Runnable runnable) {
+ if (mHandler.getLooper() == Looper.myLooper()) {
+ runnable.run();
+ } else {
+ mHandler.post(runnable);
+ }
+ }
+}
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/utils/GraphicsUtil.java b/app/src/main/java/foundation/e/blisslauncher/core/utils/GraphicsUtil.java
index 5beeee8546bb7151d0e56ec11b20a5bdfee429cb..5fc02caba4fdd5d5dc108fdcd244f6a42a6df8f4 100755
--- a/app/src/main/java/foundation/e/blisslauncher/core/utils/GraphicsUtil.java
+++ b/app/src/main/java/foundation/e/blisslauncher/core/utils/GraphicsUtil.java
@@ -130,7 +130,7 @@ public class GraphicsUtil {
Bitmap mergedBitmap = Bitmap.createBitmap(width, height, Bitmap
.Config.ARGB_8888);
Canvas canvas = new Canvas(mergedBitmap);
- canvas.drawColor(isFolder ? Color.WHITE : getDominantColor(bitmap));
+ canvas.drawColor(isFolder ? 0x88D3D3D3 : getDominantColor(bitmap));
Paint paint = new Paint(
Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
diff --git a/app/src/main/java/foundation/e/blisslauncher/core/utils/SingletonHolder.kt b/app/src/main/java/foundation/e/blisslauncher/core/utils/SingletonHolder.kt
new file mode 100644
index 0000000000000000000000000000000000000000..7a9b470ab958b1997e25e6a3023453a048388749
--- /dev/null
+++ b/app/src/main/java/foundation/e/blisslauncher/core/utils/SingletonHolder.kt
@@ -0,0 +1,55 @@
+package foundation.e.blisslauncher.core.utils
+
+import android.content.Context
+import android.os.Looper
+import foundation.e.blisslauncher.core.executors.MainThreadExecutor
+import java.util.concurrent.Callable
+import java.util.concurrent.ExecutionException
+
+open class SingletonHolder(creator: (A) -> T) {
+ private var creator: ((A) -> T)? = creator
+ @Volatile
+ private var instance: T? = null
+
+ open fun getInstance(arg: A): T {
+ val i = instance
+ if (i != null) {
+ return i
+ }
+
+ return synchronized(this) {
+ val i2 = instance
+ if (i2 != null) {
+ i2
+ } else {
+ val created = creator!!(arg)
+ instance = created
+ creator = null
+ created
+ }
+ }
+ }
+
+ protected fun dangerousGetInstance() = instance
+}
+
+
+fun ensureOnMainThread(creator: (A) -> T): (A) -> T {
+ return { it ->
+ if (Looper.myLooper() == Looper.getMainLooper()) {
+ creator(it)
+ } else {
+ try {
+ MainThreadExecutor().submit(Callable { creator(it) }).get()
+ } catch (e: InterruptedException) {
+ throw RuntimeException(e)
+ } catch (e: ExecutionException) {
+ throw RuntimeException(e)
+ }
+
+ }
+ }
+}
+fun useApplicationContext(creator: (Context) -> T): (Context) -> T {
+ return { it -> creator(it.applicationContext) }
+}
\ No newline at end of file
diff --git a/app/src/main/java/foundation/e/blisslauncher/features/launcher/AppProvider.java b/app/src/main/java/foundation/e/blisslauncher/features/launcher/AppProvider.java
index 854839cd4b5a1be2e3e043a1429434a33efe8aa3..fe221fcab4628c7a6dda0201d2e680856a205236 100644
--- a/app/src/main/java/foundation/e/blisslauncher/features/launcher/AppProvider.java
+++ b/app/src/main/java/foundation/e/blisslauncher/features/launcher/AppProvider.java
@@ -297,28 +297,15 @@ public class AppProvider {
if (databaseItem.itemType == Constants.ITEM_TYPE_APPLICATION) {
ApplicationItem applicationItem = mApplicationItems.get(databaseItem.id);
if (applicationItem == null) {
- UserHandle userHandle = null;
- int index = databaseItem.id.lastIndexOf((int) '/');
- if (index > -1) {
- String serialText = databaseItem.id.substring(index);
- try {
- long serial = Long.parseLong(serialText);
- userHandle = new UserHandle(serial, Process.myUserHandle());
- } catch (NumberFormatException e) {
- e.printStackTrace();
- }
- }
- if(userHandle == null){
- userHandle = new UserHandle();
- }
+ UserHandle userHandle = new UserHandle();
if (isAppOnSdcard(databaseItem.packageName, userHandle) || !isSdCardReady) {
Log.d(TAG, "Missing package: " + databaseItem.packageName);
Log.d(TAG, "Is App on Sdcard " + isAppOnSdcard(databaseItem.packageName, databaseItem.user));
Log.d(TAG, "Is Sdcard ready " + isSdCardReady);
-
pendingPackages.addToList(userHandle, databaseItem.packageName);
applicationItem = new ApplicationItem();
+ applicationItem.id = databaseItem.id;
applicationItem.title = databaseItem.title;
applicationItem.user = userHandle;
applicationItem.componentName = databaseItem.getTargetComponent();
diff --git a/app/src/main/java/foundation/e/blisslauncher/features/launcher/LauncherActivity.java b/app/src/main/java/foundation/e/blisslauncher/features/launcher/LauncherActivity.java
index cf00c23cf96855aace279b39145e776d9fdf7d66..05786c476b15451f61163c7297bcb2085ba5188a 100755
--- a/app/src/main/java/foundation/e/blisslauncher/features/launcher/LauncherActivity.java
+++ b/app/src/main/java/foundation/e/blisslauncher/features/launcher/LauncherActivity.java
@@ -4,14 +4,13 @@ import android.Manifest;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
-import android.animation.ArgbEvaluator;
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.app.WallpaperManager;
import android.app.usage.UsageStats;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
@@ -19,11 +18,12 @@ import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
-import android.graphics.Color;
+import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -38,7 +38,7 @@ import android.os.StrictMode;
import android.os.UserManager;
import android.provider.Settings;
import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
+import android.support.v4.app.ActivityCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
@@ -48,16 +48,15 @@ import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
+import android.util.Log;
import android.view.DragEvent;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
-import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
@@ -66,7 +65,6 @@ import android.widget.GridLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
-import android.widget.ScrollView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
@@ -90,13 +88,17 @@ import foundation.e.blisslauncher.core.Alarm;
import foundation.e.blisslauncher.core.DeviceProfile;
import foundation.e.blisslauncher.core.Preferences;
import foundation.e.blisslauncher.core.Utilities;
+import foundation.e.blisslauncher.core.blur.BlurWallpaperProvider;
import foundation.e.blisslauncher.core.broadcast.ManagedProfileBroadcastReceiver;
import foundation.e.blisslauncher.core.broadcast.TimeChangeBroadcastReceiver;
+import foundation.e.blisslauncher.core.broadcast.WallpaperChangeReceiver;
import foundation.e.blisslauncher.core.customviews.BlissDragShadowBuilder;
import foundation.e.blisslauncher.core.customviews.BlissFrameLayout;
import foundation.e.blisslauncher.core.customviews.BlissInput;
import foundation.e.blisslauncher.core.customviews.DockGridLayout;
import foundation.e.blisslauncher.core.customviews.HorizontalPager;
+import foundation.e.blisslauncher.core.customviews.InsettableRelativeLayout;
+import foundation.e.blisslauncher.core.customviews.InsettableScrollLayout;
import foundation.e.blisslauncher.core.customviews.PageIndicatorLinearLayout;
import foundation.e.blisslauncher.core.customviews.RoundedWidgetView;
import foundation.e.blisslauncher.core.customviews.SquareFrameLayout;
@@ -149,12 +151,14 @@ import static android.view.View.GONE;
import static android.view.View.VISIBLE;
public class LauncherActivity extends AppCompatActivity implements
- AutoCompleteAdapter.OnSuggestionClickListener, OnSwipeDownListener {
+ AutoCompleteAdapter.OnSuggestionClickListener,
+ OnSwipeDownListener {
public static final int REORDER_TIMEOUT = 350;
private final static int EMPTY_LOCATION_DRAG = -999;
private static final int REQUEST_PERMISSION_CALL_PHONE = 14;
private static final int REQUEST_LOCATION_SOURCE_SETTING = 267;
+ private static final int STORAGE_PERMISSION_REQUEST_CODE = 586;
public static boolean longPressed;
private final Alarm mReorderAlarm = new Alarm();
private final Alarm mDockReorderAlarm = new Alarm();
@@ -198,8 +202,8 @@ public class LauncherActivity extends AppCompatActivity implements
private List mUsageStats;
private FrameLayout swipeSearchContainer;
- private RelativeLayout workspace;
- private View backgroundLayer;
+ private InsettableRelativeLayout workspace;
+ private View blurLayer; // Blur layer for folders and search container.
private BroadcastReceiver mWeatherReceiver = new BroadcastReceiver() {
@Override
@@ -212,14 +216,12 @@ public class LauncherActivity extends AppCompatActivity implements
private FolderItem activeFolder;
private BlissFrameLayout activeFolderView;
private int activeDot;
- private int statusBarHeight;
private static final String TAG = "LauncherActivity";
private AppWidgetManager mAppWidgetManager;
private WidgetHost mAppWidgetHost;
private LinearLayout widgetContainer;
- ArgbEvaluator argbEvaluator = new ArgbEvaluator();
private FrameLayout widgetsPage;
private SearchInputDisposableObserver searchDisposableObserver;
private AnimatorSet currentAnimator;
@@ -228,22 +230,25 @@ public class LauncherActivity extends AppCompatActivity implements
private float startScaleFinal;
private boolean showSwipeSearch;
private RoundedWidgetView activeRoundedWidgetView;
- private boolean widgetResizeContainerVisible;
// EventRelay to handle pass events related to app addition, deletion or changed.
private EventRelay events;
private ManagedProfileBroadcastReceiver managedProfileReceiver;
- private boolean forceReload;
- private AppProvider appProvider;
private int moveTo;
+ private WallpaperChangeReceiver wallpaperChangeReceiver;
+
+ public static LauncherActivity getLauncher(Context context) {
+ if (context instanceof LauncherActivity) {
+ return (LauncherActivity) context;
+ }
+ return ((LauncherActivity) ((ContextWrapper) context).getBaseContext());
+ }
@SuppressLint("InflateParams")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- appProvider = BlissLauncher.getApplication(this).getAppProvider();
-
prepareBroadcastReceivers();
mDeviceProfile = BlissLauncher.getApplication(this).getDeviceProfile();
@@ -253,9 +258,13 @@ public class LauncherActivity extends AppCompatActivity implements
mLauncherView = LayoutInflater.from(this).inflate(
foundation.e.blisslauncher.R.layout.activity_main, null);
+
setContentView(mLauncherView);
setupViews();
+ WallpaperManager wm = (WallpaperManager) getSystemService(WALLPAPER_SERVICE);
+ wm.suggestDesiredDimensions(mDeviceProfile.widthPx, mDeviceProfile.heightPx);
+
mProgressBar.setVisibility(View.VISIBLE);
if (Preferences.shouldAskForNotificationAccess(this)) {
@@ -282,6 +291,10 @@ public class LauncherActivity extends AppCompatActivity implements
}
}
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE);
+ }
+
// Start NotificationService to add count badge to Icons
Intent notificationServiceIntent = new Intent(this, NotificationService.class);
startService(notificationServiceIntent);
@@ -291,13 +304,21 @@ public class LauncherActivity extends AppCompatActivity implements
private void setupViews() {
workspace = mLauncherView.findViewById(R.id.workspace);
+ wallpaperChangeReceiver = new WallpaperChangeReceiver(workspace);
+ workspace.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ wallpaperChangeReceiver.setWindowToken(v.getWindowToken());
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ wallpaperChangeReceiver.setWindowToken(null);
+ }
+ });
mHorizontalPager = mLauncherView.findViewById(R.id.pages_container);
- backgroundLayer = mLauncherView.findViewById(R.id.background_layer);
- statusBarHeight = 0;
- int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
- if (resourceId > 0) {
- statusBarHeight = getResources().getDimensionPixelSize(resourceId);
- }
+ blurLayer = mLauncherView.findViewById(R.id.blur_layer);
+ blurLayer.setAlpha(0f);
mDock = mLauncherView.findViewById(R.id.dock);
mIndicator = mLauncherView.findViewById(R.id.page_indicator);
@@ -314,7 +335,8 @@ public class LauncherActivity extends AppCompatActivity implements
wobbleAnimation = AnimationUtils.loadAnimation(this, R.anim.wobble);
wobbleReverseAnimation = AnimationUtils.loadAnimation(this, R.anim.wobble_reverse);
getWindow().getDecorView().setSystemUiVisibility(
- View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
workspace.setOnClickListener(v -> {
if (swipeSearchContainer.getVisibility() == VISIBLE) {
@@ -1039,7 +1061,7 @@ public class LauncherActivity extends AppCompatActivity implements
return false;
});
mFolderTitleInput.setOnClickListener(view -> mFolderTitleInput.setCursorVisible(true));
- mFolderWindowContainer.setOnClickListener(view -> hideFolderWindowContainer());
+ mFolderWindowContainer.setOnClickListener(view -> returnToHomeScreen());
}
public void hideKeyboard(View view) {
@@ -1070,8 +1092,6 @@ public class LauncherActivity extends AppCompatActivity implements
* updated
*/
private void createPageChangeListener() {
- Integer color1 = Color.TRANSPARENT;
- Integer color2 = ContextCompat.getColor(this, R.color.dark_grey_44);
mHorizontalPager.addOnScrollListener(new HorizontalPager.OnScrollListener() {
boolean isViewScrolling = true;
@@ -1080,8 +1100,8 @@ public class LauncherActivity extends AppCompatActivity implements
if (scrollX >= 0 && scrollX < mDeviceProfile.availableWidthPx) {
float fraction = (float) (mDeviceProfile.availableWidthPx - scrollX)
/ mDeviceProfile.availableWidthPx;
- mHorizontalPager.setBackgroundColor(
- (Integer) argbEvaluator.evaluate(fraction, color1, color2));
+ int radius = (int) (fraction * 18);
+ blurLayer.setAlpha(fraction);
}
if (isViewScrolling) {
dragDropEnabled = false;
@@ -1090,11 +1110,11 @@ public class LauncherActivity extends AppCompatActivity implements
@Override
public void onViewScrollFinished(int page) {
- mHorizontalPager.setBackgroundColor(page == 0 ? color2 : color1);
isViewScrolling = false;
- if (currentPageNumber != page) {
+ blurLayer.setAlpha((page == 0 || mFolderWindowContainer.getVisibility() == VISIBLE) ? 1f : 0f);
+ if (currentPageNumber != page) {
currentPageNumber = page;
// Remove mIndicator and mDock from widgets page, and make them
// reappear when user swipes to the first apps page
@@ -1218,7 +1238,7 @@ public class LauncherActivity extends AppCompatActivity implements
grid.setRowCount(mDeviceProfile.numRows);
grid.setLayoutTransition(getDefaultLayoutTransition());
grid.setPadding(mDeviceProfile.iconDrawablePaddingPx / 2,
- (int) (statusBarHeight + Utilities.pxFromDp(8, this)),
+ (int) (Utilities.pxFromDp(8, this)),
mDeviceProfile.iconDrawablePaddingPx / 2, 0);
return grid;
}
@@ -1227,12 +1247,12 @@ public class LauncherActivity extends AppCompatActivity implements
widgetsPage = (FrameLayout) getLayoutInflater().inflate(R.layout.widgets_page,
mHorizontalPager, false);
widgetContainer = widgetsPage.findViewById(R.id.widget_container);
- widgetsPage.setPadding(0,
- (int) (statusBarHeight + Utilities.pxFromDp(8, this)),
- 0, 0);
+ /*widgetsPage.setPadding(0,
+ (int) (Utilities.pxFromDp(8, this)),
+ 0, 0);*/
mHorizontalPager.addView(widgetsPage, 0);
widgetsPage.setOnDragListener(null);
- ScrollView scrollView = widgetsPage.findViewById(R.id.widgets_scroll_container);
+ InsettableScrollLayout scrollView = widgetsPage.findViewById(R.id.widgets_scroll_container);
scrollView.setOnTouchListener((v, event) -> {
if (widgetsPage.findViewById(R.id.widget_resizer_container).getVisibility()
== VISIBLE) {
@@ -1240,6 +1260,7 @@ public class LauncherActivity extends AppCompatActivity implements
}
return false;
});
+ scrollView.post(() -> scrollView.setInsets(workspace.getRootWindowInsets()));
currentPageNumber = 1;
mHorizontalPager.setCurrentPage(currentPageNumber);
@@ -1426,6 +1447,12 @@ public class LauncherActivity extends AppCompatActivity implements
.setAction(WeatherUpdateService.ACTION_FORCE_UPDATE));
}
}
+ } else if (requestCode == STORAGE_PERMISSION_REQUEST_CODE) {
+ if (grantResults.length > 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ Log.d(TAG, "Storage permission granted");
+ BlurWallpaperProvider.Companion.getInstance(getApplicationContext()).updateAsync();
+ }
}
}
@@ -2723,46 +2750,57 @@ public class LauncherActivity extends AppCompatActivity implements
startBounds.bottom += deltaHeight;
}
- mFolderWindowContainer.setVisibility(View.VISIBLE);
-
- // Set the pivot point for SCALE_X and SCALE_Y transformations
- // to the top-left corner of the zoomed-in view (the default
- // is the center of the view).
- mFolderWindowContainer.setPivotX(0f);
- mFolderWindowContainer.setPivotY(0f);
-
// Construct and run the parallel animation of the four translation and
// scale properties (X, Y, SCALE_X, and SCALE_Y).
AnimatorSet set = new AnimatorSet();
- ValueAnimator valueAnimator = ValueAnimator.ofArgb(Color.parseColor("#00000000"),
- Color.parseColor("#44000000"));
- valueAnimator.addUpdateListener(animation -> backgroundLayer.setBackgroundColor(
- (Integer) animation.getAnimatedValue()));
- set
- .play(ObjectAnimator.ofFloat(mFolderWindowContainer, View.X,
- startBounds.left, finalBounds.left))
+ /*ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 18);
+ valueAnimator.addUpdateListener(animation ->
+ BlurWallpaperProvider.getInstance(this).blur((Integer) animation.getAnimatedValue()));*/
+ set.play(ObjectAnimator.ofFloat(mFolderWindowContainer, View.X,
+ startBounds.left, finalBounds.left))
.with(ObjectAnimator.ofFloat(mFolderWindowContainer, View.Y,
startBounds.top, finalBounds.top))
.with(ObjectAnimator.ofFloat(mFolderWindowContainer, View.SCALE_X,
startScale, 1f))
.with(ObjectAnimator.ofFloat(mFolderWindowContainer,
View.SCALE_Y, startScale, 1f))
- .with(ObjectAnimator.ofFloat(backgroundLayer, View.ALPHA, 0f, 1f))
- .with(ObjectAnimator.ofFloat(mHorizontalPager, View.ALPHA, 1f, 0f))
- .with(ObjectAnimator.ofFloat(mIndicator, View.ALPHA, 1f, 0f))
- .with(ObjectAnimator.ofFloat(mDock, View.ALPHA, 1f, 0f));
-
+ .with(ObjectAnimator.ofFloat(blurLayer, View.ALPHA, 1f))
+ .with(ObjectAnimator.ofFloat(mHorizontalPager, View.ALPHA, 0f))
+ .with(ObjectAnimator.ofFloat(mIndicator, View.ALPHA, 0f))
+ .with(ObjectAnimator.ofFloat(mDock, View.ALPHA, 0f));
set.setDuration(300);
- set.setInterpolator(new DecelerateInterpolator());
+ set.setInterpolator(new LinearInterpolator());
set.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ mFolderWindowContainer.setVisibility(View.VISIBLE);
+
+ // Set the pivot point for SCALE_X and SCALE_Y transformations
+ // to the top-left corner of the zoomed-in view (the default
+ // is the center of the view).
+ mFolderWindowContainer.setPivotX(0f);
+ mFolderWindowContainer.setPivotY(0f);
+ //BlurWallpaperProvider.getInstance(LauncherActivity.this).clear();
+ }
+
@Override
public void onAnimationEnd(Animator animation) {
currentAnimator = null;
+ blurLayer.setAlpha(1f);
+ mHorizontalPager.setAlpha(0f);
+ mIndicator.setAlpha(0f);
+ mDock.setAlpha(0f);
}
@Override
public void onAnimationCancel(Animator animation) {
currentAnimator = null;
+ mFolderWindowContainer.setVisibility(GONE);
+ blurLayer.setAlpha(0f);
+ mHorizontalPager.setAlpha(1f);
+ mIndicator.setAlpha(1f);
+ mDock.setAlpha(1f);
}
});
set.start();
@@ -2782,6 +2820,15 @@ public class LauncherActivity extends AppCompatActivity implements
}
+ private Bitmap getLauncherView() {
+ View view = getWindow().getDecorView().getRootView();
+ view.setDrawingCacheEnabled(true);
+ view.buildDrawingCache(true);
+ Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
+ view.setDrawingCacheEnabled(false);
+ return bitmap;
+ }
+
/**
* Hides folder window with an animation
*/
@@ -2796,10 +2843,9 @@ public class LauncherActivity extends AppCompatActivity implements
// Animate the four positioning/sizing properties in parallel,
// back to their original values.
AnimatorSet set = new AnimatorSet();
- ValueAnimator valueAnimator = ValueAnimator.ofArgb(Color.parseColor("#44000000"),
- Color.parseColor("#00000000"));
- valueAnimator.addUpdateListener(animation -> mFolderWindowContainer.setBackgroundColor(
- (Integer) animation.getAnimatedValue()));
+ /*ValueAnimator valueAnimator = ValueAnimator.ofInt(18, 0);
+ valueAnimator.addUpdateListener(animation ->
+ BlurWallpaperProvider.getInstance(this).blurWithLauncherView(mergedView, (Integer) animation.getAnimatedValue()));*/
set.play(ObjectAnimator
.ofFloat(mFolderWindowContainer, View.X, startBounds.left))
.with(ObjectAnimator
@@ -2811,23 +2857,40 @@ public class LauncherActivity extends AppCompatActivity implements
.with(ObjectAnimator
.ofFloat(mFolderWindowContainer,
View.SCALE_Y, startScaleFinal))
- .with(ObjectAnimator.ofFloat(backgroundLayer, View.ALPHA, 1f, 0f))
- .with(ObjectAnimator.ofFloat(mHorizontalPager, View.ALPHA, 0f, 1f))
- .with(ObjectAnimator.ofFloat(mIndicator, View.ALPHA, 0f, 1f))
- .with(ObjectAnimator.ofFloat(mDock, View.ALPHA, 0f, 1f));
+ .with(ObjectAnimator.ofFloat(blurLayer, View.ALPHA, 0f))
+ .with(ObjectAnimator.ofFloat(mHorizontalPager, View.ALPHA, 1f))
+ .with(ObjectAnimator.ofFloat(mIndicator, View.ALPHA, 1f))
+ .with(ObjectAnimator.ofFloat(mDock, View.ALPHA, 1f));
+ //.with(valueAnimator);
set.setDuration(300);
- set.setInterpolator(new AccelerateInterpolator());
+ set.setInterpolator(new LinearInterpolator());
set.addListener(new AnimatorListenerAdapter() {
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mHorizontalPager.setVisibility(VISIBLE);
+ mDock.setVisibility(VISIBLE);
+ mIndicator.setVisibility(VISIBLE);
+ }
+
@Override
public void onAnimationEnd(Animator animation) {
mFolderWindowContainer.setVisibility(View.GONE);
currentAnimator = null;
+ blurLayer.setAlpha(0f);
+ mHorizontalPager.setAlpha(1f);
+ mIndicator.setAlpha(1f);
+ mDock.setAlpha(1f);
}
@Override
public void onAnimationCancel(Animator animation) {
mFolderWindowContainer.setVisibility(View.GONE);
currentAnimator = null;
+ blurLayer.setAlpha(0f);
+ mHorizontalPager.setAlpha(1f);
+ mIndicator.setAlpha(1f);
+ mDock.setAlpha(1f);
}
});
set.start();
@@ -2847,10 +2910,18 @@ public class LauncherActivity extends AppCompatActivity implements
&& mFolderWindowContainer.getVisibility() != View.VISIBLE
&& (activeRoundedWidgetView == null || !activeRoundedWidgetView.isWidgetActivated());
+ if (alreadyOnHome) {
+ returnToHomeScreen();
+ }
+
if (shouldMoveToDefaultScreen) {
+ mHorizontalPager.setVisibility(VISIBLE);
+ mHorizontalPager.setAlpha(1f);
+ mDock.setVisibility(VISIBLE);
+ mDock.setAlpha(1f);
+ mIndicator.setVisibility(VISIBLE);
+ mIndicator.setAlpha(1f);
mHorizontalPager.setCurrentPage(1);
- } else if (alreadyOnHome) {
- returnToHomeScreen();
}
}
@@ -2879,12 +2950,15 @@ public class LauncherActivity extends AppCompatActivity implements
currentAnimator.cancel();
}
AnimatorSet set = new AnimatorSet();
+ /*ValueAnimator blurAnimator = ValueAnimator.ofInt(blurRadius, 18);
+ blurAnimator.addUpdateListener(animation ->
+ BlurWallpaperProvider.getInstance(this).blurWithLauncherView(mergedView, (Integer) animation.getAnimatedValue()));*/
set.play(ObjectAnimator.ofFloat(swipeSearchContainer, View.TRANSLATION_Y, 0))
- .with(ObjectAnimator.ofFloat(backgroundLayer, View.ALPHA, 1f))
+ .with(ObjectAnimator.ofFloat(blurLayer, View.ALPHA, 1f))
.with(ObjectAnimator.ofFloat(mHorizontalPager, View.ALPHA, 0f))
.with(ObjectAnimator.ofFloat(mIndicator, View.ALPHA, 0f))
.with(ObjectAnimator.ofFloat(mDock, View.ALPHA, 0f));
- set.setDuration(200);
+ set.setDuration(300);
set.setInterpolator(new LinearInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@Override
@@ -2892,18 +2966,22 @@ public class LauncherActivity extends AppCompatActivity implements
super.onAnimationCancel(animation);
currentAnimator = null;
swipeSearchContainer.setVisibility(GONE);
+ blurLayer.setAlpha(0f);
mHorizontalPager.setVisibility(VISIBLE);
- mIndicator.setVisibility(VISIBLE);
mDock.setVisibility(VISIBLE);
+ mIndicator.setVisibility(VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
currentAnimator = null;
+
+ blurLayer.setAlpha(1f);
mHorizontalPager.setVisibility(GONE);
- mIndicator.setVisibility(GONE);
mDock.setVisibility(GONE);
+ mIndicator.setVisibility(GONE);
+
BlissInput searchEditText = swipeSearchContainer.findViewById(
R.id.search_input);
ImageView clearSuggestions = swipeSearchContainer.findViewById(
@@ -2989,28 +3067,31 @@ public class LauncherActivity extends AppCompatActivity implements
AnimatorSet set = new AnimatorSet();
set.play(ObjectAnimator.ofFloat(swipeSearchContainer, View.TRANSLATION_Y,
-swipeSearchContainer.getHeight()))
- .with(ObjectAnimator.ofFloat(backgroundLayer, View.ALPHA, 0f))
.with(ObjectAnimator.ofFloat(mHorizontalPager, View.ALPHA, 1f))
.with(ObjectAnimator.ofFloat(mIndicator, View.ALPHA, 1f))
- .with(ObjectAnimator.ofFloat(mDock, View.ALPHA, 1f));
- set.setDuration(200);
+ .with(ObjectAnimator.ofFloat(mDock, View.ALPHA, 1f))
+ .with(ObjectAnimator.ofFloat(blurLayer, View.ALPHA, 0f));
+ set.setDuration(300);
set.setInterpolator(new LinearInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
mHorizontalPager.setVisibility(VISIBLE);
- mIndicator.setVisibility(VISIBLE);
mDock.setVisibility(VISIBLE);
+ mIndicator.setVisibility(VISIBLE);
+ //BlurWallpaperProvider.getInstance(LauncherActivity.this).clear();
}
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
currentAnimator = null;
+ swipeSearchContainer.setVisibility(VISIBLE);
+ blurLayer.setAlpha(1f);
mHorizontalPager.setVisibility(GONE);
- mIndicator.setVisibility(GONE);
mDock.setVisibility(GONE);
+ mIndicator.setVisibility(GONE);
}
@Override
@@ -3018,6 +3099,7 @@ public class LauncherActivity extends AppCompatActivity implements
super.onAnimationEnd(animation);
currentAnimator = null;
swipeSearchContainer.setVisibility(GONE);
+ blurLayer.setAlpha(0f);
if (searchDisposableObserver != null
&& !searchDisposableObserver.isDisposed()) {
searchDisposableObserver.dispose();
@@ -3050,7 +3132,7 @@ public class LauncherActivity extends AppCompatActivity implements
mHorizontalPager.setAlpha(deltaAlpha);
mIndicator.setAlpha(deltaAlpha);
mDock.setAlpha(deltaAlpha);
- backgroundLayer.setAlpha(1 - deltaAlpha);
+ blurLayer.setAlpha(1 - deltaAlpha);
}
if (translateBy >= swipeSearchContainer.getHeight() / 2) {
@@ -3088,7 +3170,7 @@ public class LauncherActivity extends AppCompatActivity implements
AnimatorSet set = new AnimatorSet();
set.play(ObjectAnimator.ofFloat(widgetResizeContainer, View.Y,
mDeviceProfile.availableHeightPx,
- mDeviceProfile.availableHeightPx - Utilities.pxFromDp(24, this)));
+ mDeviceProfile.availableHeightPx - Utilities.pxFromDp(48, this)));
set.setDuration(200);
set.setInterpolator(new LinearInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@@ -3128,7 +3210,6 @@ public class LauncherActivity extends AppCompatActivity implements
int defaultHeight = activeRoundedWidgetView.getHeight();
int currentProgress = (defaultHeight - minHeight) * 100 / (maxHeight - minHeight);
- seekBar.setMin(1);
seekBar.setMax(100);
seekBar.setProgress(currentProgress);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
diff --git a/app/src/main/res/drawable/folder_window.xml b/app/src/main/res/drawable/folder_window.xml
index fdf7c5c0f5191d7fdd519ab73fc1cfc9d454c463..ca9e4d75f53c6134780eec773437ea934b07642c 100755
--- a/app/src/main/res/drawable/folder_window.xml
+++ b/app/src/main/res/drawable/folder_window.xml
@@ -3,7 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index fa3be947194b132a150c7adca202f77c1d4f35ef..fd86f7d15c44e02f176536bd88d0c0d46e925e99 100755
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,18 +1,17 @@
-
-
+ android:layout_height="match_parent" />
@@ -108,4 +106,4 @@
android:layout_centerInParent="true"
android:visibility="gone" />
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/widgets_page.xml b/app/src/main/res/layout/widgets_page.xml
index 988aae0b48d3ea84025d9b9dae9b12e19f45508d..30cc0f5d8b7b597e08f3a9b38974b36225abd8cb 100755
--- a/app/src/main/res/layout/widgets_page.xml
+++ b/app/src/main/res/layout/widgets_page.xml
@@ -1,17 +1,18 @@
-
+
+
-
+
+ layout="@layout/layout_weather_info" />
+
+ android:orientation="vertical" />
+ android:text="Edit" />
-
+
-
-
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index ae982fae9248d034ec236d7830524c03f25ddcf2..394476d03704ebd586b8b9b62a57d4678db67a02 100755
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -33,4 +33,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 7152258f5e8794328780ef2394fcbc8a5742fef0..6670a805a5a70cfe385faad750f045b98883631f 100755
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -13,6 +13,8 @@
- @android:color/transparent
- true
- @android:color/transparent
+ - @android:color/transparent
+ - true