diff --git a/lawnchair/res/values/strings.xml b/lawnchair/res/values/strings.xml
index 017e8307e5..530417452d 100644
--- a/lawnchair/res/values/strings.xml
+++ b/lawnchair/res/values/strings.xml
@@ -294,6 +294,7 @@
Colors
Accent color
+ Stroke color
Swatches
@@ -529,6 +530,7 @@
Google Search bar
Opacity
+ Stroke
Corner radius
Apply accent color
Search provider
diff --git a/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt b/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt
index fe799124d1..f7dc725d13 100644
--- a/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt
+++ b/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt
@@ -95,7 +95,7 @@ class PreferenceManager private constructor(private val context: Context) : Base
val drawerThemedIcons = BoolPref("drawer_themed_icons", false, recreate)
val hotseatQsbCornerRadius = FloatPref("pref_hotseatQsbCornerRadius", 1F, recreate)
val searchBackgroundHotseatTransparency = IntPref("pref_searchHotseatTranparency", 0, recreate)
-
+ val searchStrokeWidth = FloatPref("pref_searchStrokeWidth", 1F, recreate)
val enableWallpaperBlur = BoolPref("pref_enableWallpaperBlur", false, recreate)
val wallpaperBlur = IntPref("pref_wallpaperBlur", 25, recreate)
val wallpaperBlurFactorThreshold = IntPref("pref_wallpaperBlurFactor", 25, recreate)
diff --git a/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt b/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt
index 8537ed03c6..c04cbd42e9 100644
--- a/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt
+++ b/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt
@@ -120,6 +120,14 @@ class PreferenceManager2 private constructor(private val context: Context) : Pre
onSet = { reloadHelper.restart() },
)
+ val strokeColorStyle = preference(
+ key = stringPreferencesKey(name = "stroke_color"),
+ parse = ColorOption::fromString,
+ save = ColorOption::toString,
+ onSet = { reloadHelper.restart() },
+ defaultValue = ColorOption.fromString(context.getString(R.string.config_default_accent_color)),
+ )
+
val notificationDotColor = preference(
key = stringPreferencesKey(name = "notification_dot_color"),
parse = ColorOption::fromString,
diff --git a/lawnchair/src/app/lawnchair/qsb/LawnQsbLayout.kt b/lawnchair/src/app/lawnchair/qsb/LawnQsbLayout.kt
index 70fb79c223..be263db77a 100644
--- a/lawnchair/src/app/lawnchair/qsb/LawnQsbLayout.kt
+++ b/lawnchair/src/app/lawnchair/qsb/LawnQsbLayout.kt
@@ -6,6 +6,8 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.Color
+import android.graphics.Paint
+import android.graphics.drawable.LayerDrawable
import android.graphics.drawable.PaintDrawable
import android.util.AttributeSet
import android.widget.FrameLayout
@@ -27,6 +29,7 @@ import app.lawnchair.qsb.providers.Google
import app.lawnchair.qsb.providers.GoogleGo
import app.lawnchair.qsb.providers.PixelSearch
import app.lawnchair.qsb.providers.QsbSearchProvider
+import app.lawnchair.theme.color.ColorOption
import app.lawnchair.util.pendingIntent
import app.lawnchair.util.repeatOnAttached
import app.lawnchair.util.viewAttachedScope
@@ -37,6 +40,9 @@ import com.android.launcher3.qsb.QsbContainerView
import com.android.launcher3.util.Themes
import com.android.launcher3.views.ActivityContext
import com.patrykmichalik.opto.core.firstBlocking
+import com.patrykmichalik.opto.core.onEach
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flatMapLatest
@@ -53,6 +59,9 @@ class LawnQsbLayout(context: Context, attrs: AttributeSet?) : FrameLayout(contex
private lateinit var preferenceManager: PreferenceManager
private lateinit var preferenceManager2: PreferenceManager2
private var searchPendingIntent: PendingIntent? = null
+ private val coroutineScope = CoroutineScope(Dispatchers.Default)
+
+ private var strokeColor: ColorOption? = null
@OptIn(ExperimentalCoroutinesApi::class)
override fun onFinishInflate() {
@@ -65,6 +74,11 @@ class LawnQsbLayout(context: Context, attrs: AttributeSet?) : FrameLayout(contex
preferenceManager = PreferenceManager.getInstance(context)
preferenceManager2 = PreferenceManager2.getInstance(context)
+ preferenceManager2.strokeColorStyle.onEach(launchIn = coroutineScope) {
+ strokeColor = it
+ setUpBackground()
+ }
+
setUpBackground()
clipIconRipples()
@@ -116,6 +130,7 @@ class LawnQsbLayout(context: Context, attrs: AttributeSet?) : FrameLayout(contex
}
preferenceManager.searchBackgroundHotseatTransparency.subscribeChanges(this::setUpBackground)
+ preferenceManager.searchStrokeWidth.subscribeChanges(this::setUpBackground)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
@@ -186,12 +201,25 @@ class LawnQsbLayout(context: Context, attrs: AttributeSet?) : FrameLayout(contex
val baseColor = if (themed) Themes.getColorBackgroundFloating(context) else Themes.getAttrColor(context, R.attr.qsbFillColor)
val alphaValue = (transparency * 255) / 100
val color = Color.argb(alphaValue, Color.red(baseColor), Color.green(baseColor), Color.blue(baseColor))
+ val strokeColor = strokeColor
+ val strokeWidth = preferenceManager.searchStrokeWidth.get()
+
+ val backgroundDrawable = PaintDrawable(color).apply {
+ setCornerRadius(cornerRadius)
+ }
+
+ val strokeDrawable = PaintDrawable().apply {
+ paint.style = Paint.Style.STROKE
+ paint.color = strokeColor?.colorPreferenceEntry?.lightColor?.invoke(context) ?: Themes.getColorAccent(context)
+ paint.strokeWidth = strokeWidth
+ setCornerRadius(cornerRadius)
+ }
+
+ val combinedDrawable = LayerDrawable(arrayOf(backgroundDrawable, strokeDrawable))
with(inner) {
clipToOutline = cornerRadius > 0
- background = PaintDrawable(color).apply {
- setCornerRadius(cornerRadius)
- }
+ background = combinedDrawable
}
}
diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/colorpreference/ColorPreferenceModelList.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/colorpreference/ColorPreferenceModelList.kt
index e2e2f49c94..99ce3858c7 100644
--- a/lawnchair/src/app/lawnchair/ui/preferences/components/colorpreference/ColorPreferenceModelList.kt
+++ b/lawnchair/src/app/lawnchair/ui/preferences/components/colorpreference/ColorPreferenceModelList.kt
@@ -17,6 +17,13 @@ class ColorPreferenceModelList(context: Context) {
dynamicEntries = dynamicColors,
),
)
+ registerModel(
+ ColorPreferenceModel(
+ prefObject = prefs.strokeColorStyle,
+ labelRes = R.string.stroke_color,
+ dynamicEntries = dynamicColors,
+ ),
+ )
registerModel(
ColorPreferenceModel(
prefObject = prefs.notificationDotColor,
diff --git a/lawnchair/src/app/lawnchair/ui/preferences/destinations/DockPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/destinations/DockPreferences.kt
index 0fd72087c2..fed3c3ae53 100644
--- a/lawnchair/src/app/lawnchair/ui/preferences/destinations/DockPreferences.kt
+++ b/lawnchair/src/app/lawnchair/ui/preferences/destinations/DockPreferences.kt
@@ -30,6 +30,7 @@ import app.lawnchair.preferences2.preferenceManager2
import app.lawnchair.qsb.providers.QsbSearchProvider
import app.lawnchair.ui.preferences.LocalIsExpandedScreen
import app.lawnchair.ui.preferences.components.NavigationActionPreference
+import app.lawnchair.ui.preferences.components.colorpreference.ColorPreference
import app.lawnchair.ui.preferences.components.controls.ListPreference
import app.lawnchair.ui.preferences.components.controls.ListPreferenceEntry
import app.lawnchair.ui.preferences.components.controls.MainSwitchPreference
@@ -70,13 +71,6 @@ fun DockPreferences(
adapter = prefs2.themedHotseatQsb.getAdapter(),
label = stringResource(id = R.string.apply_accent_color_label),
)
- SliderPreference(
- label = stringResource(id = R.string.search_background_transparency),
- adapter = prefs.searchBackgroundHotseatTransparency.getAdapter(),
- step = 5,
- valueRange = 0..100,
- showUnit = "%",
- )
SliderPreference(
label = stringResource(id = R.string.corner_radius_label),
adapter = prefs.hotseatQsbCornerRadius.getAdapter(),
@@ -94,6 +88,21 @@ fun DockPreferences(
.name,
),
)
+ SliderPreference(
+ label = stringResource(id = R.string.search_background_transparency),
+ adapter = prefs.searchBackgroundHotseatTransparency.getAdapter(),
+ step = 5,
+ valueRange = 0..100,
+ showUnit = "%",
+ )
+ SliderPreference(
+ label = stringResource(id = R.string.stroke_width),
+ adapter = prefs.searchStrokeWidth.getAdapter(),
+ step = 1f,
+ valueRange = 0f..10f,
+ showUnit = "vw",
+ )
+ ColorPreference(preference = prefs2.strokeColorStyle)
}
}
}