diff --git a/lawnchair/res/color/surface_light.xml b/lawnchair/res/color/surface_light.xml new file mode 100644 index 0000000000..55d7b6ae45 --- /dev/null +++ b/lawnchair/res/color/surface_light.xml @@ -0,0 +1,5 @@ + + + + diff --git a/lawnchair/res/values/attrs.xml b/lawnchair/res/values/attrs.xml index 2353625334..4d398ddf5e 100644 --- a/lawnchair/res/values/attrs.xml +++ b/lawnchair/res/values/attrs.xml @@ -18,6 +18,8 @@ + + diff --git a/lawnchair/res/values/dimens.xml b/lawnchair/res/values/dimens.xml index 936a4d2f3e..0b19e9038e 100644 --- a/lawnchair/res/values/dimens.xml +++ b/lawnchair/res/values/dimens.xml @@ -32,5 +32,8 @@ 20dp 60dp 52dp + 1.0dip + 28dp 16dp + 4dp diff --git a/lawnchair/res/values/styles.xml b/lawnchair/res/values/styles.xml index 453eb40fab..95aee9d95b 100644 --- a/lawnchair/res/values/styles.xml +++ b/lawnchair/res/values/styles.xml @@ -9,6 +9,8 @@ ?android:attr/colorBackground @color/system_neutral1_100 @color/dark_drawer_text_color + @color/system_neutral1_0 + @color/surface_light @color/surface_variant_light @@ -43,6 +49,8 @@ ?android:attr/colorBackground @color/system_neutral1_700 ?android:textColorSecondary + @color/system_neutral1_700 + @color/surface_dark @color/system_neutral1_800 diff --git a/lawnchair/src/app/lawnchair/allapps/AllAppsSearchInput.kt b/lawnchair/src/app/lawnchair/allapps/AllAppsSearchInput.kt index 309512b93c..78a3026358 100644 --- a/lawnchair/src/app/lawnchair/allapps/AllAppsSearchInput.kt +++ b/lawnchair/src/app/lawnchair/allapps/AllAppsSearchInput.kt @@ -77,6 +77,7 @@ class AllAppsSearchInput(context: Context, attrs: AttributeSet?) : LinearLayout( LawnchairAppSearchAlgorithm(launcher), input, launcher, this ) + input.initialize(appsView) } override fun onAppsUpdated() { diff --git a/lawnchair/src/app/lawnchair/allapps/FallbackSearchInputView.kt b/lawnchair/src/app/lawnchair/allapps/FallbackSearchInputView.kt index 8d8483aa9e..c98120bc89 100644 --- a/lawnchair/src/app/lawnchair/allapps/FallbackSearchInputView.kt +++ b/lawnchair/src/app/lawnchair/allapps/FallbackSearchInputView.kt @@ -1,14 +1,53 @@ package app.lawnchair.allapps import android.content.Context +import android.graphics.Rect import android.util.AttributeSet import com.android.launcher3.ExtendedEditText import com.android.launcher3.R +import com.android.launcher3.allapps.AllAppsContainerView class FallbackSearchInputView(context: Context, attrs: AttributeSet?) : ExtendedEditText(context, attrs) { + private var appsView: AllAppsContainerView? = null + private var shown = true + set(value) { + if (field != value) { + field = value + updateBackground() + } + } + + fun initialize(appsView: AllAppsContainerView) { + this.appsView = appsView + } + + private fun updateBackground() { + val showBackground = shown && !isFocused + if (showBackground) { + setBackgroundResource(R.drawable.search_input_fg) + } else { + background = null + } + } + override fun show() { super.show() - setBackgroundResource(R.drawable.search_input_fg) + shown = true + } + + override fun hide() { + super.hide() + shown = false + } + + override fun hideKeyboard() { + super.hideKeyboard() + this.appsView?.requestFocus() + } + + override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) { + super.onFocusChanged(focused, direction, previouslyFocusedRect) + updateBackground() } } diff --git a/lawnchair/src/app/lawnchair/allapps/LawnchairAppSearchAlgorithm.kt b/lawnchair/src/app/lawnchair/allapps/LawnchairAppSearchAlgorithm.kt index 4413b2c96e..b6bb3da00d 100644 --- a/lawnchair/src/app/lawnchair/allapps/LawnchairAppSearchAlgorithm.kt +++ b/lawnchair/src/app/lawnchair/allapps/LawnchairAppSearchAlgorithm.kt @@ -13,6 +13,12 @@ import java.util.* class LawnchairAppSearchAlgorithm(context: Context) : DefaultAppSearchAlgorithm(context) { private val useFuzzySearch by PreferenceManager.getInstance(context).useFuzzySearch + private val iconBackground = SearchItemBackground( + context, + showBackground = false, + roundTop = true, + roundBottom = true + ) override fun getResult( apps: MutableList, @@ -35,7 +41,7 @@ class LawnchairAppSearchAlgorithm(context: Context) : DefaultAppSearchAlgorithm( .filter { StringMatcherUtility.matches(queryTextLower, it.title.toString(), matcher) } .take(MAX_RESULTS_COUNT) .mapIndexed { index, info -> - LawnchairSearchAdapterProvider.asIcon(index, "", info, index) + LawnchairSearchAdapterProvider.asIcon(index, "", info, index, iconBackground) } .toCollection(ArrayList()) return result @@ -49,7 +55,7 @@ class LawnchairAppSearchAlgorithm(context: Context) : DefaultAppSearchAlgorithm( return matches.take(MAX_RESULTS_COUNT) .mapIndexed { index, match -> - LawnchairSearchAdapterProvider.asIcon(index, "", match.referent, index) + LawnchairSearchAdapterProvider.asIcon(index, "", match.referent, index, iconBackground) } .toCollection(ArrayList()) } diff --git a/lawnchair/src/app/lawnchair/allapps/LawnchairSearchAdapterProvider.kt b/lawnchair/src/app/lawnchair/allapps/LawnchairSearchAdapterProvider.kt index 47d50e9523..1f21b44f62 100644 --- a/lawnchair/src/app/lawnchair/allapps/LawnchairSearchAdapterProvider.kt +++ b/lawnchair/src/app/lawnchair/allapps/LawnchairSearchAdapterProvider.kt @@ -17,6 +17,8 @@ class LawnchairSearchAdapterProvider( private val appsView: AllAppsContainerView ) : DefaultSearchAdapterProvider(launcher, appsView) { + private val decorator = SearchItemDecorator(appsView) + override fun isViewSupported(viewType: Int): Boolean { return viewType == SEARCH_RESULT_ICON } @@ -54,11 +56,13 @@ class LawnchairSearchAdapterProvider( } } + override fun getDecorator() = decorator + companion object { private const val SEARCH_RESULT_ICON = (1 shl 8) and AllAppsGridAdapter.VIEW_TYPE_ICON fun asIcon( - pos: Int, sectionName: String, appInfo: AppInfo, appIndex: Int + pos: Int, sectionName: String, appInfo: AppInfo, appIndex: Int, background: SearchItemBackground ): AdapterItem { val item = AdapterItem() item.viewType = SEARCH_RESULT_ICON @@ -66,6 +70,7 @@ class LawnchairSearchAdapterProvider( item.sectionName = sectionName item.appInfo = appInfo item.appIndex = appIndex + item.decorationInfo = SearchDecorationInfo(background) return item } } diff --git a/lawnchair/src/app/lawnchair/allapps/SearchDecorationInfo.kt b/lawnchair/src/app/lawnchair/allapps/SearchDecorationInfo.kt new file mode 100644 index 0000000000..afa1fb5f03 --- /dev/null +++ b/lawnchair/src/app/lawnchair/allapps/SearchDecorationInfo.kt @@ -0,0 +1,5 @@ +package app.lawnchair.allapps + +import com.android.launcher3.allapps.DecorationInfo + +data class SearchDecorationInfo(val background: SearchItemBackground?) : DecorationInfo() diff --git a/lawnchair/src/app/lawnchair/allapps/SearchItemBackground.kt b/lawnchair/src/app/lawnchair/allapps/SearchItemBackground.kt new file mode 100644 index 0000000000..e1a14e2e76 --- /dev/null +++ b/lawnchair/src/app/lawnchair/allapps/SearchItemBackground.kt @@ -0,0 +1,59 @@ +package app.lawnchair.allapps + +import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path +import android.graphics.RectF +import android.view.View +import com.android.launcher3.R +import com.android.launcher3.util.Themes + +class SearchItemBackground( + context: Context, + showBackground: Boolean, + roundTop: Boolean, + roundBottom: Boolean +) { + private val resources = context.resources + + private val searchDecorationPadding = resources.getDimensionPixelSize(R.dimen.search_decoration_padding) + private val focusHighlight = Themes.getAttrColor(context, R.attr.focusHighlight) + private val groupHighlight = if (showBackground) Themes.getAttrColor(context, R.attr.groupHighlight) else 0 + + private val cornerRadii: FloatArray + private val paint = Paint(Paint.ANTI_ALIAS_FLAG) + private val tmpPath = Path() + private val tmpRect = RectF() + + init { + val searchGroupRadius = resources.getDimensionPixelSize(R.dimen.search_group_radius).toFloat() + val searchResultRadius = resources.getDimensionPixelSize(R.dimen.search_result_radius).toFloat() + + val topRadius = if (roundTop) searchGroupRadius else searchResultRadius + val bottomRadius = if (roundBottom) searchGroupRadius else searchResultRadius + + cornerRadii = floatArrayOf( + topRadius, topRadius, topRadius, topRadius, + bottomRadius, bottomRadius, bottomRadius, bottomRadius + ) + } + + fun draw(c: Canvas, child: View, isFocused: Boolean) { + val color = if (isFocused) focusHighlight else groupHighlight + if (color == 0) return + + paint.color = color + + val left = child.left.toFloat() + searchDecorationPadding + val top = child.top.toFloat() + searchDecorationPadding + val right = child.right.toFloat() - searchDecorationPadding + val bottom = child.bottom.toFloat() - searchDecorationPadding + tmpRect.set(left, top, right, bottom) + + tmpPath.reset() + tmpPath.addRoundRect(tmpRect, cornerRadii, Path.Direction.CW) + + c.drawPath(tmpPath, paint) + } +} \ No newline at end of file diff --git a/lawnchair/src/app/lawnchair/allapps/SearchItemDecorator.kt b/lawnchair/src/app/lawnchair/allapps/SearchItemDecorator.kt new file mode 100644 index 0000000000..44052aa65a --- /dev/null +++ b/lawnchair/src/app/lawnchair/allapps/SearchItemDecorator.kt @@ -0,0 +1,43 @@ +package app.lawnchair.allapps + +import android.graphics.Canvas +import android.graphics.Rect +import android.view.View +import androidx.core.view.children +import androidx.recyclerview.widget.RecyclerView +import com.android.launcher3.R +import com.android.launcher3.allapps.AllAppsContainerView + +class SearchItemDecorator(private val appsView: AllAppsContainerView) : RecyclerView.ItemDecoration() { + private val context = appsView.context + private val resources = context.resources + + private val searchDecorationPadding = resources.getDimensionPixelSize(R.dimen.search_decoration_padding) + + override fun getItemOffsets( + outRect: Rect, + view: View, + parent: RecyclerView, + state: RecyclerView.State + ) { + outRect.offset(0, searchDecorationPadding) + } + + override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { + val adapterItems = appsView.apps.adapterItems + val searchAdapterProvider = appsView.searchAdapterProvider + parent.children.forEach { child -> + val adapterPosition = parent.getChildAdapterPosition(child) + if (adapterPosition >= 0 && adapterPosition < adapterItems.size) { + val adapterItem = adapterItems[adapterPosition] + val background = (adapterItem.decorationInfo as? SearchDecorationInfo)?.background + if (background != null) { + val isHighlightedItem = child == searchAdapterProvider.highlightedItem + val inputHasFocus = appsView.searchUiManager.editText?.hasFocus() == true + val isFocused = isHighlightedItem && inputHasFocus + background.draw(c, child, isFocused) + } + } + } + } +} diff --git a/src/com/android/launcher3/ExtendedEditText.java b/src/com/android/launcher3/ExtendedEditText.java index a4e1af6fb3..80613f1909 100644 --- a/src/com/android/launcher3/ExtendedEditText.java +++ b/src/com/android/launcher3/ExtendedEditText.java @@ -101,6 +101,7 @@ public class ExtendedEditText extends EditText { // inherited class can override to change the appearance of the edit text. public void show() {} + public void hide() {} public void showKeyboard() { mShowImeAfterFirstLayout = !showSoftInput(); diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index 80068e21ba..5ec03dce2e 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -61,6 +61,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener; import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget.DragObject; +import com.android.launcher3.ExtendedEditText; import com.android.launcher3.Insettable; import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.R; @@ -806,8 +807,14 @@ public class AllAppsContainerView extends AllAppsStretchLayout implements DragSo getSearchView().setBackgroundColor(viewBG); getFloatingHeaderView().setHeaderColor(viewBG); invalidateHeader(); - if (mHeaderColor == mScrimColor && mSearchUiManager.getEditText() != null) { - mSearchUiManager.getEditText().show(); + + ExtendedEditText editText = mSearchUiManager.getEditText(); + if (editText != null) { + if (mHeaderColor == mScrimColor) { + editText.show(); + } else { + editText.hide(); + } } } } diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java index 788add45be..79718fb6df 100644 --- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java +++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java @@ -138,7 +138,6 @@ public class AllAppsSearchBarController public void reset() { mCallback.clearSearchResult(); mInput.reset(); - mInput.clearFocus(); mQuery = null; }