blob: 1aa42f4381ee8f6cea88f7daf29e2782d2c72a88 [file] [log] [blame]
/*
* Copyright (C) 2013 Fairphone 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.fairphone.fplauncher3.edgeswipe.editor;
import java.util.ArrayList;
import android.app.Activity;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.DragEvent;
import android.view.HapticFeedbackConstants;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.fairphone.fplauncher3.AppInfo;
import com.fairphone.fplauncher3.R;
import com.fairphone.fplauncher3.edgeswipe.editor.ui.DropDragEventListener;
import com.fairphone.fplauncher3.edgeswipe.editor.ui.EditFavoritesGridView;
import com.fairphone.fplauncher3.edgeswipe.editor.ui.EditFavoritesGridView.OnEditFavouritesIconDraggedListener;
import com.fairphone.fplauncher3.edgeswipe.editor.ui.FavoriteItemView;
import com.fairphone.fplauncher3.edgeswipe.editor.ui.FavoriteItemView.OnFavouriteItemDraggedListener;
import com.fairphone.fplauncher3.edgeswipe.editor.ui.IconDragShadowBuilder;
/**
* Edit favorites activity implements functionality to edit your favorite apps
* that will appear with the edge swipe.
*/
public class EditFavoritesActivity extends Activity implements View.OnDragListener, DragDropItemLayoutListener
{
public static final String PREFS_EDGE_SWIPE_MENU = "com.fairphone.fplauncher.PREFS_EDGE_SWIPE_MENU";
public static final String EDGE_SWIPE_THEME = "com.fairphone.fplauncher.EDGE_SWIPE_THEME";
private static final String TAG = EditFavoritesActivity.class.getSimpleName();
// This is used to differentiate a drag from the all apps to favorites
// from a drag between two favorites to perform a swap
public static final int SELECTED_APPS_DRAG = 0;
public static final int ALL_APPS_DRAG = 1;
public enum Themes
{
LIGHT, DARK
}
private AllAppsListAdapter mAllAppsListAdapter;
private ArrayList<AppInfo> mAllApps;
private ArrayList<FrameLayout> mFavIcons;
private AppInfo[] mSelectedApps;
private EditFavoritesGridView mAllAppsGridView;
private int mDragOrigin;
private View mRemoveFavouriteOverlay;
private TextView mRemoveFavouriteText;
private ImageView mAllAppsImageView;
private RadioGroup mThemeRadioGroup;
private RadioButton mThemeRadioButtonLight;
private RadioButton mThemeRadioButtonDark;
private View mFavouritesGroup;
private SharedPreferences mSharedPrefs;
private Themes mCurrentTheme;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.fp_edit_favorites);
mAllApps = AppDiscoverer.getInstance().getPackages();
mSelectedApps = FavoritesStorageHelper.loadSelectedApps(this, 4);
mFavIcons = new ArrayList<>();
mFavIcons.add((FrameLayout) findViewById(R.id.favourite_group_1));
mFavIcons.add((FrameLayout) findViewById(R.id.favourite_group_2));
mFavIcons.add((FrameLayout) findViewById(R.id.favourite_group_3));
mFavIcons.add((FrameLayout) findViewById(R.id.favourite_group_4));
mAllAppsImageView = (ImageView) findViewById(R.id.all_apps_image_view);
mRemoveFavouriteOverlay = findViewById(R.id.remove_favourite_overlay);
mRemoveFavouriteText = (TextView) findViewById(R.id.remove_favourite_text);
mThemeRadioGroup = (RadioGroup) findViewById(R.id.theme_radio_group);
mThemeRadioButtonLight = (RadioButton) findViewById(R.id.theme_radio_button_light);
mThemeRadioButtonDark = (RadioButton) findViewById(R.id.theme_radio_button_dark);
mFavouritesGroup = findViewById(R.id.favourites_group);
mSharedPrefs = getSharedPreferences(PREFS_EDGE_SWIPE_MENU, Context.MODE_PRIVATE);
mCurrentTheme = getCurrentTheme(this);
changeTheme(mCurrentTheme);
mThemeRadioGroup.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (v.getAlpha() == 0f){
v.setAlpha(1f);
Toast.makeText(getApplicationContext(), R.string.easter_egg_toast_theme, Toast.LENGTH_SHORT).show();
mThemeRadioButtonDark.setVisibility(View.VISIBLE);
mThemeRadioButtonLight.setVisibility(View.VISIBLE);
mThemeRadioButtonDark.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mCurrentTheme == Themes.DARK) {
changeTheme(Themes.LIGHT);
} else {
changeTheme(Themes.DARK);
}
}
});
mThemeRadioButtonLight.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mCurrentTheme == Themes.LIGHT) {
changeTheme(Themes.DARK);
} else {
changeTheme(Themes.LIGHT);
}
}
});
}
}
});
setupAllAppsList();
setupSelectedAppsList();
}
public static Themes getCurrentTheme(Context context)
{
Themes currentTheme;
SharedPreferences sharedPrefs = context.getSharedPreferences(PREFS_EDGE_SWIPE_MENU, Context.MODE_PRIVATE);
String currentThemePref = sharedPrefs.getString(EDGE_SWIPE_THEME, Themes.DARK.name());
try
{
currentTheme = Themes.valueOf(currentThemePref);
} catch (Exception e)
{
currentTheme = Themes.DARK;
}
return currentTheme;
}
private void saveTheme(Themes theme)
{
mCurrentTheme = theme;
SharedPreferences.Editor editor = mSharedPrefs.edit();
editor.putString(EDGE_SWIPE_THEME, theme.name());
editor.commit();
}
@Override
public void onPause()
{
super.onPause();
}
private void changeTheme(Themes theme)
{
switch (theme)
{
case DARK:
mThemeRadioGroup.setBackgroundResource(R.drawable.stripe_dark_up_tile);
mFavouritesGroup.setBackgroundResource(R.color.background_blue_dark);
mAllAppsImageView.setImageResource(R.drawable.icon_allapps_blue_light_transparent);
mThemeRadioButtonDark.setChecked(true);
break;
case LIGHT:
mThemeRadioGroup.setBackgroundResource(R.drawable.stripe_light_up_tile);
mFavouritesGroup.setBackgroundResource(R.color.edit_favourites_background_white);
mAllAppsImageView.setImageResource(R.drawable.icon_allapps_grey);
mThemeRadioButtonLight.setChecked(true);
break;
default:
Log.w(TAG, "Unknown theme: " + theme);
theme = Themes.DARK;
break;
}
saveTheme(theme);
setupSelectedAppsList();
}
/**
* Setup the list with all the apps installed on the device.
*/
private void setupAllAppsList()
{
mAllAppsGridView = (EditFavoritesGridView) findViewById(R.id.all_apps_gridview);
View header = View.inflate( this, R.layout.fp_edit_favorites_list_header, null);
mAllAppsGridView.addHeaderView(header);
mAllAppsListAdapter = new AllAppsListAdapter(this);
mAllAppsListAdapter.setAllApps(mAllApps);
mAllAppsGridView.setLongClickable(true);
mAllAppsGridView.setOnEditFavouritesIconDraggedListener(new OnEditFavouritesIconDraggedListener()
{
@Override
public void OnEditFavouritesIconDragged(AdapterView<?> parent, View view, int position, long id)
{
startDraggingIcon(view, position);
}
@Override
public void OnEditFavouritesIconDragEnded()
{
hideAllAppsRemoveZone();
}
});
mAllAppsGridView.setAdapter(mAllAppsListAdapter);
// set the drag listener to enable favorite icon removal
mRemoveFavouriteOverlay.setOnDragListener(new DropDragEventListener(this, mFavIcons, mSelectedApps, mAllApps, true));
}
private void startDraggingIcon(View view, int position)
{
// display a circle around the possible destinations
toggleFavoriteBackground(-1, true);
View mainView = this.getWindow().getDecorView();
AppInfo applicationInfo = mAllApps.get(position);
// set the item with the origin of the drag and the index of the dragged
// view
mDragOrigin = EditFavoritesActivity.ALL_APPS_DRAG;
String selectedItem = serializeItem(mDragOrigin, position);
ClipData.Item item = new ClipData.Item(selectedItem);
ClipData dragData = ClipData.newPlainText(applicationInfo.getApplicationTitle(), applicationInfo.getApplicationTitle());
dragData.addItem(item);
mainView.startDrag(dragData,
new IconDragShadowBuilder(EditFavoritesActivity.this, view, new BitmapDrawable(getResources(), applicationInfo.getIconBitmap()), mDragOrigin),
view, 0);
mainView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
}
/**
* Setup the list with the selected app list, which is the holder of the
* apps that has been selected to become the favorite apps.
*/
private void setupSelectedAppsList()
{
for (int i = 0; i < 4; i++)
{
setupFavoriteIcon(mFavIcons.get(i), mSelectedApps[i], i, false);
// set the listeners
// The last argument is set to false since this hasn't the ability
// to remove icons, it only switches them
mFavIcons.get(i).setOnDragListener(new DropDragEventListener(this, mFavIcons, mSelectedApps, mAllApps, false));
}
}
@Override
public void setupFavoriteIcon(FrameLayout rla, AppInfo applicationInfo, final int idx, boolean performAnimation)
{
if (applicationInfo == null)
{
final View dragPlaceholderView = rla.getChildAt(0);
final FavoriteItemView iconView = (FavoriteItemView) rla.getChildAt(1);
if (performAnimation)
{
startViewFadeOutFadeInAnimation(dragPlaceholderView, iconView, null);
}
else
{
dragPlaceholderView.setVisibility(View.VISIBLE);
iconView.setVisibility(View.INVISIBLE);
}
iconView.setOnFavouriteItemDraggedListener(null);
mSelectedApps[idx] = null;
applyFavoriteUpState(rla);
}
else
{
final View dragPlaceholderView = rla.getChildAt(0);
final FavoriteItemView iconView = (FavoriteItemView) rla.getChildAt(1);
// Log.d(TAG, "Adding app : " +
// applicationInfo.getApplicationTitle());
if (mSelectedApps[idx] == null)
{
updateFavoriteIcon(applicationInfo, iconView);
if (performAnimation)
{
startViewFadeOutFadeInAnimation(iconView, dragPlaceholderView, null);
}
else
{
dragPlaceholderView.setVisibility(View.INVISIBLE);
iconView.setVisibility(View.VISIBLE);
}
}
else
{
if (performAnimation)
{
startViewFadeOutFadeInAnimation(null, iconView, applicationInfo);
}
else
{
updateFavoriteIcon(applicationInfo, iconView);
dragPlaceholderView.setVisibility(View.INVISIBLE);
iconView.setVisibility(View.VISIBLE);
}
}
mSelectedApps[idx] = applicationInfo;
// Set the listener
// pass the main view and the instance setup the drag and visibility
// of some views
final View mainView = this.getWindow().getDecorView();
iconView.setOnFavouriteItemDraggedListener(new OnFavouriteItemDraggedListener()
{
@Override
public void OnFavouriteItemDragged(View view)
{
startFavoriteDrag(view, idx, mainView, EditFavoritesActivity.this);
}
@Override
public void OnFavouriteItemDragEnded()
{
hideAllAppsRemoveZone();
}
});
}
FavoritesStorageHelper.storeSelectedApps(this, mSelectedApps);
}
/**
* Update the icon and label of a favorite
*
* @param applicationInfo
* App information that contains the icon and label
* @param icon
* the icon to update
*/
private void updateFavoriteIcon(AppInfo applicationInfo, final TextView icon)
{
Drawable drawable = new BitmapDrawable(getResources(), applicationInfo.getIconBitmap());
Resources r = getResources();
float px = r.getDimension(R.dimen.edit_favorites_icon_size);
drawable.setBounds(0, 0, Math.round(px), Math.round(px));
icon.setCompoundDrawables(null, drawable, null, null);
}
/**
* Performs the animation when replacing one favorite
*
* @param viewToFadeIn
* view that will appear. When null it means that we are swapping
* two favorites
* @param viewToFadeOut
* view that will disappear.
* @param applicationInfo
* app info that is used to swap two favorites
*/
private void startViewFadeOutFadeInAnimation(final View viewToFadeIn, final View viewToFadeOut, final AppInfo applicationInfo)
{
Animation fadeOutAnimation = AnimationUtils.loadAnimation(this, R.anim.fade_out_fast);
fadeOutAnimation.setAnimationListener(new AnimationListener()
{
@Override
public void onAnimationStart(Animation animation)
{
}
@Override
public void onAnimationRepeat(Animation animation)
{
}
@Override
public void onAnimationEnd(Animation animation)
{
viewToFadeOut.setVisibility(View.INVISIBLE);
if (applicationInfo == null && viewToFadeIn != null)
{
if (viewToFadeIn.getVisibility() != View.VISIBLE)
{
viewToFadeIn.setVisibility(View.VISIBLE);
Animation fadeInAnimation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fade_in_fast);
viewToFadeIn.startAnimation(fadeInAnimation);
}
}
else if (applicationInfo != null)
{
// get the new icon
updateFavoriteIcon(applicationInfo, (TextView) viewToFadeOut);
viewToFadeOut.setVisibility(View.VISIBLE);
Animation fadeInAnimation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fade_in_fast);
viewToFadeOut.startAnimation(fadeInAnimation);
}
}
});
if (viewToFadeOut.getVisibility() == View.VISIBLE)
{
viewToFadeOut.startAnimation(fadeOutAnimation);
}
}
/**
* Capture the back button press, to make sure we save the selected apps
* before exiting.
*/
@Override
public void onBackPressed()
{
FavoritesStorageHelper.storeSelectedApps(this, mSelectedApps);
Intent intent = getIntent();
setResult(RESULT_OK, intent);
finish();
}
/**
* Serializes the item id and origin that is being dragged.
*
* @param appOrigin
* the origin: can be SELECT_APPS_DRAG or ALL_APPS_DRAG
* @param appIndex
* the item index
* @return the serialized item info
*/
public static String serializeItem(int appOrigin, int appIndex)
{
String selectedItem = appOrigin + ";" + appIndex;
return selectedItem;
}
/**
* Deserializes the item id and origin that is being dragged.
*
* @param toDeserialize
* string to deserialize
* @return an array containing {appOrign, appIndex}
*/
public static String[] deserializeItem(String toDeserialize)
{
String[] selectedItem = toDeserialize.split(";");
return selectedItem;
}
private void startFavoriteDrag(View v, int id, View mainView, DragDropItemLayoutListener listener)
{
// Show the zone where favorites can be removed
listener.showAllAppsRemoveZone();
// display a circle around the possible destinations
toggleFavoriteBackground(-1, true);
// set the drag info
AppInfo applicationInfo = mSelectedApps[id];
// set the item with the origin of the drag and the index of the
// dragged view
mDragOrigin = EditFavoritesActivity.SELECTED_APPS_DRAG;
String selectedItem = serializeItem(mDragOrigin, id);
ClipData.Item item = new ClipData.Item(selectedItem);
ClipData dragData = ClipData.newPlainText(applicationInfo.getApplicationTitle(), applicationInfo.getApplicationTitle());
dragData.addItem(item);
mainView.startDrag(dragData,
new IconDragShadowBuilder(EditFavoritesActivity.this, v, new BitmapDrawable(getResources(), applicationInfo.getIconBitmap()), mDragOrigin), v,
0);
mainView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
}
@Override
public boolean onDrag(View v, DragEvent event)
{
return false;
}
@Override
public void hideAllAppsRemoveZone()
{
hideAllAppsRemoveZoneRedGlow();
mRemoveFavouriteOverlay.setVisibility(View.GONE);
mRemoveFavouriteText.setVisibility(View.GONE);
// hide the circle around the possible destinations
toggleFavoriteBackground(-1, false);
}
@Override
public void showAllAppsRemoveZone()
{
mRemoveFavouriteOverlay.setVisibility(View.VISIBLE);
mRemoveFavouriteText.setVisibility(View.VISIBLE);
}
@Override
public void showAllAppsRemoveZoneRedGlow()
{
Resources resources = getResources();
mRemoveFavouriteOverlay.setBackgroundResource(R.drawable.stripe_red_up_tile);
mRemoveFavouriteText.setTextColor(resources.getColor(R.color.edit_favourites_text_white));
}
@Override
public void hideAllAppsRemoveZoneRedGlow()
{
Resources resources = getResources();
mRemoveFavouriteOverlay.setBackgroundResource(R.drawable.stripe_grey_up_tile);
mRemoveFavouriteText.setTextColor(resources.getColor(R.color.edit_favourites_text_white));
}
@Override
public void toggleAllAppRemoveZoneRedGlow(float pointerX, float pointerY)
{
// the red glow only makes sense when removing favorites
if (mDragOrigin == SELECTED_APPS_DRAG)
{
if (isInRemoveZone(pointerX, pointerY))
{
showAllAppsRemoveZoneRedGlow();
}
else
{
hideAllAppsRemoveZoneRedGlow();
}
}
}
private boolean isInRemoveZone(float pointerX, float pointerY)
{
boolean validX;
boolean validY;
View allAppsGroupView = findViewById(R.id.remove_favourite_overlay);
validX = pointerX <= (allAppsGroupView.getX() + allAppsGroupView.getWidth());
validY = pointerY >= allAppsGroupView.getY();
return validX && validY;
}
/**
* Displays a background on the favorite possible positions when configuring
* it
*
* @param selectedFavorite
* the favorite position where the background will not be shown.
* -1 means that all backgrounds will be shown.
* @param showBackground
* true: displays the background; false: removes the background
*/
private void toggleFavoriteBackground(int selectedFavorite, boolean showBackground)
{
for (int i = 0; i < mFavIcons.size(); i++)
{
if (i != selectedFavorite && showBackground)
{
switch (mCurrentTheme)
{
case LIGHT:
mFavIcons.get(i).setBackgroundResource(R.drawable.stripe_light_up_tile);
break;
case DARK:
default:
mFavIcons.get(i).setBackgroundResource(R.drawable.stripe_dark_up_tile);
break;
}
}
else
{
mFavIcons.get(i).setBackground(null);
}
}
}
@Override
public void applyFavoritePressState(FrameLayout view)
{
switch (mCurrentTheme)
{
case LIGHT:
applyFavouriteState(view, R.drawable.stripe_light_press_tile, R.color.edit_favourites_text_blue_light);
break;
case DARK:
default:
applyFavouriteState(view, R.drawable.stripe_dark_press_tile, R.color.white);
break;
}
}
@Override
public void applyFavoriteUpState(FrameLayout view)
{
switch (mCurrentTheme)
{
case LIGHT:
applyFavouriteState(view, R.drawable.stripe_light_up_tile, R.color.edit_favourites_text_grey_dark);
break;
case DARK:
default:
applyFavouriteState(view, R.drawable.stripe_dark_up_tile, R.color.blue);
break;
}
}
private void applyFavouriteState(FrameLayout view, int backgroundResourceId, int textColorResourceId)
{
if (view != null)
{
TextView emptyFavorites = (TextView) view.getChildAt(0);
view.setBackgroundResource(backgroundResourceId);
if (emptyFavorites != null)
{
int color = getResources().getColor(textColorResourceId);
emptyFavorites.setBackgroundResource(backgroundResourceId);
emptyFavorites.setTextColor(color);
}
}
}
}