Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8b1d573 authored by Amit Kumar's avatar Amit Kumar 💻
Browse files

Add blur view in BlissLauncher v2

parent 4987554a
Loading
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ class ShaderBlurDrawable internal constructor(private val blurWallpaperProvider:
        }

    private val blurBounds = RectF()
    var canvasOffset: Float = 0f
    private val blurPath = Path()
    private var blurPathValid = false
        set(value) {
@@ -44,6 +45,7 @@ class ShaderBlurDrawable internal constructor(private val blurWallpaperProvider:

    fun draw(canvas: Canvas, noRadius: Boolean = false) {
        if (blurAlpha == 0) return
        if (blurBounds.right.toInt() - blurBounds.left.toInt() == 0) return
        blurBitmap = blurWallpaperProvider.wallpaper

        if (blurBitmap == null) {
@@ -65,7 +67,11 @@ class ShaderBlurDrawable internal constructor(private val blurWallpaperProvider:

        // setupBlurPath()

        // canvas.translate(0f, -1500f)
        // We check the offset just to make sure we don't translate it incorrectly
        // when moving back to home screen from widget page.
        if (canvasOffset > 0) {
            canvas.translate(canvasOffset, 0f)
        }
        if (noRadius) {
            canvas.drawRect(
                0f, 0f,
@@ -75,7 +81,9 @@ class ShaderBlurDrawable internal constructor(private val blurWallpaperProvider:
        } else {
            canvas.drawPath(DeviceProfile.path, blurPaint)
        }
        // canvas.translate(0f, 1500f)

        if (canvasOffset > 0)
            canvas.translate(-canvasOffset, 0f)
    }

    override fun setAlpha(alpha: Int) {
+93 −2
Original line number Diff line number Diff line
@@ -17,7 +17,9 @@
package foundation.e.blisslauncher.features.launcher;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
@@ -27,14 +29,22 @@ import android.view.ViewGroup;
import android.view.WindowInsets;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.logging.Handler;

import foundation.e.blisslauncher.R;
import foundation.e.blisslauncher.core.blur.BlurWallpaperProvider;
import foundation.e.blisslauncher.core.blur.ShaderBlurDrawable;
import foundation.e.blisslauncher.core.customviews.Insettable;
import foundation.e.blisslauncher.core.customviews.InsettableFrameLayout;
import foundation.e.blisslauncher.core.executors.MainThreadExecutor;
import foundation.e.blisslauncher.features.test.CellLayout;
import foundation.e.blisslauncher.features.test.TestActivity;
import foundation.e.blisslauncher.features.test.VariantDeviceProfile;

public class Hotseat extends CellLayout implements Insettable {
public class Hotseat extends CellLayout implements Insettable, BlurWallpaperProvider.Listener {

    private final TestActivity mLauncher;
    private CellLayout mContent;
@@ -44,6 +54,30 @@ public class Hotseat extends CellLayout implements Insettable {
    @ViewDebug.ExportedProperty(category = "launcher")
    private boolean mHasVerticalHotseat;

    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) {
            new MainThreadExecutor().execute(() -> invalidate());
        }

        @Override
        public void scheduleDrawable(
            @NonNull Drawable who, @NonNull Runnable what, long when
        ) {

        }

        @Override
        public void unscheduleDrawable(
            @NonNull Drawable who, @NonNull Runnable what
        ) {

        }
    };

    public Hotseat(Context context) {
        this(context, null);
    }
@@ -55,7 +89,19 @@ public class Hotseat extends CellLayout implements Insettable {
    public Hotseat(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mLauncher = TestActivity.Companion.getLauncher(context);
        setBackgroundColor(0x33000000);
        setWillNotDraw(false);
        blurWallpaperProvider = BlurWallpaperProvider.Companion.getInstance(getContext());
        createBlurDrawable();
    }

    private void createBlurDrawable() {
        if (isAttachedToWindow() && fullBlurDrawable != null) {
            fullBlurDrawable.stopListening();
        }
        fullBlurDrawable = blurWallpaperProvider.createDrawable();
        fullBlurDrawable.setCallback(blurDrawableCallback);
        fullBlurDrawable.setBounds(getLeft(), getTop(), getRight(), getBottom());
        if (isAttachedToWindow()) fullBlurDrawable.startListening();
    }

    // TODO: Remove this later.
@@ -70,6 +116,41 @@ public class Hotseat extends CellLayout implements Insettable {
        setGridSize(idp.getInv().getNumHotseatIcons(), 1);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        BlurWallpaperProvider.Companion.getInstance(getContext()).addListener(this);
        if (fullBlurDrawable != null) {
            fullBlurDrawable.startListening();
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        BlurWallpaperProvider.Companion.getInstance(getContext()).removeListener(this);
        if (fullBlurDrawable != null) {
            fullBlurDrawable.stopListening();
        }
    }

    @Override
    protected void onDraw(@Nullable Canvas canvas) {
        if (fullBlurDrawable != null) {
            fullBlurDrawable.setAlpha(blurAlpha);
            fullBlurDrawable.draw(canvas);
        }
        super.onDraw(canvas);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        if (changed && fullBlurDrawable != null) {
            fullBlurDrawable.setBounds(left, top, right, bottom);
        }
        super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // We don't want any clicks to go through to the hotseat unless the workspace is in
@@ -96,4 +177,14 @@ public class Hotseat extends CellLayout implements Insettable {
        // Don't let if follow through to workspace
        return true;
    }

    @Override
    public void onWallpaperChanged() {

    }

    @Override
    public void onEnabledChanged() {
        createBlurDrawable();
    }
}
+75 −3
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.app.ActivityOptions
import android.app.AlertDialog
import android.app.WallpaperManager
import android.app.usage.UsageStats
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProviderInfo
@@ -21,6 +22,7 @@ import android.content.pm.ActivityInfo
import android.content.pm.ApplicationInfo
import android.content.pm.LauncherActivityInfo
import android.content.pm.LauncherApps
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.graphics.Point
import android.graphics.Rect
@@ -43,6 +45,7 @@ import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.View.OnAttachStateChangeListener
import android.view.View.OnFocusChangeListener
import android.view.ViewGroup
import android.view.animation.AccelerateDecelerateInterpolator
@@ -57,6 +60,7 @@ import android.widget.SeekBar
import android.widget.TextView
import android.widget.TextView.OnEditorActionListener
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.view.isVisible
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.recyclerview.widget.DividerItemDecoration
@@ -68,11 +72,12 @@ import foundation.e.blisslauncher.BlissLauncher
import foundation.e.blisslauncher.R
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.WallpaperChangeReceiver
import foundation.e.blisslauncher.core.customviews.AbstractFloatingView
import foundation.e.blisslauncher.core.customviews.BlissFrameLayout
import foundation.e.blisslauncher.core.customviews.BlissInput
import foundation.e.blisslauncher.core.customviews.FolderTitleInput
import foundation.e.blisslauncher.core.customviews.InsettableFrameLayout
import foundation.e.blisslauncher.core.customviews.LauncherPagedView
import foundation.e.blisslauncher.core.customviews.RoundedWidgetView
import foundation.e.blisslauncher.core.customviews.SquareFrameLayout
@@ -113,6 +118,7 @@ import foundation.e.blisslauncher.features.weather.WeatherPreferences
import foundation.e.blisslauncher.features.weather.WeatherSourceListenerService
import foundation.e.blisslauncher.features.weather.WeatherUpdateService
import foundation.e.blisslauncher.features.widgets.WidgetManager
import foundation.e.blisslauncher.features.widgets.WidgetPageLayer
import foundation.e.blisslauncher.features.widgets.WidgetViewBuilder
import foundation.e.blisslauncher.features.widgets.WidgetsActivity
import foundation.e.blisslauncher.features.widgets.WidgetsRootView
@@ -170,7 +176,7 @@ class TestActivity : BaseDraggingActivity(), AutoCompleteAdapter.OnSuggestionCli
    private lateinit var dragLayer: DragLayer
    private lateinit var workspace: LauncherPagedView
    private lateinit var hotseat: Hotseat
    private lateinit var widgetPage: InsettableFrameLayout
    private lateinit var widgetPage: WidgetPageLayer

    private lateinit var mSearchInput: BlissInput

@@ -227,6 +233,8 @@ class TestActivity : BaseDraggingActivity(), AutoCompleteAdapter.OnSuggestionCli

    private val TAG = "TestActivity"

    private var wallpaperChangeReceiver: WallpaperChangeReceiver? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        if (DEBUG_STRICT_MODE) {
            StrictMode.setThreadPolicy(
@@ -259,6 +267,8 @@ class TestActivity : BaseDraggingActivity(), AutoCompleteAdapter.OnSuggestionCli
        mAppWidgetHost = BlissLauncher.getApplication(this).appWidgetHost

        initDeviceProfile(BlissLauncher.getApplication(this).invariantDeviceProfile)
        val wm = getSystemService(WALLPAPER_SERVICE) as WallpaperManager
        wm.suggestDesiredDimensions(mDeviceProfile.widthPx, mDeviceProfile.heightPx)
        dragController = DragController(this)
        rotationHelper = RotationHelper(this)
        mStateManager = LauncherStateManager(this)
@@ -299,6 +309,17 @@ class TestActivity : BaseDraggingActivity(), AutoCompleteAdapter.OnSuggestionCli
                }
            }
        })

        if (ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.READ_EXTERNAL_STORAGE
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            requestPermissions(
                arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
                STORAGE_PERMISSION_REQUEST_CODE
            )
        }
        createOrUpdateIconGrid()
        overlayCallbackImpl = OverlayCallbackImpl(this)
        setLauncherOverlay(overlayCallbackImpl)
@@ -448,11 +469,53 @@ class TestActivity : BaseDraggingActivity(), AutoCompleteAdapter.OnSuggestionCli

        // Setup the drag controller (drop targets have to be added in reverse order in priority)
        dragController.setMoveTarget(workspace)

        wallpaperChangeReceiver = WallpaperChangeReceiver(workspace)
        workspace.addOnAttachStateChangeListener(object : OnAttachStateChangeListener {
            override fun onViewAttachedToWindow(v: View) {
                wallpaperChangeReceiver?.setWindowToken(v.windowToken)
            }

            override fun onViewDetachedFromWindow(v: View) {
                wallpaperChangeReceiver?.setWindowToken(null)
            }
        })
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        if (requestCode == WeatherPreferences.LOCATION_PERMISSION_REQUEST_CODE) {
            if (grantResults.isNotEmpty() &&
                grantResults[0] == PackageManager.PERMISSION_GRANTED
            ) {
                // We only get here if user tried to enable the preference,
                // hence safe to turn it on after permission is granted
                val lm = getSystemService(LOCATION_SERVICE) as LocationManager
                if (!lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
                    showLocationEnableDialog()
                    Preferences.setEnableLocation(this)
                } else {
                    startService(
                        Intent(this, WeatherUpdateService::class.java)
                            .setAction(WeatherUpdateService.ACTION_FORCE_UPDATE)
                    )
                }
            }
        } else if (requestCode == STORAGE_PERMISSION_REQUEST_CODE) {
            if (grantResults.isNotEmpty() &&
                grantResults[0] == PackageManager.PERMISSION_GRANTED
            ) {
                BlurWallpaperProvider.getInstance(applicationContext).updateAsync()
            }
        } else super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }

    private fun setupWidgetPage() {
        widgetPage =
            layoutInflater.inflate(R.layout.widgets_page, rootView, false) as InsettableFrameLayout
            layoutInflater.inflate(R.layout.widgets_page, rootView, false) as WidgetPageLayer
        rootView.addView(widgetPage)

        widgetContainer = widgetPage.findViewById(R.id.widget_container)
@@ -1337,6 +1400,8 @@ class TestActivity : BaseDraggingActivity(), AutoCompleteAdapter.OnSuggestionCli

        const val DEBUG_STRICT_MODE = false

        private val STORAGE_PERMISSION_REQUEST_CODE: Int = 586

        // TODO: Remove after test is finished
        fun getLauncher(context: Context): TestActivity {
            return if (context is TestActivity) {
@@ -1396,8 +1461,11 @@ class TestActivity : BaseDraggingActivity(), AutoCompleteAdapter.OnSuggestionCli
                if (scrollFromWorkspace) {
                    workspace.onOverlayScrollChanged(progress)
                    widgetPage.translationX = widgetPage.measuredWidth * (progress - 1)
                    widgetPage.changeBlurBounds(progress, true)
                } else {
                    workspace.onOverlayScrollChanged(progress)
                    Log.i(TAG, "onScrollChanged: $progress")
                    widgetPage.changeBlurBounds(progress, false)
                }
            }
        }
@@ -1414,6 +1482,7 @@ class TestActivity : BaseDraggingActivity(), AutoCompleteAdapter.OnSuggestionCli
                    workspace.onOverlayScrollChanged(it.animatedValue as Float)
                    widgetPage.translationX =
                        widgetPage.measuredWidth * (it.animatedValue as Float - 1)
                    widgetPage.changeBlurBounds(it.animatedValue as Float, true)
                }
                workspaceAnim.duration = 300
                workspaceAnim.interpolator = AccelerateDecelerateInterpolator()
@@ -1425,6 +1494,7 @@ class TestActivity : BaseDraggingActivity(), AutoCompleteAdapter.OnSuggestionCli
                    override fun onAnimationCancel(animation: Animator) {
                        workspace.onOverlayScrollChanged(0f)
                        widgetPage.translationX = (-widgetPage.measuredWidth).toFloat()
                        widgetPage.changeBlurBounds(0f, true)
                        animator = null
                    }
                })
@@ -1435,6 +1505,7 @@ class TestActivity : BaseDraggingActivity(), AutoCompleteAdapter.OnSuggestionCli
                    workspace.onOverlayScrollChanged(it.animatedValue as Float)
                    widgetPage.translationX =
                        widgetPage.measuredWidth * (it.animatedValue as Float - 1)
                    widgetPage.changeBlurBounds(it.animatedValue as Float, false)
                }
                workspaceAnim.duration = 300
                workspaceAnim.interpolator = AccelerateDecelerateInterpolator()
@@ -1446,6 +1517,7 @@ class TestActivity : BaseDraggingActivity(), AutoCompleteAdapter.OnSuggestionCli
                    override fun onAnimationCancel(animation: Animator) {
                        workspace.onOverlayScrollChanged(1f)
                        widgetPage.translationX = 0f
                        widgetPage.changeBlurBounds(1f, false)
                        animator = null
                    }
                })
+107 −0
Original line number Diff line number Diff line
package foundation.e.blisslauncher.features.widgets

import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import foundation.e.blisslauncher.core.blur.BlurWallpaperProvider
import foundation.e.blisslauncher.core.blur.ShaderBlurDrawable
import foundation.e.blisslauncher.core.customviews.Insettable
import foundation.e.blisslauncher.core.customviews.InsettableFrameLayout
import foundation.e.blisslauncher.core.runOnMainThread

class WidgetPageLayer @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
) : InsettableFrameLayout(context, attrs), Insettable,
    BlurWallpaperProvider.Listener {
    private val blurWallpaperProvider: BlurWallpaperProvider
    private var fullBlurDrawable: ShaderBlurDrawable? = null
    private val blurAlpha = 255
    private val blurDrawableCallback: Drawable.Callback = object : Drawable.Callback {
        override fun invalidateDrawable(who: Drawable) {
            runOnMainThread {
                invalidate()
            }
        }

        override fun scheduleDrawable(
            who: Drawable,
            what: Runnable,
            `when`: Long
        ) {
        }

        override fun unscheduleDrawable(
            who: Drawable,
            what: Runnable
        ) {
        }
    }

    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?.alpha = blurAlpha
        fullBlurDrawable?.draw(canvas)
        super.onDraw(canvas)
    }

    override fun onLayout(
        changed: Boolean,
        left: Int,
        top: Int,
        right: Int,
        bottom: Int
    ) {
        super.onLayout(changed, left, top, right, bottom)
        if (changed) {
            fullBlurDrawable?.setBounds(left, top, right, bottom)
        }
    }

    /**
     * We only need to change right bound for widget page blur layer.
     */
    fun changeBlurBounds(factor: Float, isLeftToRight: Boolean) {
        fullBlurDrawable?.setBounds(left, top, (right * factor).toInt(), bottom)
        if (isLeftToRight) {
            fullBlurDrawable?.canvasOffset =
                (right - left) * (1 - factor)
        }
        fullBlurDrawable?.invalidateSelf()
    }

    private fun createBlurDrawable() {
        if (isAttachedToWindow) {
            fullBlurDrawable?.stopListening()
        }
        fullBlurDrawable = blurWallpaperProvider.createDrawable().apply {
            callback = blurDrawableCallback
            setBounds(left, top, right, bottom)
        }
        if (isAttachedToWindow) fullBlurDrawable?.startListening()
    }

    override fun onEnabledChanged() {
        createBlurDrawable()
    }

    override fun onWallpaperChanged() {}

    init {
        setWillNotDraw(false)
        blurWallpaperProvider = BlurWallpaperProvider.getInstance(context)
        createBlurDrawable()
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -15,6 +15,11 @@
        android:clipToPadding="false"
        android:importantForAccessibility="no">

        <!--<foundation.e.blisslauncher.core.customviews.BlurBackgroundView
            android:id="@+id/blur_layer"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />-->

        <foundation.e.blisslauncher.core.customviews.LauncherPagedView
            android:id="@+id/workspace"
            android:layout_width="match_parent"
Loading