mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-19 10:48:19 +00:00
Split InvariantDeviceProfile#numHotseatIcons into two variables: numDatabaseHotseatIcons and numShownHotseatIcons. These are generally the same, but different DisplayOptions within the same GridOption can choose to show different numbers of hotseat icons while sharing the same database. numDatabaseHotseatIcons is used for all reading/writing/migrating purposes, while numShownHotseatIcons determines how many Hotseat icons to show in the UI. Test: Existing tests pass, added two new migration tests Bug: 184789479 Bug: 171917176 Change-Id: I54583504f61a47a4444b6a637ebb7e3ab31528b7
216 lines
7.6 KiB
Java
216 lines
7.6 KiB
Java
/*
|
|
* Copyright (C) 2017 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package com.android.launcher3.allapps.search;
|
|
|
|
import static android.view.View.MeasureSpec.EXACTLY;
|
|
import static android.view.View.MeasureSpec.getSize;
|
|
import static android.view.View.MeasureSpec.makeMeasureSpec;
|
|
|
|
import static com.android.launcher3.Utilities.prefixTextWithIcon;
|
|
import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
|
|
|
|
import android.content.Context;
|
|
import android.graphics.Rect;
|
|
import android.text.Selection;
|
|
import android.text.SpannableStringBuilder;
|
|
import android.text.method.TextKeyListener;
|
|
import android.util.AttributeSet;
|
|
import android.view.KeyEvent;
|
|
import android.view.View;
|
|
import android.view.ViewGroup.MarginLayoutParams;
|
|
|
|
import com.android.launcher3.BaseDraggingActivity;
|
|
import com.android.launcher3.DeviceProfile;
|
|
import com.android.launcher3.ExtendedEditText;
|
|
import com.android.launcher3.Insettable;
|
|
import com.android.launcher3.R;
|
|
import com.android.launcher3.allapps.AllAppsContainerView;
|
|
import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
|
|
import com.android.launcher3.allapps.AllAppsStore;
|
|
import com.android.launcher3.allapps.AlphabeticalAppsList;
|
|
import com.android.launcher3.allapps.SearchUiManager;
|
|
import com.android.launcher3.search.SearchCallback;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
/**
|
|
* Layout to contain the All-apps search UI.
|
|
*/
|
|
public class AppsSearchContainerLayout extends ExtendedEditText
|
|
implements SearchUiManager, SearchCallback<AdapterItem>,
|
|
AllAppsStore.OnUpdateListener, Insettable {
|
|
|
|
private final BaseDraggingActivity mLauncher;
|
|
private final AllAppsSearchBarController mSearchBarController;
|
|
private final SpannableStringBuilder mSearchQueryBuilder;
|
|
|
|
private AlphabeticalAppsList mApps;
|
|
private AllAppsContainerView mAppsView;
|
|
|
|
// The amount of pixels to shift down and overlap with the rest of the content.
|
|
private final int mContentOverlap;
|
|
|
|
public AppsSearchContainerLayout(Context context) {
|
|
this(context, null);
|
|
}
|
|
|
|
public AppsSearchContainerLayout(Context context, AttributeSet attrs) {
|
|
this(context, attrs, 0);
|
|
}
|
|
|
|
public AppsSearchContainerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
super(context, attrs, defStyleAttr);
|
|
|
|
mLauncher = BaseDraggingActivity.fromContext(context);
|
|
mSearchBarController = new AllAppsSearchBarController();
|
|
|
|
mSearchQueryBuilder = new SpannableStringBuilder();
|
|
Selection.setSelection(mSearchQueryBuilder, 0);
|
|
setHint(prefixTextWithIcon(getContext(), R.drawable.ic_allapps_search, getHint()));
|
|
|
|
mContentOverlap =
|
|
getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_field_height) / 2;
|
|
}
|
|
|
|
@Override
|
|
protected void onAttachedToWindow() {
|
|
super.onAttachedToWindow();
|
|
mAppsView.getAppsStore().addUpdateListener(this);
|
|
}
|
|
|
|
@Override
|
|
protected void onDetachedFromWindow() {
|
|
super.onDetachedFromWindow();
|
|
mAppsView.getAppsStore().removeUpdateListener(this);
|
|
}
|
|
|
|
@Override
|
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
// Update the width to match the grid padding
|
|
DeviceProfile dp = mLauncher.getDeviceProfile();
|
|
int myRequestedWidth = getSize(widthMeasureSpec);
|
|
int rowWidth = myRequestedWidth - mAppsView.getActiveRecyclerView().getPaddingLeft()
|
|
- mAppsView.getActiveRecyclerView().getPaddingRight();
|
|
|
|
int cellWidth = DeviceProfile.calculateCellWidth(rowWidth, dp.cellLayoutBorderSpacingPx,
|
|
dp.numShownHotseatIcons);
|
|
int iconVisibleSize = Math.round(ICON_VISIBLE_AREA_FACTOR * dp.iconSizePx);
|
|
int iconPadding = cellWidth - iconVisibleSize;
|
|
|
|
int myWidth = rowWidth - iconPadding + getPaddingLeft() + getPaddingRight();
|
|
super.onMeasure(makeMeasureSpec(myWidth, EXACTLY), heightMeasureSpec);
|
|
}
|
|
|
|
@Override
|
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
super.onLayout(changed, left, top, right, bottom);
|
|
|
|
// Shift the widget horizontally so that its centered in the parent (b/63428078)
|
|
View parent = (View) getParent();
|
|
int availableWidth = parent.getWidth() - parent.getPaddingLeft() - parent.getPaddingRight();
|
|
int myWidth = right - left;
|
|
int expectedLeft = parent.getPaddingLeft() + (availableWidth - myWidth) / 2;
|
|
int shift = expectedLeft - left;
|
|
setTranslationX(shift);
|
|
|
|
offsetTopAndBottom(mContentOverlap);
|
|
}
|
|
|
|
@Override
|
|
public void initializeSearch(AllAppsContainerView appsView) {
|
|
mApps = appsView.getApps();
|
|
mAppsView = appsView;
|
|
mSearchBarController.initialize(
|
|
new DefaultAppSearchAlgorithm(mLauncher),
|
|
this, mLauncher, this);
|
|
}
|
|
|
|
@Override
|
|
public void onAppsUpdated() {
|
|
mSearchBarController.refreshSearchResult();
|
|
}
|
|
|
|
@Override
|
|
public void resetSearch() {
|
|
mSearchBarController.reset();
|
|
}
|
|
|
|
@Override
|
|
public void preDispatchKeyEvent(KeyEvent event) {
|
|
// Determine if the key event was actual text, if so, focus the search bar and then dispatch
|
|
// the key normally so that it can process this key event
|
|
if (!mSearchBarController.isSearchFieldFocused() &&
|
|
event.getAction() == KeyEvent.ACTION_DOWN) {
|
|
final int unicodeChar = event.getUnicodeChar();
|
|
final boolean isKeyNotWhitespace = unicodeChar > 0 &&
|
|
!Character.isWhitespace(unicodeChar) && !Character.isSpaceChar(unicodeChar);
|
|
if (isKeyNotWhitespace) {
|
|
boolean gotKey = TextKeyListener.getInstance().onKeyDown(this, mSearchQueryBuilder,
|
|
event.getKeyCode(), event);
|
|
if (gotKey && mSearchQueryBuilder.length() > 0) {
|
|
mSearchBarController.focusSearchField();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onSearchResult(String query, ArrayList<AdapterItem> items) {
|
|
if (items != null) {
|
|
mApps.setSearchResults(items);
|
|
notifyResultChanged();
|
|
mAppsView.setLastSearchQuery(query);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onAppendSearchResult(String query, ArrayList<AdapterItem> items) {
|
|
if (items != null) {
|
|
mApps.appendSearchResults(items);
|
|
notifyResultChanged();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void clearSearchResult() {
|
|
if (mApps.setSearchResults(null)) {
|
|
notifyResultChanged();
|
|
}
|
|
|
|
// Clear the search query
|
|
mSearchQueryBuilder.clear();
|
|
mSearchQueryBuilder.clearSpans();
|
|
Selection.setSelection(mSearchQueryBuilder, 0);
|
|
mAppsView.onClearSearchResult();
|
|
}
|
|
|
|
private void notifyResultChanged() {
|
|
mAppsView.onSearchResultsChanged();
|
|
}
|
|
|
|
@Override
|
|
public void setInsets(Rect insets) {
|
|
MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
|
|
mlp.topMargin = insets.top;
|
|
requestLayout();
|
|
}
|
|
|
|
@Override
|
|
public ExtendedEditText getEditText() {
|
|
return this;
|
|
}
|
|
}
|