diff options
author | Yvonne Wong <ywong@cyngn.com> | 2015-12-01 17:04:07 -0800 |
---|---|---|
committer | Tom Powell <zifnab@zifnab06.net> | 2017-03-26 15:52:42 -0700 |
commit | 9c9418bc626d36dce33f2ac6513e7407f07298d4 (patch) | |
tree | 06b1b9bc48a3bbd03c5aa66ab8ee637ace1ae70f | |
parent | 14e1bef375ccb9e719bac1877c53359fad8d9d47 (diff) | |
download | android_packages_apps_Trebuchet-9c9418bc626d36dce33f2ac6513e7407f07298d4.tar.gz android_packages_apps_Trebuchet-9c9418bc626d36dce33f2ac6513e7407f07298d4.tar.bz2 android_packages_apps_Trebuchet-9c9418bc626d36dce33f2ac6513e7407f07298d4.zip |
Reimplement CM Settings Overview Panel Part 3
- Enable dynamic grid resizing
Change-Id: I95a7f20da48e037a94ce5b6191c5597490d91d9d
20 files changed, 987 insertions, 53 deletions
diff --git a/res/drawable/ic_navigation_next.xml b/res/drawable/ic_navigation_next.xml new file mode 100644 index 000000000..571280bb9 --- /dev/null +++ b/res/drawable/ic_navigation_next.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 The CyanogenMod 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="#FFFFFF" + android:pathData="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" /> + <path + android:pathData="M0 0h24v24H0z" /> +</vector>
\ No newline at end of file diff --git a/res/drawable/ic_navigation_prev.xml b/res/drawable/ic_navigation_prev.xml new file mode 100644 index 000000000..f0a6a3b32 --- /dev/null +++ b/res/drawable/ic_navigation_prev.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 The CyanogenMod 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="#FFFFFF" + android:pathData="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" /> + <path + android:pathData="M0 0h24v24H0z" /> +</vector>
\ No newline at end of file diff --git a/res/drawable/listitem_bg.xml b/res/drawable/listitem_bg.xml index 1a1e93d53..55dbfcf27 100644 --- a/res/drawable/listitem_bg.xml +++ b/res/drawable/listitem_bg.xml @@ -16,6 +16,6 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_enabled="true" - android:state_pressed="true" android:drawable="@android:color/white" /> + android:state_pressed="true" android:drawable="@android:color/white" /> <item android:drawable="@color/settings_bg_color" /> </selector> diff --git a/res/drawable/listitem_text.xml b/res/drawable/listitem_text.xml index 9637fd308..d6c2503a6 100644 --- a/res/drawable/listitem_text.xml +++ b/res/drawable/listitem_text.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_enabled="true" - android:state_pressed="true" android:color="@color/slideup_panel_bg_color" /> + android:state_pressed="true" android:color="@color/settings_bg_color" /> <item android:color="@android:color/white" /> </selector> diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml index 3a93365a7..3fe6f893d 100644 --- a/res/layout-land/launcher.xml +++ b/res/layout-land/launcher.xml @@ -18,6 +18,7 @@ <com.android.launcher3.LauncherRootView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:launcher="http://schemas.android.com/apk/res-auto" + xmlns:insettable="http://schemas.android.com/apk/res-auto" android:id="@+id/launcher" android:layout_width="match_parent" android:layout_height="match_parent" @@ -30,6 +31,7 @@ android:layout_height="match_parent" android:visibility="invisible" android:alpha="1.0" + insettable:layout_ignoreInsets="true" android:clipToPadding="false"> <ImageView diff --git a/res/layout/custom_grid_size_dialog.xml b/res/layout/custom_grid_size_dialog.xml new file mode 100644 index 000000000..59a5db484 --- /dev/null +++ b/res/layout/custom_grid_size_dialog.xml @@ -0,0 +1,48 @@ +<!-- + Copyright (C) 2015 The CyanogenMod 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. +--> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" > + + <LinearLayout + android:id="@+id/grid_number_pickers" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerHorizontal="true" + android:orientation="horizontal"> + + <NumberPicker + android:id="@+id/custom_rows" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginRight="@dimen/dialog_padding"/> + + <NumberPicker + android:id="@+id/custom_columns" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="@dimen/dialog_padding"/> + + </LinearLayout> + + <Button + android:id="@+id/dialog_confirm_button" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/dialog_confirm" + android:layout_below="@id/grid_number_pickers" + android:layout_marginTop="@dimen/dialog_padding"/> +</RelativeLayout>
\ No newline at end of file diff --git a/res/layout/dynamic_grid_size_screen.xml b/res/layout/dynamic_grid_size_screen.xml new file mode 100644 index 000000000..85dc992fb --- /dev/null +++ b/res/layout/dynamic_grid_size_screen.xml @@ -0,0 +1,69 @@ +<!-- + Copyright (C) 2015 The CyanogenMod 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. +--> +<com.android.launcher3.InsettableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:insettable="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="center_horizontal|bottom" + android:background="@color/settings_bg_color" + android:orientation="vertical" + android:clickable="true" > + + <LinearLayout + android:id="@+id/dynamic_grid_title" + insettable:layout_ignoreBottomInsets="true" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:background="@drawable/listitem_bg" + android:clickable="true" > + + <ImageView + android:id="@+id/nav_prev" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:adjustViewBounds="true" + android:src="@drawable/ic_navigation_prev" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/grid_size_text" + android:textAllCaps="true" + android:fontFamily="sans-serif-condensed" + android:textColor="@drawable/listitem_text" + android:layout_gravity="center_vertical" + android:textSize="16sp" /> + </LinearLayout> + + <view + insettable:layout_ignoreInsets="true" + class="com.android.launcher3.DynamicGridSizeFragment$GridSizeView" + android:id="@+id/dynamic_grid_size_image" + android:layout_width="150dp" + android:layout_height="150dp" + android:layout_gravity="center_horizontal" + android:layout_marginBottom="@dimen/grid_padding"/> + + <ListView + insettable:layout_ignoreTopInsets="true" + android:id="@+id/dynamic_grid_list" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:listSelector="@android:color/transparent" + android:splitMotionEvents="false"/> +</com.android.launcher3.InsettableLinearLayout> diff --git a/res/layout/overview_panel.xml b/res/layout/overview_panel.xml index 5698c86a9..636e36b89 100644 --- a/res/layout/overview_panel.xml +++ b/res/layout/overview_panel.xml @@ -28,7 +28,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" - android:background="@color/slideup_panel_bg_color" + android:background="@color/settings_bg_color" android:paddingTop="@dimen/overview_panel_top_padding" > <ImageView @@ -45,7 +45,7 @@ <FrameLayout android:orientation="vertical" android:layout_width="match_parent" - android:background="@color/slideup_panel_bg_color" + android:background="@color/settings_bg_color" android:layout_height="match_parent" > <LinearLayout diff --git a/res/layout/settings_pane_list_header.xml b/res/layout/settings_pane_list_header.xml index 2429b9b81..a7d04e36e 100644 --- a/res/layout/settings_pane_list_header.xml +++ b/res/layout/settings_pane_list_header.xml @@ -1,8 +1,23 @@ +<!-- + Copyright (C) 2015 The CyanogenMod 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. +--> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal|bottom" - android:background="@color/slideup_panel_bg_color" + android:background="@color/settings_bg_color" android:paddingLeft="@dimen/overview_panel_list_padding" android:paddingRight="@dimen/overview_panel_list_padding" android:orientation="horizontal" > diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml index e31fed119..9072824ce 100644 --- a/res/values/cm_strings.xml +++ b/res/values/cm_strings.xml @@ -43,6 +43,9 @@ <string name="grid_size_custom">Custom (<xliff:g id="rows">%1$d</xliff:g> \u00d7 <xliff:g id="columns">%2$d</xliff:g>)</string> <string name="preferences_interface_homescreen_custom">Select custom size</string> + <!-- Dialog --> + <string name="dialog_confirm">Confirm</string> + <!-- Home screen search bar --> <string name="home_screen_search_text">Search bar</string> diff --git a/res/values/colors.xml b/res/values/colors.xml index 80c0d6f6d..1b8962170 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -36,7 +36,6 @@ <color name="quantum_panel_text_color_dark">#FFF</color> <color name="quantum_panel_bg_color">#FFF5F5F5</color> <color name="quantum_panel_bg_color_dark">#76000000</color> - <color name="slideup_panel_bg_color">#FF374248</color> <color name="outline_color">#FFFFFFFF</color> @@ -61,7 +60,11 @@ <color name="widgets_cell_color">#263238</color> <!-- CM Settings --> - <color name="settings_header_text">#FF6cd2ea</color> + <color name="settings_bg_color">#424242</color> + <color name="settings_header_text">#00B1E5</color> + + <color name="dynamic_grid_preview_background">#FFFFFFFF</color> + <color name="dynamic_grid_preview_foreground">#FF000000</color> <color name="app_scrubber_highlight_color">@android:color/white</color> <color name="app_scrubber_gray_color">@android:color/darker_gray</color> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 95557d9c5..d73bd33db 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -28,6 +28,9 @@ <dimen name="dynamic_grid_overview_max_icon_zone_height">120dp</dimen> <dimen name="dynamic_grid_overview_bar_item_width">80dp</dimen> <dimen name="dynamic_grid_overview_bar_spacer_width">20dp</dimen> + <dimen name="dialog_padding">10dp</dimen> + <dimen name="grid_padding">15dp</dimen> + <dimen name="grid_custom_text">50dp</dimen> <!-- App Widget resize frame --> <dimen name="default_widget_padding">8dp</dimen> diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 7e9d8f8a7..6115df62f 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -37,7 +37,6 @@ import com.android.launcher3.settings.SettingsProvider; import com.android.launcher3.allapps.AllAppsContainerView; public class DeviceProfile { - public final InvariantDeviceProfile inv; // Device properties diff --git a/src/com/android/launcher3/DynamicGridSizeFragment.java b/src/com/android/launcher3/DynamicGridSizeFragment.java new file mode 100644 index 000000000..103d660dd --- /dev/null +++ b/src/com/android/launcher3/DynamicGridSizeFragment.java @@ -0,0 +1,381 @@ +/* + * Copyright (C) 2014 The CyanogenMod 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; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; +import android.app.Dialog; +import android.app.Fragment; +import android.content.Context; +import android.content.DialogInterface; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.os.Bundle; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.NumberPicker; +import android.widget.TextView; +import com.android.launcher3.settings.SettingsProvider; + +public class DynamicGridSizeFragment extends Fragment + implements NumberPicker.OnValueChangeListener, Dialog.OnDismissListener { + public static final String DYNAMIC_GRID_SIZE_FRAGMENT = "DynamicGridSizeFragment"; + + public static final int MIN_DYNAMIC_GRID_ROWS = 2; + public static final int MIN_DYNAMIC_GRID_COLUMNS = 3; + + GridSizeView mDynamicGrid; + + ListView mListView; + View mCurrentSelection; + GridSizeAdapter mAdapter; + InvariantDeviceProfile.GridSize mCurrentSize; + + Dialog mDialog; + + int mCustomGridRows = 0; + int mCustomGridColumns = 0; + + View.OnClickListener mSettingsItemListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + mCurrentSize = InvariantDeviceProfile.GridSize.getModeForValue((Integer) v.getTag()); + + setCleared(mCurrentSelection); + setSelected(v); + mCurrentSelection = v; + + if (mCurrentSize == InvariantDeviceProfile.GridSize.Custom) { + showNumberPicker(); + } + + ((GridSizeAdapter) mListView.getAdapter()).notifyDataSetChanged(); + + mAdapter.notifyDataSetInvalidated(); + updateGridMetrics(); + } + }; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.dynamic_grid_size_screen, container, false); + mDynamicGrid = (GridSizeView) v.findViewById(R.id.dynamic_grid_size_image); + mListView = (ListView) v.findViewById(R.id.dynamic_grid_list); + + Launcher launcher = (Launcher) getActivity(); + LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) + mListView.getLayoutParams(); + lp.bottomMargin = ((FrameLayout.LayoutParams) launcher.getOverviewPanel() + .findViewById(R.id.settings_container).getLayoutParams()).bottomMargin; + mListView.setLayoutParams(lp); + + LinearLayout titleLayout = (LinearLayout) v.findViewById(R.id.dynamic_grid_title); + titleLayout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + setSize(); + } + }); + + mCurrentSize = InvariantDeviceProfile.GridSize.getModeForValue( + SettingsProvider.getIntCustomDefault(getActivity(), + SettingsProvider.SETTINGS_UI_DYNAMIC_GRID_SIZE, 0)); + + InvariantDeviceProfile grid = getInvariantDeviceProfile(); + mCustomGridRows = grid.numRows; + mCustomGridColumns = grid.numColumns; + + updateGridMetrics(); + + Resources res = getResources(); + int[] valueResIds = { + R.string.grid_size_comfortable, + R.string.grid_size_cozy, + R.string.grid_size_condensed, + R.string.grid_size_custom + }; + mAdapter = new GridSizeAdapter(getActivity(), valueResIds); + mListView.setAdapter(mAdapter); + + // RTL + ImageView navPrev = (ImageView) v.findViewById(R.id.nav_prev); + Configuration config = getResources().getConfiguration(); + if (config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { + navPrev.setImageResource(R.drawable.ic_navigation_next); + } + + return v; + } + + private void updateGridMetrics() { + if (mCurrentSize == InvariantDeviceProfile.GridSize.Custom) { + mDynamicGrid.setMetrics(mCustomGridRows, mCustomGridColumns); + } else { + InvariantDeviceProfile grid = getInvariantDeviceProfile(); + mDynamicGrid.setMetrics(grid.numRowsBase + mCurrentSize.getValue(), + grid.numColumnsBase + mCurrentSize.getValue()); + } + } + + @Override + public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) { + if (enter) { + DisplayMetrics displaymetrics = new DisplayMetrics(); + getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); + int width = displaymetrics.widthPixels; + Configuration config = getResources().getConfiguration(); + final ObjectAnimator anim; + if (config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { + anim = ObjectAnimator.ofFloat(this, "translationX", -width, 0); + } else { + anim = ObjectAnimator.ofFloat(this, "translationX", width, 0); + } + + final View darkPanel = ((Launcher) getActivity()).getDarkPanel(); + darkPanel.setVisibility(View.VISIBLE); + ObjectAnimator anim2 = ObjectAnimator.ofFloat(darkPanel, "alpha", 0.0f, 0.3f); + anim2.start(); + + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd (Animator animation) { + darkPanel.setVisibility(View.GONE); + } + }); + + return anim; + } else { + return super.onCreateAnimator(transit, enter, nextAnim); + } + } + + public void setSize() { + ((Launcher) getActivity()).setDynamicGridSize(mCurrentSize); + } + + private void setSelected(View v) { + v.setBackgroundColor(Color.WHITE); + TextView t = (TextView) v.findViewById(R.id.item_name); + t.setTextColor(getResources().getColor(R.color.settings_bg_color)); + } + + private void setCleared(View v) { + v.setBackgroundColor(getResources().getColor(R.color.settings_bg_color)); + TextView t = (TextView) v.findViewById(R.id.item_name); + t.setTextColor(Color.WHITE); + } + + private void showNumberPicker() { + mDialog = new Dialog(getActivity()); + mDialog.setTitle(getResources().getString( + R.string.preferences_interface_homescreen_custom)); + mDialog.setContentView(R.layout.custom_grid_size_dialog); + + NumberPicker nPRows = (NumberPicker) mDialog.findViewById(R.id.custom_rows); + NumberPicker nPColumns = (NumberPicker) mDialog.findViewById(R.id.custom_columns); + + InvariantDeviceProfile grid = getInvariantDeviceProfile(); + int rows = grid.numRowsBase; + int columns = grid.numColumnsBase; + + nPRows.setMinValue(Math.max(MIN_DYNAMIC_GRID_ROWS, rows - InvariantDeviceProfile.GRID_SIZE_MIN)); + nPRows.setMaxValue(rows + InvariantDeviceProfile.GRID_SIZE_MAX); + nPRows.setValue(mCustomGridRows); + nPRows.setWrapSelectorWheel(false); + nPRows.setOnValueChangedListener(this); + nPRows.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS); + + nPColumns.setMinValue(Math.max(MIN_DYNAMIC_GRID_COLUMNS, + columns - InvariantDeviceProfile.GRID_SIZE_MIN)); + nPColumns.setMaxValue(columns + InvariantDeviceProfile.GRID_SIZE_MAX); + nPColumns.setValue(mCustomGridColumns); + nPColumns.setWrapSelectorWheel(false); + nPColumns.setOnValueChangedListener(this); + nPColumns.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS); + + Button button = (Button) mDialog.findViewById(R.id.dialog_confirm_button); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mDialog != null) { + mDialog.dismiss(); + } + } + }); + + mDialog.setOnDismissListener(this); + mDialog.show(); + } + + @Override + public void onPause() { + super.onPause(); + if (mDialog != null) { + mDialog.dismiss(); + } + } + + @Override + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + if (picker.getId() == R.id.custom_rows) { + mCustomGridRows = newVal; + } else if (picker.getId() == R.id.custom_columns) { + mCustomGridColumns = newVal; + } + } + + @Override + public void onDismiss(DialogInterface dialog) { + SettingsProvider.putInt(getActivity(), + SettingsProvider.SETTINGS_UI_HOMESCREEN_ROWS, mCustomGridRows); + SettingsProvider.putInt(getActivity(), + SettingsProvider.SETTINGS_UI_HOMESCREEN_COLUMNS, mCustomGridColumns); + + mAdapter.notifyDataSetInvalidated(); + mDynamicGrid.setMetrics(mCustomGridRows, mCustomGridColumns); + } + + private class GridSizeAdapter extends BaseAdapter { + Context mContext; + int[] mTitleResIds; + + public GridSizeAdapter(Context context, int[] resIds) { + mContext = context; + mTitleResIds = resIds; + } + + @Override + public int getCount() { + return mTitleResIds.length; + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public Object getItem(int position) { + return mContext.getString(mTitleResIds[position]); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + if (convertView == null) { + LayoutInflater inflater = (LayoutInflater) + mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + convertView = inflater.inflate(R.layout.settings_pane_list_item, parent, false); + } + + TextView textView = (TextView) convertView.findViewById(R.id.item_name); + + // RTL + Configuration config = getResources().getConfiguration(); + if (config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { + textView.setGravity(Gravity.RIGHT); + } + + // Set selected state + if (position == mCurrentSize.getValue()) { + if (mCurrentSelection != null) { + setCleared(mCurrentSelection); + } + mCurrentSelection = convertView; + setSelected(mCurrentSelection); + } + + if (position == InvariantDeviceProfile.GridSize.Custom.getValue()) { + InvariantDeviceProfile grid = getInvariantDeviceProfile(); + + int rows = SettingsProvider.getIntCustomDefault(getActivity(), + SettingsProvider.SETTINGS_UI_HOMESCREEN_ROWS, grid.numRowsBase); + int columns = SettingsProvider.getIntCustomDefault(getActivity(), + SettingsProvider.SETTINGS_UI_HOMESCREEN_COLUMNS, grid.numColumnsBase); + textView.setText(mContext.getString(mTitleResIds[position], rows, columns)); + } else { + textView.setText(mTitleResIds[position]); + } + + convertView.setOnClickListener(mSettingsItemListener); + convertView.setTag(position); + return convertView; + } + } + + private InvariantDeviceProfile getInvariantDeviceProfile() { + LauncherAppState app = LauncherAppState.getInstance(); + return app.getInvariantDeviceProfile(); + } + + private static class GridSizeView extends View { + private int mRows = 0, mColumns = 0; + private Paint mForegroundPaint; + private int mBackgroundColor; + + public GridSizeView(Context context, AttributeSet attrs) { + super(context, attrs); + Resources res = context.getResources(); + + mForegroundPaint = new Paint(); + mForegroundPaint.setColor(res.getColor(R.color.dynamic_grid_preview_foreground)); + mBackgroundColor = res.getColor(R.color.dynamic_grid_preview_background); + } + + public void setMetrics(int rows, int columns) { + mRows = rows; + mColumns = columns; + invalidate(); + } + + @Override + protected void onDraw(Canvas canvas) { + float width = getWidth() - getPaddingLeft() - getPaddingRight(); + float height = getHeight() - getPaddingTop() - getPaddingBottom(); + float xOffset = getPaddingLeft(); + float yOffset = getPaddingTop(); + + canvas.drawColor(mBackgroundColor); + + // Draw rows + for (int i = 1; i < mRows; i++) { + float yPos = yOffset + height / mRows * i; + canvas.drawLine(xOffset, yPos, xOffset + width, yPos, mForegroundPaint); + } + + // Draw columns + for (int j = 1; j < mColumns; j++) { + float xPos = xOffset + width / mColumns * j; + canvas.drawLine(xPos, yOffset, xPos, yOffset + height, mForegroundPaint); + } + } + } +} diff --git a/src/com/android/launcher3/InsettableLinearLayout.java b/src/com/android/launcher3/InsettableLinearLayout.java new file mode 100644 index 000000000..8f64713e5 --- /dev/null +++ b/src/com/android/launcher3/InsettableLinearLayout.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2015 The CyanogenMod 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; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; + +public class InsettableLinearLayout extends LinearLayout implements + ViewGroup.OnHierarchyChangeListener, Insettable { + + protected Rect mInsets = new Rect(); + + public InsettableLinearLayout(Context context, AttributeSet attrs) { + super(context, attrs); + setOnHierarchyChangeListener(this); + } + + public void setLinearLayoutChildInsets(View child, Rect newInsets, Rect oldInsets) { + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + + if (child instanceof Insettable) { + ((Insettable) child).setInsets(newInsets); + } else if (!lp.ignoreInsets) { + if (!lp.ignoreTopInsets) { + lp.topMargin += (newInsets.top - oldInsets.top); + } + lp.leftMargin += (newInsets.left - oldInsets.left); + lp.rightMargin += (newInsets.right - oldInsets.right); + if (!lp.ignoreBottomInsets) { + lp.bottomMargin += (newInsets.bottom - oldInsets.bottom); + } + } + child.setLayoutParams(lp); + } + + @Override + public void setInsets(Rect insets) { + final int n = getChildCount(); + for (int i = 0; i < n; i++) { + final View child = getChildAt(i); + setLinearLayoutChildInsets(child, insets, mInsets); + } + mInsets.set(insets); + } + + @Override + public LayoutParams generateLayoutParams(AttributeSet attrs) { + return new LayoutParams(getContext(), attrs); + } + + @Override + protected LayoutParams generateDefaultLayoutParams() { + return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + } + + // Override to allow type-checking of LayoutParams. + @Override + protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { + return p instanceof LayoutParams; + } + + @Override + protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { + return new LayoutParams(p); + } + + public static class LayoutParams extends LinearLayout.LayoutParams { + boolean ignoreInsets = false; + boolean ignoreTopInsets = false; + boolean ignoreBottomInsets = false; + + public LayoutParams(Context c, AttributeSet attrs) { + super(c, attrs); + TypedArray a = c.obtainStyledAttributes(attrs, + R.styleable.InsettableLinearLayout_Layout); + ignoreInsets = a.getBoolean( + R.styleable.InsettableLinearLayout_Layout_layout_ignoreInsets, false); + ignoreTopInsets = a.getBoolean( + R.styleable.InsettableLinearLayout_Layout_layout_ignoreTopInsets, false); + ignoreBottomInsets = a.getBoolean( + R.styleable.InsettableLinearLayout_Layout_layout_ignoreBottomInsets, false); + a.recycle(); + } + + public LayoutParams(int width, int height) { + super(width, height); + } + + public LayoutParams(ViewGroup.LayoutParams lp) { + super(lp); + } + } + + @Override + public void onChildViewAdded(View parent, View child) { + setLinearLayoutChildInsets(child, mInsets, new Rect()); + } + + @Override + public void onChildViewRemoved(View parent, View child) { + } + +} diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 6d4d95292..a03cc31f2 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -33,6 +33,38 @@ import java.util.Comparator; public class InvariantDeviceProfile { + public enum GridSize { + Comfortable(0), + Cozy(1), + Condensed(2), + Custom(3); + + private final int mValue; + GridSize(int value) { + mValue = value; + } + + public int getValue() { + return mValue; + } + + public static GridSize getModeForValue(int value) { + switch (value) { + case 1: + return Cozy; + case 2: + return Condensed; + case 3: + return Custom; + default : + return Comfortable; + } + } + } + + public final static int GRID_SIZE_MAX = 3; + public final static int GRID_SIZE_MIN = 2; + // This is a static that we use for the default icon size on a 4/5-inch phone private static float DEFAULT_ICON_SIZE_DP = 60; @@ -56,6 +88,8 @@ public class InvariantDeviceProfile { */ public int numRows; public int numColumns; + public int numRowsBase; + public int numColumnsBase; /** * The minimum number of predicted apps in all apps. @@ -148,6 +182,29 @@ public class InvariantDeviceProfile { numFolderColumns = closestProfile.numFolderColumns; minAllAppsPredictionColumns = closestProfile.minAllAppsPredictionColumns; + numRowsBase = numRows; + int gridResize = SettingsProvider.getIntCustomDefault(context, + SettingsProvider.SETTINGS_UI_DYNAMIC_GRID_SIZE, 0); + if (GridSize.getModeForValue(gridResize) != GridSize.Custom) { + numRows += gridResize; + } else { + int iTempNumberOfRows = SettingsProvider.getIntCustomDefault(context, + SettingsProvider.SETTINGS_UI_HOMESCREEN_ROWS, numRows); + if (iTempNumberOfRows > 0) { + numRows = iTempNumberOfRows; + } + } + numColumnsBase = numColumns; + if (GridSize.getModeForValue(gridResize) != GridSize.Custom) { + numColumns += gridResize; + } else { + int iTempNumberOfColumns = SettingsProvider.getIntCustomDefault(context, + SettingsProvider.SETTINGS_UI_HOMESCREEN_COLUMNS, numColumns); + if (iTempNumberOfColumns > 0) { + numColumns = iTempNumberOfColumns; + } + } + iconSize = interpolatedDeviceProfileOut.iconSize; iconBitmapSize = Utilities.pxFromDp(iconSize, dm); iconTextSize = interpolatedDeviceProfileOut.iconTextSize; diff --git a/src/com/android/launcher3/ItemInfo.java b/src/com/android/launcher3/ItemInfo.java index f7e0ea488..c7729ffe6 100644 --- a/src/com/android/launcher3/ItemInfo.java +++ b/src/com/android/launcher3/ItemInfo.java @@ -115,6 +115,12 @@ public class ItemInfo { public CharSequence contentDescription; /** + * Indicates that this item has had it's position changed + * because the grid size was made smaller and it could no longer fit. + */ + public boolean wasMovedDueToReducedSpace = false; + + /** * The position of the item in a drag-and-drop operation. */ public int[] dropPos = null; diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 15373c20b..8f3bbf578 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -32,7 +32,6 @@ import android.app.AlertDialog; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; -import android.app.Dialog; import android.app.SearchManager; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetManager; @@ -258,6 +257,7 @@ public class Launcher extends Activity private DragController mDragController; private View mWeightWatcher; protected HiddenFolderFragment mHiddenFolderFragment; + private DynamicGridSizeFragment mDynamicGridSizeFragment; private AppWidgetManagerCompat mAppWidgetManager; private LauncherAppWidgetHost mAppWidgetHost; @@ -273,6 +273,7 @@ public class Launcher extends Activity @Thunk Hotseat mHotseat; private ViewGroup mOverviewPanel; + private View mDarkPanel; OverviewSettingsPanel mOverviewSettingsPanel; private View mAllAppsButton; @@ -369,6 +370,20 @@ public class Launcher extends Activity private BubbleTextView mWaitingForResume; private boolean mReloadLauncher; + private boolean mResizeGridRequired; + + public Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator arg0) {} + @Override + public void onAnimationRepeat(Animator arg0) {} + @Override + public void onAnimationEnd(Animator arg0) { + mDarkPanel.setVisibility(View.GONE); + } + @Override + public void onAnimationCancel(Animator arg0) {} + }; // Preferences private boolean mHideIconLabels; @@ -1120,6 +1135,13 @@ public class Launcher extends Activity mLauncherCallbacks.onResume(); } + // Close out fragments + Fragment gridFragment = getFragmentManager().findFragmentByTag( + DynamicGridSizeFragment.DYNAMIC_GRID_SIZE_FRAGMENT); + if (gridFragment != null) { + mDynamicGridSizeFragment.setSize(); + } + reloadLauncherIfNeeded(); //Close out Fragments @@ -1439,6 +1461,8 @@ public class Launcher extends Activity mOverviewSettingsPanel = new OverviewSettingsPanel(this); mOverviewSettingsPanel.initializeAdapter(); + mDarkPanel = mOverviewPanel.findViewById(R.id.dark_panel); + mWidgetsButton = findViewById(R.id.widget_button); mWidgetsButton.setOnClickListener(new OnClickListener() { @Override @@ -1759,11 +1783,13 @@ public class Launcher extends Activity } /** - * Sets the reload launcher flag to true, which will reload the launcher at the next appropriate - * time. + * Sets the reload launcher flag to true and the resize grid flag to the parameter value, + * which will reload the launcher/grid size at the next appropriate time. + * @param shouldResizeGrid Indicates whether the grid needs to be resized. */ - public void setReloadLauncher() { + public void setReloadLauncher(boolean shouldResizeGrid) { mReloadLauncher = true; + mResizeGridRequired = shouldResizeGrid; } /** @@ -1774,6 +1800,7 @@ public class Launcher extends Activity if (mReloadLauncher) { reloadLauncher(mWorkspace.getCurrentPage()); mReloadLauncher = false; + mResizeGridRequired = false; return true; } @@ -1797,12 +1824,76 @@ public class Launcher extends Activity // Reload mModel.resetLoadedState(true, true); - mModel.startLoader(page, LauncherModel.LOADER_FLAG_NONE); + int flag = mResizeGridRequired ? LauncherModel.LOADER_FLAG_RESIZE_GRID : + LauncherModel.LOADER_FLAG_NONE; + mModel.startLoader(page, flag); mWorkspace.updateCustomContentVisibility(); mAppsView.reset(); } + /** + * Replaces currently added fragments in the launcher layout with a + * {@link DynamicGridSizeFragment}. + */ + public void onClickDynamicGridSizeButton() { + FragmentManager fragmentManager = getFragmentManager(); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + + mDynamicGridSizeFragment = new DynamicGridSizeFragment(); + fragmentTransaction.replace(R.id.launcher, mDynamicGridSizeFragment, + DynamicGridSizeFragment.DYNAMIC_GRID_SIZE_FRAGMENT); + fragmentTransaction.commit(); + } + + /** + * If the new grid size is different from the current grid size, the launcher will be reloaded + * and the overview settings panel updated with the new grid size value. + * @param size The new grid size to set the workspace to. + */ + public void setDynamicGridSize(InvariantDeviceProfile.GridSize size) { + int gridSize = SettingsProvider.getIntCustomDefault(this, + SettingsProvider.SETTINGS_UI_DYNAMIC_GRID_SIZE, 0); + boolean customValuesChanged = false; + if (gridSize == size.getValue() && size == InvariantDeviceProfile.GridSize.Custom) { + int tempRows = SettingsProvider.getIntCustomDefault(this, + SettingsProvider.SETTINGS_UI_HOMESCREEN_ROWS, mDeviceProfile.inv.numRows); + int tempColumns = SettingsProvider.getIntCustomDefault(this, + SettingsProvider.SETTINGS_UI_HOMESCREEN_COLUMNS, mDeviceProfile.inv.numColumns); + if (tempColumns != mDeviceProfile.inv.numColumns || + tempRows != mDeviceProfile.inv.numRows) { + customValuesChanged = true; + } + } + + if (gridSize != size.getValue() || customValuesChanged) { + SettingsProvider.putInt(this, + SettingsProvider.SETTINGS_UI_DYNAMIC_GRID_SIZE, size.getValue()); + + setReloadLauncher(true); + } + + mOverviewSettingsPanel.notifyDataSetInvalidated(); + + FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); + Configuration config = getResources().getConfiguration(); + if(config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { + fragmentTransaction + .setCustomAnimations(0, R.anim.exit_out_left); + } else { + fragmentTransaction + .setCustomAnimations(0, R.anim.exit_out_right); + } + fragmentTransaction + .remove(mDynamicGridSizeFragment).commit(); + + mDarkPanel.setVisibility(View.VISIBLE); + ObjectAnimator anim = ObjectAnimator.ofFloat( + mDarkPanel, "alpha", 0.3f, 0.0f); + anim.start(); + anim.addListener(mAnimatorListener); + } + @Override public void onAttachedToWindow() { super.onAttachedToWindow(); @@ -2000,6 +2091,10 @@ public class Launcher extends Activity return mOverviewPanel; } + public View getDarkPanel() { + return mDarkPanel; + } + public SearchDropTargetBar getSearchDropTargetBar() { return mSearchDropTargetBar; } @@ -2627,7 +2722,14 @@ public class Launcher extends Activity } else if (isWidgetsViewVisible()) { showOverviewMode(true); } else if (mWorkspace.isInOverviewMode()) { - showWorkspace(true); + Fragment gridFragment = getFragmentManager().findFragmentByTag( + DynamicGridSizeFragment.DYNAMIC_GRID_SIZE_FRAGMENT); + if (gridFragment != null) { + mDynamicGridSizeFragment.setSize(); + } + else { + showWorkspace(true); + } } else if (mWorkspace.getOpenFolder() != null) { Folder openFolder = mWorkspace.getOpenFolder(); if (openFolder.isEditingName()) { @@ -3516,6 +3618,8 @@ public class Launcher extends Activity } void showWorkspace(int snapToPage, boolean animated, Runnable onCompleteRunnable) { + reloadLauncherIfNeeded(); + boolean changed = mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL; if (changed) { @@ -3544,6 +3648,8 @@ public class Launcher extends Activity } void showOverviewMode(boolean animated) { + reloadLauncherIfNeeded(); + mWorkspace.setVisibility(View.VISIBLE); mStateTransitionAnimation.startAnimationToWorkspace(mState, mWorkspace.getState(), Workspace.State.OVERVIEW, @@ -4293,6 +4399,10 @@ public class Launcher extends Activity if (mLauncherCallbacks != null) { mLauncherCallbacks.finishBindingItems(false); } + + if (mWorkspace.isInOverviewMode()) { + reloadLauncherIfNeeded(); + } } private void sendLoadingCompleteBroadcastIfNecessary() { @@ -4978,14 +5088,6 @@ public class Launcher extends Activity AnimationDrawable frameAnimation = (AnimationDrawable) mAnimatedArrow.getBackground(); frameAnimation.start(); - - /*if (mLauncher.updateGridIfNeeded()) { - Workspace workspace = mLauncher.getWorkspace(); - if (workspace.isInOverviewMode()) { - workspace.setChildrenOutlineAlpha(1.0f); - mLauncher.mSearchDropTargetBar.hideSearchBar(false); - } - }*/ } @Override diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index c3ad6a8a1..4f2491f8d 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -1112,7 +1112,7 @@ public class LauncherModel extends BroadcastReceiver /** * Removes the specified items from the database * @param context - * @param item + * @param items */ static void deleteItemsFromDatabase(Context context, final ArrayList<? extends ItemInfo> items) { final ContentResolver cr = context.getContentResolver(); @@ -1644,7 +1644,7 @@ public class LauncherModel extends BroadcastReceiver // check & update map of what's occupied; used to discard overlapping/invalid items private boolean checkItemPlacement(LongArrayMap<ItemInfo[][]> occupied, ItemInfo item, - ArrayList<Long> workspaceScreens) { + ArrayList<Long> workspaceScreens, boolean shouldResizeAndUpdateDB) { LauncherAppState app = LauncherAppState.getInstance(); InvariantDeviceProfile profile = app.getInvariantDeviceProfile(); final int countX = profile.numColumns; @@ -1700,26 +1700,67 @@ public class LauncherModel extends BroadcastReceiver return true; } - if (!occupied.containsKey(item.screenId)) { - ItemInfo[][] items = new ItemInfo[countX + 1][countY + 1]; - occupied.put(item.screenId, items); + // If the current item's position lies outside of the bounds + // of the current grid size, attempt to place it in the next + // available position. + if (item.cellX < 0 || item.cellY < 0 || item.cellX + item.spanX > countX + || item.cellY + item.spanY > countY) { + // If we won't be resizing the grid, then just return, this item does not fit. + if (!shouldResizeAndUpdateDB) { + Log.e(TAG, "Error loading shortcut " + item + + " into cell (" + containerIndex + "-" + item.screenId + ":" + + item.cellX + "," + item.cellY + + ") out of screen bounds ( " + countX + "x" + countY + ")"); + return false; + } + + if (item.itemType != LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET) { + // Place the item at 0 0 of screen 1 + // if items overlap here, they will be moved later on + item.cellX = 0; + item.cellY = 0; + item.screenId = 1; + item.wasMovedDueToReducedSpace = true; + item.requiresDbUpdate = true; + } else { + // see if widget can be shrunk to fit a screen, if not, just remove it + if (item.minSpanX > countX || item.minSpanY > countY) { + return false; + } + // if the widget is larger than the grid, shrink it down + if (item.cellX + item.spanX > countX) { + item.cellX = 0; + item.spanY = (item.spanY / 2) > 0 ? item.spanY / 2 : 1; + item.spanX = item.minSpanX; + item.requiresDbUpdate = true; + item.wasMovedDueToReducedSpace = true; + } + if (item.cellY + item.spanY > countY) { + item.cellY = 0; + item.spanY = countY; + item.requiresDbUpdate = true; + item.wasMovedDueToReducedSpace = true; + } + if (item.cellY + item.spanY == countY && item.cellX + item.spanX == countX) { + // if the widget is the size of the grid, make a screen all it's own. + item.screenId = sBgWorkspaceScreens.size() + 1; + } + } + } else { + item.wasMovedDueToReducedSpace = false; + item.requiresDbUpdate = true; } - final ItemInfo[][] screens = occupied.get(item.screenId); - if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && - item.cellX < 0 || item.cellY < 0 || - item.cellX + item.spanX > countX || item.cellY + item.spanY > countY) { - Log.e(TAG, "Error loading shortcut " + item - + " into cell (" + containerIndex + "-" + item.screenId + ":" - + item.cellX + "," + item.cellY - + ") out of screen bounds ( " + countX + "x" + countY + ")"); - return false; + if (!occupied.containsKey(item.screenId)) { + ItemInfo[][] items = new ItemInfo[countX][countY]; + occupied.put(item.screenId, items); } + ItemInfo[][] screens = occupied.get(item.screenId); // Check if any workspace icons overlap with each other for (int x = item.cellX; x < (item.cellX+item.spanX); x++) { for (int y = item.cellY; y < (item.cellY+item.spanY); y++) { - if (screens[x][y] != null) { + if (!shouldResizeAndUpdateDB && screens[x][y] != null) { Log.e(TAG, "Error loading shortcut " + item + " into cell (" + containerIndex + "-" + item.screenId + ":" + x + "," + y @@ -1732,6 +1773,16 @@ public class LauncherModel extends BroadcastReceiver for (int x = item.cellX; x < (item.cellX+item.spanX); x++) { for (int y = item.cellY; y < (item.cellY+item.spanY); y++) { screens[x][y] = item; + if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET + && shouldResizeAndUpdateDB) { + // fill up the entire grid where the widget technically is + for (int spanX = x; spanX < item.spanX; spanX++) { + screens[spanX][y] = item; + for (int spanY = y; spanY < item.spanX; spanY++) { + screens[spanX][spanY] = item; + } + } + } } } @@ -1765,6 +1816,8 @@ public class LauncherModel extends BroadcastReceiver int countX = profile.numColumns; int countY = profile.numRows; + boolean shouldResize = ((mFlags & LOADER_FLAG_RESIZE_GRID) != 0); + if (MigrateFromRestoreTask.ENABLED && MigrateFromRestoreTask.shouldRunTask(mContext)) { long migrationStartTime = System.currentTimeMillis(); Log.v(TAG, "Starting workspace migration after restore"); @@ -2076,7 +2129,8 @@ public class LauncherModel extends BroadcastReceiver } // check & update map of what's occupied - if (!checkItemPlacement(occupied, info, sBgWorkspaceScreens)) { + if (!checkItemPlacement(occupied, info, sBgWorkspaceScreens, + shouldResize)) { itemsToRemove.add(id); break; } @@ -2127,7 +2181,8 @@ public class LauncherModel extends BroadcastReceiver folderInfo.options = c.getInt(optionsIndex); // check & update map of what's occupied - if (!checkItemPlacement(occupied, folderInfo, sBgWorkspaceScreens)) { + if (!checkItemPlacement(occupied, folderInfo, sBgWorkspaceScreens, + shouldResize)) { itemsToRemove.add(id); break; } @@ -2254,7 +2309,8 @@ public class LauncherModel extends BroadcastReceiver appWidgetInfo.container = container; // check & update map of what's occupied - if (!checkItemPlacement(occupied, appWidgetInfo, sBgWorkspaceScreens)) { + if (!checkItemPlacement(occupied, appWidgetInfo, + sBgWorkspaceScreens, shouldResize)) { itemsToRemove.add(id); break; } @@ -2359,6 +2415,17 @@ public class LauncherModel extends BroadcastReceiver updateWorkspaceScreenOrder(context, sBgWorkspaceScreens); } + // If any items have been shifted and require a DB update, update them in the DB. + if (shouldResize) { + for (ItemInfo info : sBgWorkspaceItems) { + if (info != null && info.requiresDbUpdate) { + info.requiresDbUpdate = false; + LauncherModel.modifyItemInDatabase(mContext, info, info.container, + info.screenId, info.cellX, info.cellY, info.spanX, info.spanY); + } + } + } + if (DEBUG_LOADERS) { Log.d(TAG, "loaded workspace in " + (SystemClock.uptimeMillis()-t) + "ms"); Log.d(TAG, "workspace layout: "); diff --git a/src/com/android/launcher3/list/SettingsPinnedHeaderAdapter.java b/src/com/android/launcher3/list/SettingsPinnedHeaderAdapter.java index 1dcc91db6..533e64d20 100644 --- a/src/com/android/launcher3/list/SettingsPinnedHeaderAdapter.java +++ b/src/com/android/launcher3/list/SettingsPinnedHeaderAdapter.java @@ -16,6 +16,8 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.OverviewSettingsPanel; import com.android.launcher3.R; @@ -88,7 +90,6 @@ public class SettingsPinnedHeaderAdapter extends PinnedHeaderListAdapter { Resources res = mLauncher.getResources(); - boolean current; String state; @@ -119,9 +120,9 @@ public class SettingsPinnedHeaderAdapter extends PinnedHeaderListAdapter { : res.getString(R.string.setting_state_off); ((TextView) v.findViewById(R.id.item_state)).setText(state); break; - /*case 3: + case 3: updateDynamicGridSizeSettingsItem(v); - break;*/ + break; default: ((TextView) v.findViewById(R.id.item_state)).setText(""); } @@ -173,8 +174,8 @@ public class SettingsPinnedHeaderAdapter extends PinnedHeaderListAdapter { return mPinnedHeaderCount; } - /*public void updateDynamicGridSizeSettingsItem(View v) { - DeviceProfile.GridSize gridSize = DeviceProfile.GridSize.getModeForValue( + public void updateDynamicGridSizeSettingsItem(View v) { + InvariantDeviceProfile.GridSize gridSize = InvariantDeviceProfile.GridSize.getModeForValue( SettingsProvider.getIntCustomDefault(mLauncher, SettingsProvider.SETTINGS_UI_DYNAMIC_GRID_SIZE, 0)); String state = ""; @@ -198,7 +199,7 @@ public class SettingsPinnedHeaderAdapter extends PinnedHeaderListAdapter { break; } ((TextView) v.findViewById(R.id.item_state)).setText(state); - }*/ + } OnClickListener mSettingsItemListener = new OnClickListener() { @@ -212,23 +213,23 @@ public class SettingsPinnedHeaderAdapter extends PinnedHeaderListAdapter { switch (position) { case 0: updateSearchBarVisibility(v); - mLauncher.setReloadLauncher(); + mLauncher.setReloadLauncher(false); break; case 1: onIconLabelsBooleanChanged(v, SettingsProvider.SETTINGS_UI_HOMESCREEN_HIDE_ICON_LABELS, R.bool.preferences_interface_homescreen_hide_icon_labels_default); - mLauncher.setReloadLauncher(); + mLauncher.setReloadLauncher(false); break; case 2: onSettingsBooleanChanged(v, SettingsProvider.SETTINGS_UI_HOMESCREEN_SCROLLING_WALLPAPER_SCROLL, R.bool.preferences_interface_homescreen_scrolling_wallpaper_scroll_default); - mLauncher.setReloadLauncher(); + mLauncher.setReloadLauncher(false); break; - /*case 3: + case 3: mLauncher.onClickDynamicGridSizeButton(); - break;*/ + break; } break; case OverviewSettingsPanel.DRAWER_SETTINGS_POSITION: @@ -237,7 +238,7 @@ public class SettingsPinnedHeaderAdapter extends PinnedHeaderListAdapter { onIconLabelsBooleanChanged(v, SettingsProvider.SETTINGS_UI_DRAWER_HIDE_ICON_LABELS, R.bool.preferences_interface_drawer_hide_icon_labels_default); - mLauncher.setReloadLauncher(); + mLauncher.setReloadLauncher(false); break; } break; @@ -247,7 +248,7 @@ public class SettingsPinnedHeaderAdapter extends PinnedHeaderListAdapter { onSettingsBooleanChanged(v, SettingsProvider.SETTINGS_UI_GENERAL_ICONS_LARGE, R.bool.preferences_interface_general_icons_large_default); - mLauncher.setReloadLauncher(); + mLauncher.setReloadLauncher(false); break; /*case 1: Intent intent = new Intent(); |