diff options
-rw-r--r-- | res/drawable-hdpi/quick_theme_fab.png | bin | 5088 -> 0 bytes | |||
-rw-r--r-- | res/drawable-mdpi/quick_theme_fab.png | bin | 3194 -> 0 bytes | |||
-rw-r--r-- | res/drawable-xhdpi/quick_theme_fab.png | bin | 7197 -> 0 bytes | |||
-rw-r--r-- | res/drawable-xxhdpi/quick_theme_fab.png | bin | 11880 -> 0 bytes | |||
-rw-r--r-- | res/drawable/quick_theme_fab.xml | 35 | ||||
-rw-r--r-- | res/layout/per_app_fab_floating_window_icon.xml | 9 | ||||
-rw-r--r-- | res/values/colors.xml | 12 | ||||
-rw-r--r-- | src/com/cyngn/theme/perapptheming/PerAppThemingWindow.java | 147 |
8 files changed, 116 insertions, 87 deletions
diff --git a/res/drawable-hdpi/quick_theme_fab.png b/res/drawable-hdpi/quick_theme_fab.png Binary files differdeleted file mode 100644 index 011b4c5..0000000 --- a/res/drawable-hdpi/quick_theme_fab.png +++ /dev/null diff --git a/res/drawable-mdpi/quick_theme_fab.png b/res/drawable-mdpi/quick_theme_fab.png Binary files differdeleted file mode 100644 index b8844bb..0000000 --- a/res/drawable-mdpi/quick_theme_fab.png +++ /dev/null diff --git a/res/drawable-xhdpi/quick_theme_fab.png b/res/drawable-xhdpi/quick_theme_fab.png Binary files differdeleted file mode 100644 index 53c762e..0000000 --- a/res/drawable-xhdpi/quick_theme_fab.png +++ /dev/null diff --git a/res/drawable-xxhdpi/quick_theme_fab.png b/res/drawable-xxhdpi/quick_theme_fab.png Binary files differdeleted file mode 100644 index 504528d..0000000 --- a/res/drawable-xxhdpi/quick_theme_fab.png +++ /dev/null diff --git a/res/drawable/quick_theme_fab.xml b/res/drawable/quick_theme_fab.xml new file mode 100644 index 0000000..762e014 --- /dev/null +++ b/res/drawable/quick_theme_fab.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (c) 2015 Cyanogen, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="222dp" + android:height="222dp" + android:viewportWidth="222" + android:viewportHeight="222"> + + <group> + <path + android:fillColor="@color/per_app_theme_fab_bg_color" + android:pathData="M111.5,6.5c58,0,105,47,105,105s-47,105-105,105s-105-47-105-105S53.5,6.5,111.5,6.5z" /> + <path + android:fillColor="@color/per_app_theme_fab_icon_color" + android:pathData="M111.5,134.5h-47c0,0,0-1.4,0-11s6.3-14,12-14s4,0,12,0s11-4.9,11-11c0-6.1-3-28.2-3-37s3.7-17,15-17 +s15,8.2,15,17s-3,30.9-3,37c0,6.1,3,11,11,11s6.3,0,12,0c5.7,0,12,4.4,12,14s0,11,0,11H111.5z +M111.5,54.5c-3.3,0-6,2.7-6,6 +c0,3.3,2.7,6,6,6c3.3,0,6-2.7,6-6C117.5,57.2,114.8,54.5,111.5,54.5z +M156.5,159.5c0,0-9.9-2-21-2c-11.1,0-42.4,4-53,4s-16-5-16-5 v-20h90V159.5z" /> + </group> +</vector>
\ No newline at end of file diff --git a/res/layout/per_app_fab_floating_window_icon.xml b/res/layout/per_app_fab_floating_window_icon.xml index b7e992f..8126269 100644 --- a/res/layout/per_app_fab_floating_window_icon.xml +++ b/res/layout/per_app_fab_floating_window_icon.xml @@ -5,11 +5,14 @@ <FrameLayout android:id="@+id/box" android:layout_height="match_parent" - android:layout_width="match_parent"> + android:layout_width="match_parent" + android:clipChildren="false" + android:elevation="10dp"> - <ImageView android:id="@+id/icon" + <View android:id="@+id/icon" android:layout_width="@dimen/floating_window_icon" android:layout_height="@dimen/floating_window_icon" - android:src="@drawable/quick_theme_fab" /> + android:background="@drawable/quick_theme_fab" + android:elevation="10dp"/> </FrameLayout> </FrameLayout>
\ No newline at end of file diff --git a/res/values/colors.xml b/res/values/colors.xml index 0a3c701..b043f91 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -55,11 +55,13 @@ <color name="processing_text_color">#ffffff</color> - <color name="per_app_theme_bg_color">#0fb6df</color> - <color name="per_app_theme_list_item_text_color">#fff</color> - <color name="per_app_theme_list_item_applied_text_color">#80ffffff</color> - <color name="per_app_theme_remove_background_normal">#0fb6df</color> - <color name="per_app_theme_remove_background_hover">#4fdcff</color> + <color name="per_app_theme_bg_color">#f5f5f5</color> + <color name="per_app_theme_list_item_text_color">#1f1f1f</color> + <color name="per_app_theme_list_item_applied_text_color">#00b1e5</color> + <color name="per_app_theme_remove_background_normal">#80000000</color> + <color name="per_app_theme_remove_background_hover">#80e53935</color> + <color name="per_app_theme_fab_bg_color">#00b1e5</color> + <color name="per_app_theme_fab_icon_color">#ffffff</color> <color name="per_app_theme_qs_icon_color">#ffffff</color> <color name="bottom_row_icon_color">#ffffff</color> diff --git a/src/com/cyngn/theme/perapptheming/PerAppThemingWindow.java b/src/com/cyngn/theme/perapptheming/PerAppThemingWindow.java index f550e62..c4c0c12 100644 --- a/src/com/cyngn/theme/perapptheming/PerAppThemingWindow.java +++ b/src/com/cyngn/theme/perapptheming/PerAppThemingWindow.java @@ -60,6 +60,8 @@ public class PerAppThemingWindow extends Service implements OnTouchListener, private static final int ANIMATION_DURATION = 300; + private static final int FAB_SCALE_ANIMATION_DURATION = 150; + private static final int LIST_ON_LEFT_SIDE = 0; private static final int LIST_ON_RIGHT_SIDE = 1; @@ -78,6 +80,8 @@ public class PerAppThemingWindow extends Service implements OnTouchListener, private static final int MAX_DEPRECIATION = 5; + private static final float FAB_ANIMATION_SCALE_FACTOR = 0.44f; + // Margin around the phone private static int MARGIN_VERTICAL; // Margin around the phone @@ -126,6 +130,8 @@ public class PerAppThemingWindow extends Service implements OnTouchListener, float mOrigY; boolean mDragged; + private int mListSide = LIST_ON_LEFT_SIDE; + private ThemeConfig mThemeConfig; @Override @@ -155,10 +161,19 @@ public class PerAppThemingWindow extends Service implements OnTouchListener, FLOATING_WINDOW_ICON_SIZE = (int) getResources().getDimension( R.dimen.floating_window_icon); + mDeleteView = new LinearLayout(getContext()); + View.inflate(getContext(), R.layout.per_app_delete_box_window, mDeleteView); + mDeleteBoxView = mDeleteView.findViewById(R.id.box); + addView(mDeleteView, 0, 0, Gravity.BOTTOM | Gravity.CENTER_VERTICAL, + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + mDeleteView.setVisibility(View.GONE); + mDraggableIcon = new LinearLayout(this); mDraggableIcon.setOnTouchListener(this); View.inflate(getContext(), R.layout.per_app_fab_floating_window_icon, mDraggableIcon); mDraggableIconImage = mDraggableIcon.findViewById(R.id.box); + mDraggableIconImage.setClipToOutline(true); mDraggableIconImage.getViewTreeObserver().addOnWindowAttachListener(mWindowAttachListener); mParams = addView(mDraggableIcon, 0, 0); updateIconPosition(MARGIN_HORIZONTAL, STARTING_POINT_Y); @@ -181,6 +196,10 @@ public class PerAppThemingWindow extends Service implements OnTouchListener, public boolean onTouch(View v, MotionEvent event) { switch(event.getAction()) { case MotionEvent.ACTION_DOWN: + if (mThemeListLayout.isAttachedToWindow()) { + hideThemeList(); + return false; + } mPrevDragX = mOrigX = event.getRawX(); mPrevDragY = mOrigY = event.getRawY(); @@ -209,9 +228,9 @@ public class PerAppThemingWindow extends Service implements OnTouchListener, if (!mDragged) { // clicked so show theme list final int mid = getScreenWidth() / 2; - int side = LIST_ON_LEFT_SIDE; - if (mCurrentPosX > mid) side = LIST_ON_RIGHT_SIDE; - if (!mThemeListLayout.isAttachedToWindow()) showThemeList(side); + mListSide = LIST_ON_LEFT_SIDE; + if (mCurrentPosX > mid) mListSide = LIST_ON_RIGHT_SIDE; + if (!mThemeListLayout.isAttachedToWindow()) showThemeList(); } else { // Animate the icon mAnimationTask = new AnimationTask(); @@ -229,40 +248,18 @@ public class PerAppThemingWindow extends Service implements OnTouchListener, case MotionEvent.ACTION_MOVE: mCurrentX = (int) (event.getRawX() - mDraggableIcon.getWidth() / 2); mCurrentY = (int) (event.getRawY() - mDraggableIcon.getHeight()); - if (isDeleteMode(mCurrentX, mCurrentY)) { - if (!mIsInDeleteMode) { - animateToDeleteBoxCenter(null); - } - } else if (isDeleteMode() && !mIsAnimationLocked) { + if (isDeleteMode()) { + mDeleteBoxView.setBackgroundResource(R.drawable.btn_quicktheme_remove_hover); + mIsInDeleteMode = true; + updateIconPosition(mCurrentX, mCurrentY); + } else if (mIsInDeleteMode){ + mDeleteBoxView.setBackgroundResource(R.drawable.btn_quicktheme_remove_normal); mIsInDeleteMode = false; - if (mAnimationTask != null) { - mAnimationTask.cancel(); - } - - mAnimationTask = new AnimationTask(mCurrentX, mCurrentY); - mAnimationTask.setDuration(EXIT_DELETE_MODE_ANIMATION_DURATION); - mAnimationTask.setInterpolator(new LinearInterpolator()); - mAnimationTask.setAnimationFinishedListener(new OnAnimationFinishedListener() { - @Override - public void onAnimationFinished() { - mIsAnimationLocked = false; - } - }); - - mAnimationTask.run(); - mIsAnimationLocked = true; - mDeleteBoxView.setBackgroundResource(R.drawable - .btn_quicktheme_remove_normal); } else { - if (mIsInDeleteMode) { - mDeleteBoxView.setBackgroundResource(R.drawable - .btn_quicktheme_remove_normal); - mIsInDeleteMode = false; - } if(!mIsAnimationLocked && mDragged) { + if(!mIsAnimationLocked && mDragged) { if (mAnimationTask != null) { mAnimationTask.cancel(); } - updateIconPosition(mCurrentX, mCurrentY); } } @@ -329,11 +326,11 @@ public class PerAppThemingWindow extends Service implements OnTouchListener, public void onFinish(boolean isSuccess) { ThemeManager tm = (ThemeManager) getSystemService(Context.THEME_SERVICE); tm.removeClient(this); - mDraggableIconImage.findViewById(R.id.icon).setVisibility(View.VISIBLE); mThemeListLayout.postDelayed(new Runnable() { @Override public void run() { hideScrim(); + startFabScaleUpAnimation(); } }, THEME_CHANGE_DELAY); } @@ -408,38 +405,17 @@ public class PerAppThemingWindow extends Service implements OnTouchListener, } private boolean isDeleteMode() { - return isDeleteMode(mParams.x, mParams.y); + return isHoveringOverDeleteBox(mParams.y); } - private boolean isDeleteMode(int x, int y) { - int screenWidth = getScreenWidth(); - int screenHeight = getScreenHeight(); - int boxWidth = DELETE_BOX_WIDTH; - int boxHeight = DELETE_BOX_HEIGHT; - - boolean horz = x + (mDraggableIcon == null ? 0 - : mDraggableIcon.getWidth()) > (screenWidth / 2 - boxWidth / 2) - && x < (screenWidth / 2 + boxWidth / 2); - - boolean vert = y + (mDraggableIcon == null ? 0 - : mDraggableIcon.getHeight()) > (screenHeight - boxHeight); - - return horz && vert; + private boolean isHoveringOverDeleteBox(int y) { + return y + mDraggableIconImage.getHeight() >= getScreenHeight() - DELETE_BOX_HEIGHT; } private void showDeleteBox() { if (!mDeleteBoxVisible) { mDeleteBoxVisible = true; - if (mDeleteView == null) { - mDeleteView = new LinearLayout(getContext()); - View.inflate(getContext(), R.layout.per_app_delete_box_window, mDeleteView); - mDeleteBoxView = mDeleteView.findViewById(R.id.box); - addView(mDeleteView, 0, 0, Gravity.BOTTOM | Gravity.CENTER_VERTICAL, - WindowManager.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.WRAP_CONTENT); - } else { - mDeleteView.setVisibility(View.VISIBLE); - } + mDeleteView.setVisibility(View.VISIBLE); mDeleteBoxView.setAlpha(0); mDeleteBoxView.setTranslationY(CLOSE_ANIMATION_DISTANCE); @@ -621,7 +597,7 @@ public class PerAppThemingWindow extends Service implements OnTouchListener, } }; - private void showThemeList(final int listSide) { + private void showThemeList() { if (mListLayoutParams == null) { mListLayoutParams = new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, @@ -633,20 +609,12 @@ public class PerAppThemingWindow extends Service implements OnTouchListener, PixelFormat.TRANSLUCENT); } mListLayoutParams.gravity = Gravity.TOP | - (listSide == LIST_ON_LEFT_SIDE ? Gravity.LEFT : Gravity.RIGHT); + (mListSide == LIST_ON_LEFT_SIDE ? Gravity.LEFT : Gravity.RIGHT); mWindowManager.addView(mThemeListLayout, mListLayoutParams); - mDraggableIconImage.animate() - .alpha(0f) - .setDuration(ANIMATION_DURATION) - .withEndAction(new Runnable() { - @Override - public void run() { - mDraggableIcon.setVisibility(View.GONE); - } - }); - - setThemeListPosition(listSide); + setThemeListPosition(); + startFabScaleDownAnimation(); + mAdapter.setCurrentTheme( mThemeConfig.getOverlayPkgNameForApp(Utils.getTopTaskPackageName(this))); mThemeListLayout.circularReveal(mParams.x + mDraggableIconImage.getWidth() / 2, @@ -657,10 +625,7 @@ public class PerAppThemingWindow extends Service implements OnTouchListener, if (showScrim) { showScrim(); } else { - mDraggableIcon.setVisibility(View.VISIBLE); - mDraggableIconImage.animate() - .alpha(1f) - .setDuration(ANIMATION_DURATION); + startFabScaleUpAnimation(); } mThemeListLayout.circularHide(mParams.x + mDraggableIconImage.getWidth() / 2, mParams.y + mDraggableIconImage.getHeight() / 2, ANIMATION_DURATION); @@ -725,7 +690,7 @@ public class PerAppThemingWindow extends Service implements OnTouchListener, .setDuration(ANIMATION_DURATION); } - private void setThemeListPosition(final int listSide) { + private void setThemeListPosition() { int thirdHeight = getScreenHeight() / 3; // use the center of the fab to decide where to place the list int fabLocationY = mParams.y + mDraggableIconImage.getHeight() / 2; @@ -744,17 +709,41 @@ public class PerAppThemingWindow extends Service implements OnTouchListener, // with the fab center. Bottom 3rd will position the bottom of the list with the // bottom of the fab. if (fabLocationY < thirdHeight) { - mListParams.topMargin = mParams.y; + mListParams.topMargin = mParams.y + mDraggableIconImage.getHeight() / 2; } else if (fabLocationY < thirdHeight * 2) { mListParams.topMargin = fabLocationY - listHeight / 2; } else { - mListParams.topMargin = mParams.y + mDraggableIconImage.getHeight() - listHeight; + mListParams.topMargin = mParams.y + mDraggableIconImage.getHeight() / 2 - listHeight; } mListParams.gravity = Gravity.TOP | - (listSide == LIST_ON_LEFT_SIDE ? Gravity.LEFT : Gravity.RIGHT); + (mListSide == LIST_ON_LEFT_SIDE ? Gravity.LEFT : Gravity.RIGHT); mThemeList.setLayoutParams(mListParams); } + private void startFabScaleDownAnimation() { + final int iconWidth = mDraggableIconImage.getWidth(); + final float translateX = (iconWidth - (float) iconWidth * FAB_ANIMATION_SCALE_FACTOR) / 2 * + (mListSide == LIST_ON_LEFT_SIDE ? -1 : 1); + + mDraggableIconImage.animate() + .scaleX(FAB_ANIMATION_SCALE_FACTOR) + .scaleY(FAB_ANIMATION_SCALE_FACTOR) + .translationXBy(translateX) + .setDuration(FAB_SCALE_ANIMATION_DURATION); + } + + private void startFabScaleUpAnimation() { + final float iconWidth = mDraggableIconImage.getWidth(); + final float translateX = (iconWidth - (float) iconWidth * FAB_ANIMATION_SCALE_FACTOR) / 2 * + (mListSide == LIST_ON_LEFT_SIDE ? 1 : -1); + + mDraggableIconImage.animate() + .scaleX(1f) + .scaleY(1f) + .translationXBy(translateX) + .setDuration(FAB_SCALE_ANIMATION_DURATION); + } + private AdapterView.OnItemClickListener mThemeClickedListener = new AdapterView.OnItemClickListener() { @Override |