Add back DSLV / ActionListViewSettings

Contains updates by Griffin Millender <griffinn.millender@gmail.com> and
the SlimROMs team

AICPfy:
- make it play better with themes
- bring it to Oreo
- Update SettingsActivity to forward extras from PreferenceScreen to the new fragment
  (allows using DSLV from xml)

Change-Id: I7514cdfa3603ed6e24deeb251875a716a52a02b1
This commit is contained in:
Lars Greiss
2017-10-14 12:40:52 +02:00
committed by Hung Phan
parent 7a81100ef2
commit 316b875415
15 changed files with 5385 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="36dp"
android:height="36dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?android:attr/textColorSecondary"
android:pathData="M20 9H4v2h16V9zM4 15h16v-2H4v2z" />
</vector>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<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="?android:attr/textColorPrimary"
android:pathData="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
<path
android:pathData="M0 0h24v24H0z" />
</vector>

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 Slimroms
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.
-->
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:paddingTop="8dip"
android:paddingBottom="8dip" >
<ImageView
android:id="@id/drag_handle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/dslv_ic_grabber"
android:layout_marginEnd="8dip"
android:layout_gravity="center_vertical"
android:scaleType="centerInside"
android:contentDescription="@null" />
<LinearLayout
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_gravity="fill_horizontal|center_vertical"
android:orientation="vertical"
android:paddingRight="5dp">
<TextView
android:id="@+id/click_action_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_horizontal"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textAlignment="viewStart" />
<TextView
android:id="@+id/longpress_action_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_horizontal"
android:layout_marginTop="2dip"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textAlignment="viewStart" />
</LinearLayout>
<ImageView
android:id="@+id/icon"
android:layout_width="36dip"
android:layout_height="36dip"
android:layout_marginEnd="8dip"
android:layout_gravity="center_vertical"
android:scaleType="centerInside"
android:contentDescription="@null" />
</GridLayout>

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 Slimroms
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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</LinearLayout>
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:visibility="gone"
android:background="?android:attr/listDivider"/>
<TextView
android:id="@+id/disable_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:text="@string/shortcut_action_disable_message"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone" />
<com.blissroms.blissify.preferences.dslv.DragSortListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:paddingLeft="0dp"
android:layout_margin="0dp"
android:dividerHeight="1dp"
settings:dragEnabled="true"
settings:collapsedHeight="2dp"
settings:dragScrollStart="0.33"
settings:maxDragScrollSpeed="0.5"
settings:floatAlpha="0.6"
settings:slideShuffleSpeed="0.3"
settings:trackDragSort="false"
settings:useDefaultController="true"
settings:dragHandleId="@id/drag_handle"
settings:sortEnabled="true"
settings:removeEnabled="true"
settings:dragStartMode="onMove"
settings:removeMode="flingRemove"
settings:floatBackgroundColor="?android:attr/colorBackgroundFloating" />
</LinearLayout>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Slim lockscreen shortcuts -->
<string name="shortcut_action_none">Không</string>
<string name="shortcut_action_longpress">Nhấn giữ:</string>
<string name="shortcut_action_select_action_longpress">Chọn một hành động khi chạm giữ:</string>
<string name="shortcut_action_select_action">Chọn hành động:</string>
<string name="shortcut_action_select_action_newaction">Chọn hành động mới:</string>
<string name="shortcut_action_reset">Thiết lập lại</string>
<string name="shortcut_action_add">Thêm</string>
<string name="shortcut_action_max">Đã đạt tới kích thước tối đa mục</string>
<string name="shortcut_action_warning">Khuyến cáo</string>
<string name="shortcut_action_warning_message">Không thể xóa mục sau cùng</string>
<string name="shortcut_action_disable_message">Đã tắt\nThêm một mục để kích hoạt tính năng này</string>
<string name="shortcut_image_not_valid">Các ứng dụng đã chọn không trả về một biểu tượng hợp lệ hoặc không hỗ trợ hình ảnh cắt xén. Hãy sử dụng một ứng dụng.</string>
<string name="shortcut_duplicate_entry">Các hành động đã chọn không thể được thêm vào hai lần</string>
<string name="shortcut_action_help_shortcut">phím tắt</string>
<string name="shortcut_action_help_button">phím</string>
<string name="shortcut_action_help_app">ứng dụng</string>
<string name="shortcut_action_help_icon">, trong khi lựa chọn biểu tượng sẽ hiện tùy chọn</string>
<string name="shortcut_action_help_main">Để thêm một %1$s, hãy chọn biểu tượng Thêm. Một khi một %1$s được thêm, chọn hàng sẽ thay đổi đối tượng%2$s\n\nĐể gỡ bỏ một %1$s, vuốt theo chiều ngang sang trái hoặc phảii. Để gọi lại một %1$s trong danh sách bằng cách kéo theo chiều dọc neo bên trái.\n\nĐể xóa hoặc thiết lập lại về mặc định, chọn biểu tượng Thiết lập lại.</string>
<string name="shortcut_action_help_delete_last_entry">Loại bỏ mọi %1$s trong danh sách sẽ tắt tính năng hoàn toàn.</string>
<string name="shortcut_action_help_pie_second_layer_delete_last_entry">Loại bỏ mọi %1$s trong danh sách sẽ tắt tính năng hoàn toàn.</string>
<string name="shortcuts_applications">Ứng dụng</string>
<string name="shortcuts_select_custom_app_title">Chọn ứng dụng tùy chỉnh</string>
<string name="shortcuts_icon_picker_type">Chọn loại biểu tượng:</string>
<string name="shortcuts_icon_default">Mặc định</string>
<string name="shortcuts_icon_custom">Bộ sưu tập</string>
<string name="reset_message">Đặt lại tất cả các mục về mặc định?</string>
<string name="help">Trợ giúp</string>
<string name="shortcut_action_app">Tuỳ chỉnh ứng dụng</string>
<string name="shortcut_action_home">Trang chủ</string>
<string name="shortcut_action_back">Quay lại</string>
<string name="shortcut_action_menu">Menu</string>
<string name="shortcut_action_ime">Mở trình chuyển đổi bàn phím</string>
<string name="shortcut_action_power_menu">Trình đơn nguồn</string>
<string name="shortcut_action_recent">Gần đây</string>
<string name="shortcut_action_power">Tắt màn hình</string>
<string name="shortcut_action_search">Tìm kiếm trong ứng dụng</string>
</resources>

152
res/values/dslv_arrays.xml Normal file
View File

@@ -0,0 +1,152 @@
<resources>
<!-- Icon type for DSLV. -->
<string-array name="icon_types">
<item>@string/shortcuts_icon_default</item>
<!--
<item>@string/shortcuts_icon_presets</item>
-->
<item>@string/shortcuts_icon_custom</item>
</string-array>
<string-array name="shortcut_icon_picker_labels">
<!--
<item>@string/shortcuts_icon_picker_alarm</item>
<item>@string/shortcuts_icon_picker_andy</item>
<item>@string/shortcuts_icon_picker_battery</item>
<item>@string/shortcuts_icon_picker_browser</item>
<item>@string/shortcuts_icon_picker_calendar</item>
<item>@string/shortcuts_icon_picker_camera</item>
<item>@string/shortcuts_icon_picker_cloud</item>
<item>@string/shortcuts_icon_picker_contact</item>
<item>@string/shortcuts_icon_picker_directdial</item>
<item>@string/shortcuts_icon_picker_directmessage</item>
<item>@string/shortcuts_icon_picker_drive</item>
<item>@string/shortcuts_icon_picker_dropbox</item>
<item>@string/shortcuts_icon_picker_email</item>
<item>@string/shortcuts_icon_picker_email2</item>
<item>@string/shortcuts_icon_picker_evernote</item>
<item>@string/shortcuts_icon_picker_facebook</item>
<item>@string/shortcuts_icon_picker_favorite</item>
<item>@string/shortcuts_icon_picker_file_browser</item>
<item>@string/shortcuts_icon_picker_file_browser2</item>
<item>@string/shortcuts_icon_picker_fitness</item>
<item>@string/shortcuts_icon_picker_gallery</item>
<item>@string/shortcuts_icon_picker_gears</item>
<item>@string/shortcuts_icon_picker_google_small</item>
<item>@string/shortcuts_icon_picker_gplus</item>
<item>@string/shortcuts_icon_picker_gtalk</item>
<item>@string/shortcuts_icon_picker_help</item>
<item>@string/shortcuts_icon_picker_joystick</item>
<item>@string/shortcuts_icon_picker_key</item>
<item>@string/shortcuts_icon_picker_laptop</item>
<item>@string/shortcuts_icon_picker_luggage</item>
<item>@string/shortcuts_icon_picker_maps</item>
<item>@string/shortcuts_icon_picker_market</item>
<item>@string/shortcuts_icon_picker_movie</item>
<item>@string/shortcuts_icon_picker_music</item>
<item>@string/shortcuts_icon_picker_nav</item>
<item>@string/shortcuts_icon_picker_notes</item>
<item>@string/shortcuts_icon_picker_package</item>
<item>@string/shortcuts_icon_picker_phone</item>
<item>@string/shortcuts_icon_picker_pinterest</item>
<item>@string/shortcuts_icon_picker_play</item>
<item>@string/shortcuts_icon_picker_pocket</item>
<item>@string/shortcuts_icon_picker_quicksettings</item>
<item>@string/shortcuts_icon_picker_rss</item>
<item>@string/shortcuts_icon_picker_sdcard</item>
<item>@string/shortcuts_icon_picker_search</item>
<item>@string/shortcuts_icon_picker_sms</item>
<item>@string/shortcuts_icon_picker_tasks</item>
<item>@string/shortcuts_icon_picker_terminal</item>
<item>@string/shortcuts_icon_picker_transit</item>
<item>@string/shortcuts_icon_picker_tv</item>
<item>@string/shortcuts_icon_picker_twitter</item>
<item>@string/shortcuts_icon_picker_unlock</item>
-->
</string-array>
<string-array name="shortcut_icon_picker_icons" translatable="false">
<!--
<item>@*android:drawable/ic_shortcut_alarm</item>
<item>@*android:drawable/ic_shortcut_andy</item>
<item>@*android:drawable/ic_shortcut_battery</item>
<item>@*android:drawable/ic_shortcut_browser</item>
<item>@*android:drawable/ic_shortcut_calendar</item>
<item>@*android:drawable/ic_shortcut_camera</item>
<item>@*android:drawable/ic_shortcut_cloud</item>
<item>@*android:drawable/ic_shortcut_contact</item>
<item>@*android:drawable/ic_shortcut_directdial</item>
<item>@*android:drawable/ic_shortcut_directmessage</item>
<item>@*android:drawable/ic_shortcut_drive</item>
<item>@*android:drawable/ic_shortcut_dropbox</item>
<item>@*android:drawable/ic_shortcut_email</item>
<item>@*android:drawable/ic_shortcut_email2</item>
<item>@*android:drawable/ic_shortcut_evernote</item>
<item>@*android:drawable/ic_shortcut_facebook</item>
<item>@*android:drawable/ic_shortcut_favorite</item>
<item>@*android:drawable/ic_shortcut_file_browser</item>
<item>@*android:drawable/ic_shortcut_file_browser2</item>
<item>@*android:drawable/ic_shortcut_fitness</item>
<item>@*android:drawable/ic_shortcut_gallery</item>
<item>@*android:drawable/ic_shortcut_gear</item>
<item>@*android:drawable/ic_shortcut_google_small</item>
<item>@*android:drawable/ic_shortcut_gplus</item>
<item>@*android:drawable/ic_shortcut_gtalk</item>
<item>@*android:drawable/ic_shortcut_help</item>
<item>@*android:drawable/ic_shortcut_joystick</item>
<item>@*android:drawable/ic_shortcut_key</item>
<item>@*android:drawable/ic_shortcut_laptop</item>
<item>@*android:drawable/ic_shortcut_luggage</item>
<item>@*android:drawable/ic_shortcut_maps</item>
<item>@*android:drawable/ic_shortcut_market</item>
<item>@*android:drawable/ic_shortcut_movie</item>
<item>@*android:drawable/ic_shortcut_music</item>
<item>@*android:drawable/ic_shortcut_nav</item>
<item>@*android:drawable/ic_shortcut_notes</item>
<item>@*android:drawable/ic_shortcut_package</item>
<item>@*android:drawable/ic_shortcut_phone</item>
<item>@*android:drawable/ic_shortcut_pinterest</item>
<item>@*android:drawable/ic_shortcut_play</item>
<item>@*android:drawable/ic_shortcut_pocket</item>
<item>@*android:drawable/ic_shortcut_quicksettings</item>
<item>@*android:drawable/ic_shortcut_rss</item>
<item>@*android:drawable/ic_shortcut_sdcard</item>
<item>@*android:drawable/ic_shortcut_search</item>
<item>@*android:drawable/ic_shortcut_sms</item>
<item>@*android:drawable/ic_shortcut_tasks</item>
<item>@*android:drawable/ic_shortcut_terminal</item>
<item>@*android:drawable/ic_shortcut_transit</item>
<item>@*android:drawable/ic_shortcut_tv</item>
<item>@*android:drawable/ic_shortcut_twitter</item>
<item>@*android:drawable/ic_shortcut_unlock</item>
-->
</string-array>
<string-array name="shortcut_action_entries">
<item>@string/shortcut_action_back</item>-
<item>@string/shortcut_action_app</item>-
<item>@string/shortcut_action_home</item>-
<item>@string/shortcut_action_menu</item>
<item>@string/shortcut_action_ime</item>
<item>@string/shortcut_action_power_menu</item>
<item>@string/shortcut_action_recent</item>
<item>@string/shortcut_action_power</item>
<item>@string/shortcut_action_search</item>
<item>@string/shortcut_action_none</item>
</string-array>
<string-array name="shortcut_action_values" translatable="false">
<item>**back**</item>
<item>**app**</item>
<item>**home**</item>
<item>**menu_big**</item>
<item>**ime**</item>
<item>**power_menu**</item>
<item>**recents**</item>
<item>**power**</item>
<item>**search**</item>
<item>**null**</item>
</string-array>
</resources>

32
res/values/dslv_attrs.xml Normal file
View File

@@ -0,0 +1,32 @@
<resources>
<!-- For DSLV -->
<declare-styleable name="DragSortListView">
<attr name="collapsedHeight" format="dimension" />
<attr name="dragScrollStart" format="float" />
<attr name="maxDragScrollSpeed" format="float" />
<attr name="floatBackgroundColor" format="color" />
<attr name="removeMode">
<enum name="clickRemove" value="0" />
<enum name="flingRemove" value="1" />
</attr>
<attr name="trackDragSort" format="boolean"/>
<attr name="floatAlpha" format="float"/>
<attr name="slideShuffleSpeed" format="float"/>
<attr name="removeAnimationDuration" format="integer"/>
<attr name="dropAnimationDuration" format="integer"/>
<attr name="dragEnabled" format="boolean" />
<attr name="sortEnabled" format="boolean" />
<attr name="removeEnabled" format="boolean" />
<attr name="dragStartMode">
<enum name="onDown" value="0" />
<enum name="onMove" value="1" />
<enum name="onLongPress" value="2"/>
</attr>
<attr name="dragHandleId" format="integer" />
<attr name="flingHandleId" format="integer" />
<attr name="clickRemoveId" format="integer" />
<attr name="useDefaultController" format="boolean" />
</declare-styleable>
</resources>

21
res/values/dslv_ids.xml Normal file
View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2014, 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.
*/
-->
<resources>
<item type="id" name="drag_handle" />
</resources>

View File

@@ -0,0 +1,42 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<!-- Slim lockscreen shortcuts -->
<string name="shortcut_action_none">None</string>
<string name="shortcut_action_longpress">Longpress:</string>
<string name="shortcut_action_select_action_longpress">Choose longpress action:</string>
<string name="shortcut_action_select_action">Choose action:</string>
<string name="shortcut_action_select_action_newaction">Choose new action:</string>
<string name="shortcut_action_reset">Reset</string>
<string name="shortcut_action_add">Add</string>
<string name="shortcut_action_max">Maximum entries size has been reached</string>
<string name="shortcut_action_warning">Warning</string>
<string name="shortcut_action_warning_message">It is not possible to delete last entry</string>
<string name="shortcut_action_disable_message">Disabled\nAdd an entry to enable this feature</string>
<string name="shortcut_image_not_valid">The chosen app did not return a valid icon or does not support image cropping. Use another app.</string>
<string name="shortcut_duplicate_entry">The chosen action cannot be added twice</string>
<string name="shortcut_action_help_shortcut">shortcut</string>
<string name="shortcut_action_help_button">button</string>
<string name="shortcut_action_help_app">app</string>
<string name="shortcut_action_help_icon">, while selecting the icon will bring up customization options</string>
<string name="shortcut_action_help_main">To add a %1$s, select the Add icon. Once a %1$s is added, selecting the row will change the target%2$s\n\nTo remove a %1$s, swipe the row horizontally left or right. Re-order a %1$s in the list by vertically dragging the anchor on the left.\n\nTo clear or reset to defaults, select the Reset icon.</string>
<string name="shortcut_action_help_delete_last_entry">Removing every %1$s in the list will disable the feature entirely.</string>
<string name="shortcut_action_help_pie_second_layer_delete_last_entry">Removing every %1$s in the list will disable the second pie layer entirely.</string>
<string name="shortcuts_applications">Applications</string>
<string name="shortcuts_select_custom_app_title">Select custom application</string>
<string name="shortcuts_icon_picker_type">Select icon type:</string>
<string name="shortcuts_icon_default">Default</string>
<string name="shortcuts_icon_custom">Gallery</string>
<string name="reset_message">Reset all entries to default?</string>
<string name="help">Help</string>
<string name="shortcut_action_app">Custom app</string>
<string name="shortcut_action_home">Home</string>
<string name="shortcut_action_back">Back</string>
<string name="shortcut_action_menu">Menu</string>
<string name="shortcut_action_ime">Open IME Switcher</string>
<string name="shortcut_action_power_menu">Power menu</string>
<string name="shortcut_action_recent">Recents</string>
<string name="shortcut_action_power">Screen Off</string>
<string name="shortcut_action_search">Search in app</string>
</resources>

View File

@@ -0,0 +1,177 @@
/*
* Copyright (C) 2014 SlimRoms 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.cherish.settings.preferences;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.content.Intent.ShortcutIconResource;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import com.android.settings.R;
import com.android.internal.util.slim.AppHelper;
import java.util.ArrayList;
public class SlimShortcutPickerHelper {
public static final int REQUEST_PICK_SHORTCUT = 100;
public static final int REQUEST_PICK_APPLICATION = 101;
public static final int REQUEST_CREATE_SHORTCUT = 102;
private Activity mParent;
private OnPickListener mListener;
private PackageManager mPackageManager;
private int lastFragmentId;
public interface OnPickListener {
void shortcutPicked(String uri, String friendlyName, Bitmap bmp, boolean isApplication);
}
public SlimShortcutPickerHelper(Activity parent, OnPickListener listener) {
mParent = parent;
mPackageManager = mParent.getPackageManager();
mListener = listener;
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
switch (requestCode) {
case REQUEST_PICK_APPLICATION:
completeSetCustomApp(data);
break;
case REQUEST_CREATE_SHORTCUT:
completeSetCustomShortcut(data);
break;
case REQUEST_PICK_SHORTCUT:
processShortcut(data, REQUEST_PICK_APPLICATION, REQUEST_CREATE_SHORTCUT);
break;
}
}
}
public void pickShortcut(int fragmentId) {
pickShortcut(fragmentId, false);
}
public void pickShortcut(int fragmentId, boolean fullAppsOnly) {
lastFragmentId = fragmentId;
if (fullAppsOnly) {
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);
startFragmentOrActivity(pickIntent, REQUEST_PICK_APPLICATION);
} else {
Bundle bundle = new Bundle();
ArrayList<String> shortcutNames = new ArrayList<String>();
shortcutNames.add(mParent.getString(R.string.shortcuts_applications));
bundle.putStringArrayList(Intent.EXTRA_SHORTCUT_NAME, shortcutNames);
ArrayList<ShortcutIconResource> shortcutIcons = new ArrayList<ShortcutIconResource>();
shortcutIcons.add(ShortcutIconResource.fromContext(mParent,
android.R.drawable.sym_def_app_icon));
bundle.putParcelableArrayList(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcons);
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
pickIntent.putExtra(Intent.EXTRA_INTENT, new Intent(Intent.ACTION_CREATE_SHORTCUT));
pickIntent.putExtra(Intent.EXTRA_TITLE, mParent.getText(
R.string.shortcuts_select_custom_app_title));
pickIntent.putExtras(bundle);
startFragmentOrActivity(pickIntent, REQUEST_PICK_SHORTCUT);
}
}
private void startFragmentOrActivity(Intent pickIntent, int requestCode) {
if (lastFragmentId == 0) {
mParent.startActivityForResult(pickIntent, requestCode);
} else {
Fragment cFrag = mParent.getFragmentManager().findFragmentById(lastFragmentId);
if (cFrag != null) {
mParent.startActivityFromFragment(cFrag, pickIntent, requestCode);
}
}
}
private void processShortcut(Intent intent,
int requestCodeApplication, int requestCodeShortcut) {
// Handle case where user selected "Applications"
String applicationName = mParent.getResources().getString(R.string.shortcuts_applications);
String shortcutName = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
if (applicationName != null && applicationName.equals(shortcutName)) {
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);
startFragmentOrActivity(pickIntent, requestCodeApplication);
} else {
startFragmentOrActivity(intent, requestCodeShortcut);
}
}
private void completeSetCustomApp(Intent data) {
mListener.shortcutPicked(data.toUri(0),
AppHelper.getFriendlyActivityName(mParent, mPackageManager, data, false), null, true);
}
private void completeSetCustomShortcut(Intent data) {
Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
/* preserve shortcut name, we want to restore it later */
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, data.getStringExtra(
Intent.EXTRA_SHORTCUT_NAME));
String appUri = intent.toUri(0);
appUri = appUri.replaceAll("com.android.contacts.action.QUICK_CONTACT",
"android.intent.action.VIEW");
// Check if icon is present
Bitmap bmp = null;
Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
if (extra != null && extra instanceof Bitmap) {
bmp = (Bitmap) extra;
}
// No icon till now check if icon resource is present
if (bmp == null) {
extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
if (extra != null && extra instanceof Intent.ShortcutIconResource) {
try {
Intent.ShortcutIconResource iconResource = (ShortcutIconResource) extra;
Resources resources =
mPackageManager.getResourcesForApplication(iconResource.packageName);
final int id = resources.getIdentifier(iconResource.resourceName, null, null);
bmp = BitmapFactory.decodeResource(resources, id);
} catch (Exception e) {
e.printStackTrace();
}
}
}
mListener.shortcutPicked(appUri,
AppHelper.getFriendlyShortcutName(mParent, mPackageManager, intent), bmp, false);
}
}

View File

@@ -0,0 +1,983 @@
/*
* Copyright (C) 2014 Slimroms
* Copyright (C) 2015-2017 Android Ice Cold 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.cherish.settings.preferences.dslv;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.ListFragment;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ListView;
import android.widget.Toast;
import com.android.internal.util.slim.ActionConfig;
import com.android.internal.util.slim.ActionConstants;
import com.android.internal.util.slim.ActionHelper;
import com.android.internal.util.slim.ImageHelper;
import com.android.internal.util.slim.DeviceUtils;
import com.android.internal.util.slim.DeviceUtils.FilteredDeviceFeaturesArray;
import com.android.settings.R;
import com.cherish.settings.preferences.SlimShortcutPickerHelper;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
public class ActionListViewSettings extends ListFragment implements
SlimShortcutPickerHelper.OnPickListener {
private static final int DLG_SHOW_ACTION_DIALOG = 0;
private static final int DLG_SHOW_ICON_PICKER = 1;
private static final int DLG_DELETION_NOT_ALLOWED = 2;
private static final int DLG_SHOW_HELP_SCREEN = 3;
private static final int DLG_RESET_TO_DEFAULT = 4;
private static final int MENU_HELP = Menu.FIRST;
private static final int MENU_ADD = MENU_HELP + 1;
private static final int MENU_RESET = MENU_ADD + 1;
private static final int NAV_BAR = 0;
private static final int PIE = 1;
private static final int PIE_SECOND = 2;
private static final int NAV_RING = 3;
private static final int LOCKSCREEN_SHORTCUT = 4;
private static final int POWER_MENU_SHORTCUT = 5;
private static final int SHAKE_EVENTS_DISABLED = 6;
private static final int RECENT_APP_SIDEBAR = 7;
private static final int DEFAULT_MAX_ACTION_NUMBER = 5;
public static final int REQUEST_PICK_CUSTOM_ICON = 1000;
private int mActionMode;
private int mMaxAllowedActions;
private boolean mUseAppPickerOnly;
private boolean mUseFullAppsOnly;
private boolean mDisableLongpress;
private boolean mDisableIconPicker;
private boolean mDisableDeleteLastEntry;
private TextView mDisableMessage;
private ActionConfigsAdapter mActionConfigsAdapter;
private ArrayList<ActionConfig> mActionConfigs;
private ActionConfig mActionConfig;
private boolean mAdditionalFragmentAttached;
private String mAdditionalFragment;
private View mDivider;
private int mPendingIndex = -1;
private boolean mPendingLongpress;
private boolean mPendingNewAction;
private String[] mActionDialogValues;
private String[] mActionDialogEntries;
private String mActionValuesKey;
private String mActionEntriesKey;
private Activity mActivity;
private SlimShortcutPickerHelper mPicker;
private File mImageTmp;
private DragSortListView.DropListener onDrop =
new DragSortListView.DropListener() {
@Override
public void drop(int from, int to) {
ActionConfig item = mActionConfigsAdapter.getItem(from);
mActionConfigsAdapter.remove(item);
mActionConfigsAdapter.insert(item, to);
setConfig(mActionConfigs, false);
}
};
private DragSortListView.RemoveListener onRemove =
new DragSortListView.RemoveListener() {
@Override
public void remove(int which) {
ActionConfig item = mActionConfigsAdapter.getItem(which);
mActionConfigsAdapter.remove(item);
if (mDisableDeleteLastEntry && mActionConfigs.size() == 0) {
mActionConfigsAdapter.add(item);
showDialogInner(DLG_DELETION_NOT_ALLOWED, 0, false, false);
} else {
deleteIconFileIfPresent(item, true);
setConfig(mActionConfigs, false);
if (mActionConfigs.size() == 0) {
showDisableMessage(true);
}
}
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.dslv_action_list_view_main, container, false);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Resources res = getResources();
if (false) {
// Tell Lint these arrays are used
int unused = R.array.shortcut_action_values;
unused = R.array.shortcut_action_entries;
}
mActionMode = getArguments().getInt("actionMode", NAV_BAR);
mMaxAllowedActions = getArguments().getInt("maxAllowedActions", DEFAULT_MAX_ACTION_NUMBER);
mAdditionalFragment = getArguments().getString("fragment", null);
mActionValuesKey = getArguments().getString("actionValues", "shortcut_action_values");
mActionEntriesKey = getArguments().getString("actionEntries", "shortcut_action_entries");
mDisableLongpress = getArguments().getBoolean("disableLongpress", false);
mUseAppPickerOnly = getArguments().getBoolean("useAppPickerOnly", false);
mUseFullAppsOnly = getArguments().getBoolean("useOnlyFullAppPicker", false);
mDisableIconPicker = getArguments().getBoolean("disableIconPicker", false);
mDisableDeleteLastEntry = getArguments().getBoolean("disableDeleteLastEntry", false);
mDisableMessage = (TextView) view.findViewById(R.id.disable_message);
FilteredDeviceFeaturesArray finalActionDialogArray = new FilteredDeviceFeaturesArray();
finalActionDialogArray = DeviceUtils.filterUnsupportedDeviceFeatures(mActivity,
res.getStringArray(res.getIdentifier(
mActionValuesKey, "array", "com.android.settings")),
res.getStringArray(res.getIdentifier(
mActionEntriesKey, "array", "com.android.settings")));
mActionDialogValues = finalActionDialogArray.values;
mActionDialogEntries = finalActionDialogArray.entries;
mPicker = new SlimShortcutPickerHelper(mActivity, this);
mImageTmp = new File(mActivity.getCacheDir()
+ File.separator + "shortcut.tmp");
DragSortListView listView = (DragSortListView) getListView();
listView.setDropListener(onDrop);
listView.setRemoveListener(onRemove);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
if (mUseFullAppsOnly) {
if (mPicker != null) {
mPendingIndex = arg2;
mPendingLongpress = false;
mPendingNewAction = false;
mPicker.pickShortcut(getId(), true);
}
} else if (!mUseAppPickerOnly) {
showDialogInner(DLG_SHOW_ACTION_DIALOG, arg2, false, false);
} else {
if (mPicker != null) {
mPendingIndex = arg2;
mPendingLongpress = false;
mPendingNewAction = false;
mPicker.pickShortcut(getId());
}
}
}
});
if (!mDisableLongpress) {
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
if (mUseFullAppsOnly) {
if (mPicker != null) {
mPendingIndex = arg2;
mPendingLongpress = true;
mPendingNewAction = false;
mPicker.pickShortcut(getId(), true);
}
} else if (!mUseAppPickerOnly) {
showDialogInner(DLG_SHOW_ACTION_DIALOG, arg2, true, false);
} else {
if (mPicker != null) {
mPendingIndex = arg2;
mPendingLongpress = true;
mPendingNewAction = false;
mPicker.pickShortcut(getId());
}
}
return true;
}
});
}
mActionConfigs = getConfig();
if (mActionConfigs != null) {
mActionConfigsAdapter = new ActionConfigsAdapter(mActivity, mActionConfigs);
setListAdapter(mActionConfigsAdapter);
showDisableMessage(mActionConfigs.size() == 0);
}
mDivider = (View) view.findViewById(R.id.divider);
loadAdditionalFragment();
// get shared preference
SharedPreferences preferences =
mActivity.getSharedPreferences("dslv_settings", Activity.MODE_PRIVATE);
if (!preferences.getBoolean("first_help_shown_mode_" + mActionMode, false)) {
preferences.edit()
.putBoolean("first_help_shown_mode_" + mActionMode, true).commit();
showDialogInner(DLG_SHOW_HELP_SCREEN, 0, false, false);
}
setHasOptionsMenu(true);
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (mAdditionalFragmentAttached) {
FragmentManager fragmentManager = getFragmentManager();
Fragment fragment = fragmentManager.findFragmentById(R.id.fragment_container);
if (fragment != null && !fragmentManager.isDestroyed()) {
fragmentManager.beginTransaction().remove(fragment).commit();
}
}
}
private void loadAdditionalFragment() {
if (mAdditionalFragment != null && !mAdditionalFragment.isEmpty()) {
try {
Class<?> classAdditionalFragment = Class.forName(mAdditionalFragment);
Fragment fragment = (Fragment) classAdditionalFragment.newInstance();
getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, fragment).commit();
if (mDivider != null) {
mDivider.setVisibility(View.VISIBLE);
}
mAdditionalFragmentAttached = true;
} catch (Exception e) {
mAdditionalFragmentAttached = false;
e.printStackTrace();
}
}
}
@Override
public void shortcutPicked(String action,
String description, Bitmap bmp, boolean isApplication) {
if (mPendingIndex == -1) {
return;
}
if (bmp != null && !mPendingLongpress) {
// Icon is present, save it for future use and add the file path to the action.
String fileName = mActivity.getFilesDir()
+ File.separator + "shortcut_" + System.currentTimeMillis() + ".png";
try {
FileOutputStream out = new FileOutputStream(fileName);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
action = action + "?hasExtraIcon=" + fileName;
File image = new File(fileName);
image.setReadable(true, false);
}
}
if (mPendingNewAction) {
addNewAction(action, description);
} else {
updateAction(action, description, null, mPendingIndex, mPendingLongpress);
}
mPendingLongpress = false;
mPendingNewAction = false;
mPendingIndex = -1;
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SlimShortcutPickerHelper.REQUEST_PICK_SHORTCUT
|| requestCode == SlimShortcutPickerHelper.REQUEST_PICK_APPLICATION
|| requestCode == SlimShortcutPickerHelper.REQUEST_CREATE_SHORTCUT) {
mPicker.onActivityResult(requestCode, resultCode, data);
} else if (requestCode == REQUEST_PICK_CUSTOM_ICON && mPendingIndex != -1) {
if (mImageTmp.length() == 0 || !mImageTmp.exists()) {
mPendingIndex = -1;
Toast.makeText(mActivity,
getResources().getString(R.string.shortcut_image_not_valid),
Toast.LENGTH_LONG).show();
return;
}
File image = new File(mActivity.getFilesDir() + File.separator
+ "shortcut_" + System.currentTimeMillis() + ".png");
String path = image.getAbsolutePath();
mImageTmp.renameTo(image);
image.setReadable(true, false);
updateAction(null, null, path, mPendingIndex, false);
mPendingIndex = -1;
}
} else {
if (mImageTmp.exists()) {
mImageTmp.delete();
}
mPendingLongpress = false;
mPendingNewAction = false;
mPendingIndex = -1;
}
super.onActivityResult(requestCode, resultCode, data);
}
private void updateAction(String action, String description, String icon,
int which, boolean longpress) {
if (!longpress && checkForDuplicateMainNavActions(action)) {
return;
}
ActionConfig actionConfig = mActionConfigsAdapter.getItem(which);
mActionConfigsAdapter.remove(actionConfig);
if (!longpress) {
deleteIconFileIfPresent(actionConfig, false);
}
if (icon != null) {
actionConfig.setIcon(icon);
} else {
if (longpress) {
actionConfig.setLongpressAction(action);
actionConfig.setLongpressActionDescription(description);
} else {
deleteIconFileIfPresent(actionConfig, true);
actionConfig.setClickAction(action);
actionConfig.setClickActionDescription(description);
actionConfig.setIcon(ActionConstants.ICON_EMPTY);
}
}
mActionConfigsAdapter.insert(actionConfig, which);
showDisableMessage(false);
setConfig(mActionConfigs, false);
}
private boolean checkForDuplicateMainNavActions(String action) {
ActionConfig actionConfig;
for (int i = 0; i < mActionConfigs.size(); i++) {
actionConfig = mActionConfigsAdapter.getItem(i);
if (actionConfig.getClickAction().equals(action)) {
Toast.makeText(mActivity,
getResources().getString(R.string.shortcut_duplicate_entry),
Toast.LENGTH_LONG).show();
return true;
}
}
return false;
}
private void deleteIconFileIfPresent(ActionConfig action, boolean deleteShortCutIcon) {
File oldImage = new File(action.getIcon());
if (oldImage.exists()) {
oldImage.delete();
}
oldImage = new File(action.getClickAction().replaceAll(".*?hasExtraIcon=", ""));
if (oldImage.exists() && deleteShortCutIcon) {
oldImage.delete();
}
}
private void showDisableMessage(boolean show) {
if (mDisableMessage == null || mDisableDeleteLastEntry) {
return;
}
if (show) {
mDisableMessage.setVisibility(View.VISIBLE);
} else {
mDisableMessage.setVisibility(View.GONE);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_ADD:
if (mActionConfigs.size() == mMaxAllowedActions) {
Toast.makeText(mActivity,
getResources().getString(R.string.shortcut_action_max),
Toast.LENGTH_LONG).show();
break;
}
if (mUseFullAppsOnly) {
if (mPicker != null) {
mPendingIndex = 0;
mPendingLongpress = false;
mPendingNewAction = true;
mPicker.pickShortcut(getId(), true);
}
} else if (!mUseAppPickerOnly) {
showDialogInner(DLG_SHOW_ACTION_DIALOG, 0, false, true);
} else {
if (mPicker != null) {
mPendingIndex = 0;
mPendingLongpress = false;
mPendingNewAction = true;
mPicker.pickShortcut(getId());
}
}
break;
case MENU_RESET:
showDialogInner(DLG_RESET_TO_DEFAULT, 0, false, true);
break;
case MENU_HELP:
showDialogInner(DLG_SHOW_HELP_SCREEN, 0, false, true);
break;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.add(0, MENU_HELP, 0, R.string.help)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
menu.add(0, MENU_RESET, 0, R.string.shortcut_action_reset)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
menu.add(0, MENU_ADD, 0, R.string.shortcut_action_add)
.setIcon(R.drawable.ic_menu_add)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
private void addNewAction(String action, String description) {
if (checkForDuplicateMainNavActions(action)) {
return;
}
ActionConfig actionConfig = new ActionConfig(
action, description,
ActionConstants.ACTION_NULL, getResources().getString(R.string.shortcut_action_none),
ActionConstants.ICON_EMPTY);
mActionConfigsAdapter.add(actionConfig);
showDisableMessage(false);
setConfig(mActionConfigs, false);
}
private ArrayList<ActionConfig> getConfig() {
switch (mActionMode) {
/* Disabled for now till all features are back. Enable it step per step!!!!!!
case LOCKSCREEN_SHORTCUT:
return ActionHelper.getLockscreenShortcutConfig(mActivity);
case NAV_BAR:
return ActionHelper.getNavBarConfigWithDescription(
mActivity, mActionValuesKey, mActionEntriesKey);
case NAV_RING:
return ActionHelper.getNavRingConfigWithDescription(
mActivity, mActionValuesKey, mActionEntriesKey);
case PIE:
return ActionHelper.getPieConfigWithDescription(
mActivity, mActionValuesKey, mActionEntriesKey);
case PIE_SECOND:
return ActionHelper.getPieSecondLayerConfigWithDescription(
mActivity, mActionValuesKey, mActionEntriesKey);
case POWER_MENU_SHORTCUT:
return PolicyHelper.getPowerMenuConfigWithDescription(
mActivity, mActionValuesKey, mActionEntriesKey);
case SHAKE_EVENTS_DISABLED:
return ActionHelper.getDisabledShakeApps(mActivity);
*/
case RECENT_APP_SIDEBAR:
return ActionHelper.getRecentAppSidebarConfigWithDescription(
mActivity, mActionValuesKey, mActionEntriesKey);
}
return null;
}
private void setConfig(ArrayList<ActionConfig> actionConfigs, boolean reset) {
switch (mActionMode) {
/* Disabled for now till all features are back. Enable it step per step!!!!!!
case LOCKSCREEN_SHORTCUT:
ActionHelper.setLockscreenShortcutConfig(mActivity, actionConfigs, reset);
break;
case NAV_BAR:
ActionHelper.setNavBarConfig(mActivity, actionConfigs, reset);
break;
case NAV_RING:
ActionHelper.setNavRingConfig(mActivity, actionConfigs, reset);
break;
case PIE:
ActionHelper.setPieConfig(mActivity, actionConfigs, reset);
break;
case PIE_SECOND:
ActionHelper.setPieSecondLayerConfig(mActivity, actionConfigs, reset);
break;
case POWER_MENU_SHORTCUT:
PolicyHelper.setPowerMenuConfig(mActivity, actionConfigs, reset);
break;
case SHAKE_EVENTS_DISABLED:
ActionHelper.setDisabledShakeApps(mActivity, actionConfigs, reset);
break;
*/
case RECENT_APP_SIDEBAR:
ActionHelper.setRecentAppSidebarConfig(mActivity, actionConfigs, reset);
break;
}
}
private class ViewHolder {
public TextView longpressActionDescriptionView;
public ImageView iconView;
}
private class ActionConfigsAdapter extends ArrayAdapter<ActionConfig> {
private int mIconColor;
public ActionConfigsAdapter(Context context, List<ActionConfig> clickActionDescriptions) {
super(context, R.layout.dslv_action_list_view_item,
R.id.click_action_description, clickActionDescriptions);
// Themed resources
int[] attrs = new int[] {
android.R.attr.textColorPrimary,
};
TypedArray ta = context.getTheme().obtainStyledAttributes(attrs);
mIconColor = ta.getColor(0, 0xff808080);
ta.recycle();
}
public View getView(final int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
if (v != convertView && v != null) {
ViewHolder holder = new ViewHolder();
TextView longpressActionDecription =
(TextView) v.findViewById(R.id.longpress_action_description);
ImageView icon = (ImageView) v.findViewById(R.id.icon);
if (mDisableLongpress) {
longpressActionDecription.setVisibility(View.GONE);
} else {
holder.longpressActionDescriptionView = longpressActionDecription;
}
holder.iconView = icon;
v.setTag(holder);
}
ViewHolder holder = (ViewHolder) v.getTag();
if (!mDisableLongpress) {
holder.longpressActionDescriptionView.setText(
getResources().getString(R.string.shortcut_action_longpress)
+ " " + getItem(position).getLongpressActionDescription());
}
Drawable d = null;
String iconUri = getItem(position).getIcon();
if (mActionMode == POWER_MENU_SHORTCUT) {
/* Disabled for now till slims power menu is back!!!!!!!!!!!!!!
d = ImageHelper.resize(
mActivity, PolicyHelper.getPowerMenuIconImage(mActivity,
getItem(position).getClickAction(),
iconUri, false), 36); */
} else {
d = ImageHelper.resize(
mActivity, ActionHelper.getActionIconImage(mActivity,
getItem(position).getClickAction(),
iconUri), 36);
}
if (iconUri != null && iconUri.startsWith(ActionConstants.SYSTEM_ICON_IDENTIFIER)) {
d.setTint(mIconColor);
}
holder.iconView.setImageDrawable(d);
if (!mDisableIconPicker && holder.iconView.getDrawable() != null) {
holder.iconView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mPendingIndex = position;
showDialogInner(DLG_SHOW_ICON_PICKER, 0, false, false);
}
});
}
return v;
}
}
private void showDialogInner(int id, int which, boolean longpress, boolean newAction) {
DialogFragment newFragment =
MyAlertDialogFragment.newInstance(id, which, longpress, newAction);
newFragment.setTargetFragment(this, 0);
newFragment.show(getFragmentManager(), "dialog " + id);
}
public static class MyAlertDialogFragment extends DialogFragment {
private int mIconColor;
public static MyAlertDialogFragment newInstance(int id,
int which, boolean longpress, boolean newAction) {
MyAlertDialogFragment frag = new MyAlertDialogFragment();
Bundle args = new Bundle();
args.putInt("id", id);
args.putInt("which", which);
args.putBoolean("longpress", longpress);
args.putBoolean("newAction", newAction);
frag.setArguments(args);
return frag;
}
ActionListViewSettings getOwner() {
return (ActionListViewSettings) getTargetFragment();
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int id = getArguments().getInt("id");
final int which = getArguments().getInt("which");
final boolean longpress = getArguments().getBoolean("longpress");
final boolean newAction = getArguments().getBoolean("newAction");
switch (id) {
case DLG_RESET_TO_DEFAULT:
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.shortcut_action_reset)
.setMessage(R.string.reset_message)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// first delete custom icons in case they exist
ArrayList<ActionConfig> actionConfigs = getOwner().getConfig();
for (int i = 0; i < actionConfigs.size(); i++) {
getOwner().deleteIconFileIfPresent(actionConfigs.get(i), true);
}
// reset provider values and action adapter to default
getOwner().setConfig(null, true);
getOwner().mActionConfigsAdapter.clear();
// Add the new default objects fetched from @getConfig()
actionConfigs = getOwner().getConfig();
final int newConfigsSize = actionConfigs.size();
for (int i = 0; i < newConfigsSize; i++) {
getOwner().mActionConfigsAdapter.add(actionConfigs.get(i));
}
// dirty helper if actionConfigs list has no entries
// to proper update the content. .notifyDatSetChanged()
// does not work in this case.
if (newConfigsSize == 0) {
ActionConfig emptyAction =
new ActionConfig(null, null, null, null, null);
getOwner().mActionConfigsAdapter.add(emptyAction);
getOwner().mActionConfigsAdapter.remove(emptyAction);
}
getOwner().showDisableMessage(newConfigsSize == 0);
}
})
.create();
case DLG_SHOW_HELP_SCREEN:
Resources res = getResources();
String finalHelpMessage;
String actionMode;
String icon = "";
switch (getOwner().mActionMode) {
case LOCKSCREEN_SHORTCUT:
case POWER_MENU_SHORTCUT:
actionMode = res.getString(R.string.shortcut_action_help_shortcut);
break;
case SHAKE_EVENTS_DISABLED:
actionMode = res.getString(R.string.shortcut_action_help_app);
break;
case NAV_BAR:
case NAV_RING:
case PIE:
case PIE_SECOND:
case RECENT_APP_SIDEBAR:
default:
actionMode = res.getString(R.string.shortcut_action_help_button);
break;
}
if (!getOwner().mDisableIconPicker) {
icon = res.getString(R.string.shortcut_action_help_icon);
}
finalHelpMessage = res.getString(
R.string.shortcut_action_help_main, actionMode, icon);
if (!getOwner().mDisableDeleteLastEntry) {
finalHelpMessage += " " + res.getString(
getOwner().mActionMode == PIE_SECOND
? R.string.shortcut_action_help_pie_second_layer_delete_last_entry
: R.string.shortcut_action_help_delete_last_entry, actionMode);
}
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.help)
.setMessage(finalHelpMessage)
.setNegativeButton(R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
})
.create();
case DLG_DELETION_NOT_ALLOWED:
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.shortcut_action_warning)
.setMessage(R.string.shortcut_action_warning_message)
.setNegativeButton(R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
})
.create();
case DLG_SHOW_ACTION_DIALOG:
int title;
if (longpress) {
title = R.string.shortcut_action_select_action_longpress;
} else if (newAction) {
title = R.string.shortcut_action_select_action_newaction;
} else {
title = R.string.shortcut_action_select_action;
}
// for normal press action we filter out null value
// due it does not make sense to set a null action
// on normal press action
String[] values = null;
String[] entries = null;
if (!longpress) {
List<String> finalEntriesList = new ArrayList<String>();
List<String> finalValuesList = new ArrayList<String>();
for (int i = 0; i < getOwner().mActionDialogValues.length; i++) {
if (!getOwner().mActionDialogValues[i]
.equals(ActionConstants.ACTION_NULL)) {
finalEntriesList.add(getOwner().mActionDialogEntries[i]);
finalValuesList.add(getOwner().mActionDialogValues[i]);
}
}
entries = finalEntriesList.toArray(new String[finalEntriesList.size()]);
values = finalValuesList.toArray(new String[finalValuesList.size()]);
}
final String[] finalDialogValues =
longpress ? getOwner().mActionDialogValues : values;
final String[] finalDialogEntries =
longpress ? getOwner().mActionDialogEntries : entries;
return new AlertDialog.Builder(getActivity())
.setTitle(title)
.setNegativeButton(R.string.cancel, null)
.setItems(finalDialogEntries,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (finalDialogValues[item].equals(ActionConstants.ACTION_APP)) {
if (getOwner().mPicker != null) {
getOwner().mPendingIndex = which;
getOwner().mPendingLongpress = longpress;
getOwner().mPendingNewAction = newAction;
getOwner().mPicker.pickShortcut(getOwner().getId());
}
} else {
if (newAction) {
getOwner().addNewAction(finalDialogValues[item],
finalDialogEntries[item]);
} else {
getOwner().updateAction(finalDialogValues[item],
finalDialogEntries[item],
null, which, longpress);
}
}
}
})
.create();
case DLG_SHOW_ICON_PICKER:
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.shortcuts_icon_picker_type)
.setNegativeButton(R.string.cancel, null)
.setItems(R.array.icon_types,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
switch(which) {
case 0: // Default
getOwner().updateAction(null, null,
ActionConstants.ICON_EMPTY,
getOwner().mPendingIndex, false);
getOwner().mPendingIndex = -1;
break;
case 1: // System defaults
/*
ListView list = new ListView(getActivity());
list.setAdapter(new IconAdapter(mIconColor));
final Dialog holoDialog = new Dialog(getActivity());
holoDialog.setTitle(
R.string.shortcuts_icon_picker_choose_icon_title);
holoDialog.setContentView(list);
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
IconAdapter adapter = (IconAdapter) parent.getAdapter();
getOwner().updateAction(null, null,
adapter.getItemReference(position),
getOwner().mPendingIndex, false);
getOwner().mPendingIndex = -1;
holoDialog.cancel();
}
});
holoDialog.show();
break;
case 2: // Custom user icon
*/
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("scale", true);
intent.putExtra("outputFormat",
Bitmap.CompressFormat.PNG.toString());
intent.putExtra("aspectX", 100);
intent.putExtra("aspectY", 100);
intent.putExtra("outputX", 100);
intent.putExtra("outputY", 100);
try {
getOwner().mImageTmp.createNewFile();
getOwner().mImageTmp.setWritable(true, false);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(getOwner().mImageTmp));
intent.putExtra("return-data", false);
getOwner().startActivityForResult(
intent, REQUEST_PICK_CUSTOM_ICON);
} catch (IOException e) {
e.printStackTrace();
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
break;
}
}
})
.create();
}
throw new IllegalArgumentException("unknown id " + id);
}
@Override
public void onCancel(DialogInterface dialog) {
}
public class IconAdapter extends BaseAdapter {
TypedArray icons;
String[] labels;
int color;
public IconAdapter(int iconColor) {
labels = getResources().getStringArray(R.array.shortcut_icon_picker_labels);
icons = getResources().obtainTypedArray(R.array.shortcut_icon_picker_icons);
color = iconColor;
}
@Override
public Object getItem(int position) {
return icons.getDrawable(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public int getCount() {
return labels.length;
}
public String getItemReference(int position) {
String name = icons.getString(position);
int separatorIndex = name.lastIndexOf(File.separator);
int periodIndex = name.lastIndexOf('.');
return ActionConstants.SYSTEM_ICON_IDENTIFIER
+ name.substring(separatorIndex + 1, periodIndex);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View iView = convertView;
if (convertView == null) {
iView = View.inflate(getActivity(), android.R.layout.simple_list_item_1, null);
}
TextView tt = (TextView) iView.findViewById(android.R.id.text1);
tt.setText(labels[position]);
Drawable ic = ((Drawable) getItem(position)).mutate();
ic.setTint(color);
tt.setCompoundDrawablePadding(15);
tt.setCompoundDrawablesWithIntrinsicBounds(ic, null, null, null);
return iView;
}
}
}
}

View File

@@ -0,0 +1,488 @@
/*
* Copyright 2012 Carl Bauer
* Copyright (C) 2014 SlimRoms 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.cherish.settings.preferences.dslv;
import android.graphics.Point;
import android.view.GestureDetector;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.AdapterView;
/**
* Class that starts and stops item drags on a {@link DragSortListView}
* based on touch gestures. This class also inherits from
* {@link SimpleFloatViewManager}, which provides basic float View
* creation.
*
* An instance of this class is meant to be passed to the methods
* {@link DragSortListView#setTouchListener()} and
* {@link DragSortListView#setFloatViewManager()} of your
* {@link DragSortListView} instance.
*/
public class DragSortController extends SimpleFloatViewManager
implements View.OnTouchListener, GestureDetector.OnGestureListener {
/**
* Drag init mode enum.
*/
public static final int ON_DOWN = 0;
public static final int ON_DRAG = 1;
public static final int ON_LONG_PRESS = 2;
private int mDragInitMode = ON_DOWN;
private boolean mSortEnabled = true;
/**
* Remove mode enum.
*/
public static final int CLICK_REMOVE = 0;
public static final int FLING_REMOVE = 1;
/**
* The current remove mode.
*/
private int mRemoveMode;
private boolean mRemoveEnabled = false;
private boolean mIsRemoving = false;
private GestureDetector mDetector;
private GestureDetector mFlingRemoveDetector;
private int mTouchSlop;
public static final int MISS = -1;
private int mHitPos = MISS;
private int mFlingHitPos = MISS;
private int mClickRemoveHitPos = MISS;
private int[] mTempLoc = new int[2];
private int mItemX;
private int mItemY;
private int mCurrX;
private int mCurrY;
private boolean mDragging = false;
private float mFlingSpeed = 500f;
private int mDragHandleId;
private int mClickRemoveId;
private int mFlingHandleId;
private boolean mCanDrag;
private DragSortListView mDslv;
private int mPositionX;
/**
* Calls {@link #DragSortController(DragSortListView, int)} with a
* 0 drag handle id, FLING_RIGHT_REMOVE remove mode,
* and ON_DOWN drag init. By default, sorting is enabled, and
* removal is disabled.
*
* @param dslv The DSLV instance
*/
public DragSortController(DragSortListView dslv) {
this(dslv, 0, ON_DOWN, FLING_REMOVE);
}
public DragSortController(DragSortListView dslv,
int dragHandleId, int dragInitMode, int removeMode) {
this(dslv, dragHandleId, dragInitMode, removeMode, 0);
}
public DragSortController(DragSortListView dslv, int dragHandleId,
int dragInitMode, int removeMode, int clickRemoveId) {
this(dslv, dragHandleId, dragInitMode, removeMode, clickRemoveId, 0);
}
/**
* By default, sorting is enabled, and removal is disabled.
*
* @param dslv The DSLV instance
* @param dragHandleId The resource id of the View that represents
* the drag handle in a list item.
*/
public DragSortController(DragSortListView dslv, int dragHandleId, int dragInitMode,
int removeMode, int clickRemoveId, int flingHandleId) {
super(dslv);
mDslv = dslv;
mDetector = new GestureDetector(dslv.getContext(), this);
mFlingRemoveDetector = new GestureDetector(dslv.getContext(), mFlingRemoveListener);
mFlingRemoveDetector.setIsLongpressEnabled(false);
mTouchSlop = ViewConfiguration.get(dslv.getContext()).getScaledTouchSlop();
mDragHandleId = dragHandleId;
mClickRemoveId = clickRemoveId;
mFlingHandleId = flingHandleId;
setRemoveMode(removeMode);
setDragInitMode(dragInitMode);
}
public int getDragInitMode() {
return mDragInitMode;
}
/**
* Set how a drag is initiated. Needs to be one of
* {@link ON_DOWN}, {@link ON_DRAG}, or {@link ON_LONG_PRESS}.
*
* @param mode The drag init mode.
*/
public void setDragInitMode(int mode) {
mDragInitMode = mode;
}
/**
* Enable/Disable list item sorting. Disabling is useful if only item
* removal is desired. Prevents drags in the vertical direction.
*
* @param enabled Set <code>true</code> to enable list
* item sorting.
*/
public void setSortEnabled(boolean enabled) {
mSortEnabled = enabled;
}
public boolean isSortEnabled() {
return mSortEnabled;
}
/**
* One of {@link CLICK_REMOVE}, {@link FLING_RIGHT_REMOVE},
* {@link FLING_LEFT_REMOVE},
* {@link SLIDE_RIGHT_REMOVE}, or {@link SLIDE_LEFT_REMOVE}.
*/
public void setRemoveMode(int mode) {
mRemoveMode = mode;
}
public int getRemoveMode() {
return mRemoveMode;
}
/**
* Enable/Disable item removal without affecting remove mode.
*/
public void setRemoveEnabled(boolean enabled) {
mRemoveEnabled = enabled;
}
public boolean isRemoveEnabled() {
return mRemoveEnabled;
}
/**
* Set the resource id for the View that represents the drag
* handle in a list item.
*
* @param id An android resource id.
*/
public void setDragHandleId(int id) {
mDragHandleId = id;
}
/**
* Set the resource id for the View that represents the fling
* handle in a list item.
*
* @param id An android resource id.
*/
public void setFlingHandleId(int id) {
mFlingHandleId = id;
}
/**
* Set the resource id for the View that represents click
* removal button.
*
* @param id An android resource id.
*/
public void setClickRemoveId(int id) {
mClickRemoveId = id;
}
/**
* Sets flags to restrict certain motions of the floating View
* based on DragSortController settings (such as remove mode).
* Starts the drag on the DragSortListView.
*
* @param position The list item position (includes headers).
* @param deltaX Touch x-coord minus left edge of floating View.
* @param deltaY Touch y-coord minus top edge of floating View.
*
* @return True if drag started, false otherwise.
*/
public boolean startDrag(int position, int deltaX, int deltaY) {
int dragFlags = 0;
if (mSortEnabled && !mIsRemoving) {
dragFlags |= DragSortListView.DRAG_POS_Y | DragSortListView.DRAG_NEG_Y;
}
if (mRemoveEnabled && mIsRemoving) {
dragFlags |= DragSortListView.DRAG_POS_X;
dragFlags |= DragSortListView.DRAG_NEG_X;
}
mDragging = mDslv.startDrag(position - mDslv.getHeaderViewsCount(), dragFlags, deltaX,
deltaY);
return mDragging;
}
@Override
public boolean onTouch(View v, MotionEvent ev) {
if (!mDslv.isDragEnabled() || mDslv.listViewIntercepted()) {
return false;
}
mDetector.onTouchEvent(ev);
if (mRemoveEnabled && mDragging && mRemoveMode == FLING_REMOVE) {
mFlingRemoveDetector.onTouchEvent(ev);
}
int action = ev.getAction() & MotionEvent.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mCurrX = (int) ev.getX();
mCurrY = (int) ev.getY();
break;
case MotionEvent.ACTION_UP:
if (mRemoveEnabled && mIsRemoving) {
int x = mPositionX >= 0 ? mPositionX : -mPositionX;
int removePoint = mDslv.getWidth() / 2;
if (x > removePoint) {
mDslv.stopDragWithVelocity(true, 0);
}
}
case MotionEvent.ACTION_CANCEL:
mIsRemoving = false;
mDragging = false;
break;
}
return false;
}
/**
* Overrides to provide fading when slide removal is enabled.
*/
@Override
public void onDragFloatView(View floatView, Point position, Point touch) {
if (mRemoveEnabled && mIsRemoving) {
mPositionX = position.x;
}
}
/**
* Get the position to start dragging based on the ACTION_DOWN
* MotionEvent. This function simply calls
* {@link #dragHandleHitPosition(MotionEvent)}. Override
* to change drag handle behavior;
* this function is called internally when an ACTION_DOWN
* event is detected.
*
* @param ev The ACTION_DOWN MotionEvent.
*
* @return The list position to drag if a drag-init gesture is
* detected; MISS if unsuccessful.
*/
public int startDragPosition(MotionEvent ev) {
return dragHandleHitPosition(ev);
}
public int startFlingPosition(MotionEvent ev) {
return mRemoveMode == FLING_REMOVE ? flingHandleHitPosition(ev) : MISS;
}
/**
* Checks for the touch of an item's drag handle (specified by
* {@link #setDragHandleId(int)}), and returns that item's position
* if a drag handle touch was detected.
*
* @param ev The ACTION_DOWN MotionEvent.
* @return The list position of the item whose drag handle was
* touched; MISS if unsuccessful.
*/
public int dragHandleHitPosition(MotionEvent ev) {
return viewIdHitPosition(ev, mDragHandleId);
}
public int flingHandleHitPosition(MotionEvent ev) {
return viewIdHitPosition(ev, mFlingHandleId);
}
public int viewIdHitPosition(MotionEvent ev, int id) {
final int x = (int) ev.getX();
final int y = (int) ev.getY();
int touchPos = mDslv.pointToPosition(x, y); // includes headers/footers
final int numHeaders = mDslv.getHeaderViewsCount();
final int numFooters = mDslv.getFooterViewsCount();
final int count = mDslv.getCount();
// Log.d("mobeta", "touch down on position " + itemnum);
// We're only interested if the touch was on an
// item that's not a header or footer.
if (touchPos != AdapterView.INVALID_POSITION && touchPos >= numHeaders
&& touchPos < (count - numFooters)) {
final View item = mDslv.getChildAt(touchPos - mDslv.getFirstVisiblePosition());
final int rawX = (int) ev.getRawX();
final int rawY = (int) ev.getRawY();
View dragBox = id == 0 ? item : (View) item.findViewById(id);
if (dragBox != null) {
dragBox.getLocationOnScreen(mTempLoc);
if (rawX > mTempLoc[0] && rawY > mTempLoc[1] &&
rawX < mTempLoc[0] + dragBox.getWidth() &&
rawY < mTempLoc[1] + dragBox.getHeight()) {
mItemX = item.getLeft();
mItemY = item.getTop();
return touchPos;
}
}
}
return MISS;
}
@Override
public boolean onDown(MotionEvent ev) {
if (mRemoveEnabled && mRemoveMode == CLICK_REMOVE) {
mClickRemoveHitPos = viewIdHitPosition(ev, mClickRemoveId);
}
mHitPos = startDragPosition(ev);
if (mHitPos != MISS && mDragInitMode == ON_DOWN) {
startDrag(mHitPos, (int) ev.getX() - mItemX, (int) ev.getY() - mItemY);
}
mIsRemoving = false;
mCanDrag = true;
mPositionX = 0;
mFlingHitPos = startFlingPosition(ev);
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
final int x1 = (int) e1.getX();
final int y1 = (int) e1.getY();
final int x2 = (int) e2.getX();
final int y2 = (int) e2.getY();
final int deltaX = x2 - mItemX;
final int deltaY = y2 - mItemY;
if (mCanDrag && !mDragging && (mHitPos != MISS || mFlingHitPos != MISS)) {
if (mHitPos != MISS) {
if (mDragInitMode == ON_DRAG && Math.abs(y2 - y1) > mTouchSlop && mSortEnabled) {
startDrag(mHitPos, deltaX, deltaY);
} else if (mDragInitMode != ON_DOWN
&& Math.abs(x2 - x1) > mTouchSlop && mRemoveEnabled) {
mIsRemoving = true;
startDrag(mFlingHitPos, deltaX, deltaY);
}
} else if (mFlingHitPos != MISS) {
if (Math.abs(x2 - x1) > mTouchSlop && mRemoveEnabled) {
mIsRemoving = true;
startDrag(mFlingHitPos, deltaX, deltaY);
} else if (Math.abs(y2 - y1) > mTouchSlop) {
mCanDrag = false; // if started to scroll the list then
// don't allow sorting nor fling-removing
}
}
}
// return whatever
return false;
}
@Override
public void onLongPress(MotionEvent e) {
// Log.d("mobeta", "lift listener long pressed");
if (mHitPos != MISS && mDragInitMode == ON_LONG_PRESS) {
mDslv.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
startDrag(mHitPos, mCurrX - mItemX, mCurrY - mItemY);
}
}
// complete the OnGestureListener interface
@Override
public final boolean onFling(MotionEvent e1,
MotionEvent e2, float velocityX, float velocityY) {
return false;
}
// complete the OnGestureListener interface
@Override
public boolean onSingleTapUp(MotionEvent ev) {
if (mRemoveEnabled && mRemoveMode == CLICK_REMOVE) {
if (mClickRemoveHitPos != MISS) {
mDslv.removeItem(mClickRemoveHitPos - mDslv.getHeaderViewsCount());
}
}
return true;
}
// complete the OnGestureListener interface
@Override
public void onShowPress(MotionEvent ev) {
// do nothing
}
private GestureDetector.OnGestureListener mFlingRemoveListener =
new GestureDetector.SimpleOnGestureListener() {
@Override
public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// Log.d("mobeta", "on fling remove called");
if (mRemoveEnabled && mIsRemoving) {
int w = mDslv.getWidth();
int minPos = w / 5;
if (velocityX > mFlingSpeed) {
if (mPositionX > -minPos) {
mDslv.stopDragWithVelocity(true, velocityX);
}
} else if (velocityX < -mFlingSpeed) {
if (mPositionX < minPos) {
mDslv.stopDragWithVelocity(true, velocityX);
}
}
mIsRemoving = false;
}
return false;
}
};
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright 2012 Carl Bauer
* Copyright (C) 2014 SlimRoms 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.cherish.settings.preferences.dslv;
import android.content.Context;
import android.view.Gravity;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.util.Log;
/**
* Lightweight ViewGroup that wraps list items obtained from user's
* ListAdapter. ItemView expects a single child that has a definite
* height (i.e. the child's layout height is not MATCH_PARENT).
* The width of
* ItemView will always match the width of its child (that is,
* the width MeasureSpec given to ItemView is passed directly
* to the child, and the ItemView measured width is set to the
* child's measured width). The height of ItemView can be anything;
* the
*
*
* The purpose of this class is to optimize slide
* shuffle animations.
*/
public class DragSortItemView extends ViewGroup {
private int mGravity = Gravity.TOP;
public DragSortItemView(Context context) {
super(context);
// always init with standard ListView layout params
setLayoutParams(new AbsListView.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
//setClipChildren(true);
}
public void setGravity(int gravity) {
mGravity = gravity;
}
public int getGravity() {
return mGravity;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
final View child = getChildAt(0);
if (child == null) {
return;
}
if (mGravity == Gravity.TOP) {
child.layout(0, 0, getMeasuredWidth(), child.getMeasuredHeight());
} else {
child.layout(0, getMeasuredHeight() - child.getMeasuredHeight(),
getMeasuredWidth(), getMeasuredHeight());
}
}
/**
*
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = MeasureSpec.getSize(heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
final View child = getChildAt(0);
if (child == null) {
setMeasuredDimension(0, width);
return;
}
if (child.isLayoutRequested()) {
// Always let child be as tall as it wants.
measureChild(child, widthMeasureSpec,
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
}
if (heightMode == MeasureSpec.UNSPECIFIED) {
ViewGroup.LayoutParams lp = getLayoutParams();
if (lp.height > 0) {
height = lp.height;
} else {
height = child.getMeasuredHeight();
}
}
setMeasuredDimension(width, height);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,106 @@
/*
* Copyright 2012 Carl Bauer
* Copyright (C) 2014 SlimRoms 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.cherish.settings.preferences.dslv;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Color;
import android.widget.ListView;
import android.widget.ImageView;
import android.view.View;
import android.view.ViewGroup;
import android.util.Log;
/**
* Simple implementation of the FloatViewManager class. Uses list
* items as they appear in the ListView to create the floating View.
*/
public class SimpleFloatViewManager implements DragSortListView.FloatViewManager {
private Bitmap mFloatBitmap;
private ImageView mImageView;
private int mFloatBGColor = Color.BLACK;
private ListView mListView;
public SimpleFloatViewManager(ListView lv) {
mListView = lv;
}
public void setBackgroundColor(int color) {
mFloatBGColor = color;
}
/**
* This simple implementation creates a Bitmap copy of the
* list item currently shown at ListView <code>position</code>.
*/
@Override
public View onCreateFloatView(int position) {
// Guaranteed that this will not be null? I think so. Nope, got
// a NullPointerException once...
View v = mListView.getChildAt(
position + mListView.getHeaderViewsCount() - mListView.getFirstVisiblePosition());
if (v == null) {
return null;
}
v.setPressed(false);
// Create a copy of the drawing cache so that it does not get
// recycled by the framework when the list tries to clean up memory
//v.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
v.setDrawingCacheEnabled(true);
mFloatBitmap = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false);
if (mImageView == null) {
mImageView = new ImageView(mListView.getContext());
}
mImageView.setBackgroundColor(mFloatBGColor);
mImageView.setPadding(0, 0, 0, 0);
mImageView.setImageBitmap(mFloatBitmap);
mImageView.setLayoutParams(new ViewGroup.LayoutParams(v.getWidth(), v.getHeight()));
return mImageView;
}
/**
* This does nothing
*/
@Override
public void onDragFloatView(View floatView, Point position, Point touch) {
// do nothing
}
/**
* Removes the Bitmap from the ImageView created in
* onCreateFloatView() and tells the system to recycle it.
*/
@Override
public void onDestroyFloatView(View floatView) {
((ImageView) floatView).setImageDrawable(null);
mFloatBitmap.recycle();
mFloatBitmap = null;
}
}