Loading app/src/main/java/foundation/e/blisslauncher/core/blur/ShaderBlurDrawable.kt +10 −2 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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) { Loading @@ -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, Loading @@ -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) { Loading app/src/main/java/foundation/e/blisslauncher/features/launcher/Hotseat.java +93 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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); } Loading @@ -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. Loading @@ -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 Loading @@ -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(); } } app/src/main/java/foundation/e/blisslauncher/features/test/TestActivity.kt +75 −3 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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( Loading Loading @@ -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) Loading Loading @@ -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) Loading Loading @@ -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) Loading Loading @@ -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) { Loading Loading @@ -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) } } } Loading @@ -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() Loading @@ -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 } }) Loading @@ -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() Loading @@ -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 } }) Loading app/src/main/java/foundation/e/blisslauncher/features/widgets/WidgetPageLayer.kt 0 → 100644 +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() } } app/src/main/res/layout/activity_test.xml +5 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
app/src/main/java/foundation/e/blisslauncher/core/blur/ShaderBlurDrawable.kt +10 −2 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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) { Loading @@ -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, Loading @@ -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) { Loading
app/src/main/java/foundation/e/blisslauncher/features/launcher/Hotseat.java +93 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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); } Loading @@ -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. Loading @@ -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 Loading @@ -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(); } }
app/src/main/java/foundation/e/blisslauncher/features/test/TestActivity.kt +75 −3 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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( Loading Loading @@ -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) Loading Loading @@ -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) Loading Loading @@ -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) Loading Loading @@ -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) { Loading Loading @@ -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) } } } Loading @@ -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() Loading @@ -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 } }) Loading @@ -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() Loading @@ -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 } }) Loading
app/src/main/java/foundation/e/blisslauncher/features/widgets/WidgetPageLayer.kt 0 → 100644 +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() } }
app/src/main/res/layout/activity_test.xml +5 −0 Original line number Diff line number Diff line Loading @@ -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