From bdf637a6c1c7fcdf687356a1e0e33ec51eb6e152 Mon Sep 17 00:00:00 2001 From: Pierrot Date: Fri, 5 Apr 2019 10:29:11 +0200 Subject: [PATCH] Tap outside of folder to close it (with a setting, off by default for compatibility with existing setups) --- .../activities/Customize.java | 4 + .../configuration/FolderConfig.java | 1 + .../lightning_launcher/engine/Screen.java | 8 +- .../script/api/PropertySet.java | 1 + .../lightning_launcher/views/FolderView.java | 107 +++++++++++------- app/llx/core/src/main/res/values/strings.xml | 1 + 6 files changed, 83 insertions(+), 39 deletions(-) diff --git a/app/llx/app/src/main/java/net/pierrox/lightning_launcher/activities/Customize.java b/app/llx/app/src/main/java/net/pierrox/lightning_launcher/activities/Customize.java index b5c0249..4660392 100644 --- a/app/llx/app/src/main/java/net/pierrox/lightning_launcher/activities/Customize.java +++ b/app/llx/app/src/main/java/net/pierrox/lightning_launcher/activities/Customize.java @@ -1317,6 +1317,7 @@ public class Customize extends ResourceWrapperActivity implements is_folder_page ? R.string.this_folder_feel_t : R.string.folder_feel_t, R.string.folder_feel_s)); mPreferencesPageFolderFeel = new ArrayList(); + mPreferencesPageFolderFeel.add(mPGFolderFeelOutsideTapClose = new LLPreferenceCheckBox(this, ID_mPGFolderFeelOutsideTapClose, R.string.otc_t, 0, fc.outsideTapClose, fc_def == null ? null : fc_def.outsideTapClose)); mPreferencesPageFolderFeel.add(mPGFolderFeelAutoClose = new LLPreferenceCheckBox(this, ID_mPGFolderFeelAutoClose, R.string.auto_close_t, R.string.auto_close_s, fc.autoClose, fc_def == null ? null : fc_def.autoClose)); if(!is_folder_page) { mPreferencesPageFolderFeel.add(mPGFolderFeelCloseOther = new LLPreferenceCheckBox(this, ID_mPGFolderFeelCloseOther, R.string.cof_t, R.string.cof_s, fc.closeOther, fc_def == null ? null : fc_def.closeOther)); @@ -1669,6 +1670,7 @@ public class Customize extends ResourceWrapperActivity implements fc.animationIn = (FolderAnimation) mPGFolderLookAnimOpen.getValueEnum(); fc.animationOut = (FolderAnimation) mPGFolderLookAnimClose.getValueEnum(); fc.animFade = mPGFolderLookAnimFade.isChecked(); + fc.outsideTapClose = mPGFolderFeelOutsideTapClose.isChecked(); fc.autoClose = mPGFolderFeelAutoClose.isChecked(); if(!is_folder) { fc.closeOther = mPGFolderFeelCloseOther.isChecked(); @@ -2174,6 +2176,7 @@ public class Customize extends ResourceWrapperActivity implements private LLPreferenceEventAction mPageEventMenu; private LLPreference mPGFolderFeel; + private LLPreferenceCheckBox mPGFolderFeelOutsideTapClose; private LLPreferenceCheckBox mPGFolderFeelAutoClose; private LLPreferenceCheckBox mPGFolderFeelCloseOther; private LLPreferenceCheckBox mPGFolderFeelAnimGlitchFix; @@ -2237,6 +2240,7 @@ public class Customize extends ResourceWrapperActivity implements private static final int ID_mPGZoomScrollDisableDiagonal = 90; private static final int ID_mPGZoomScrollEnablePinch = 91; private static final int ID_mPGFolderFeel = 92; + private static final int ID_mPGFolderFeelOutsideTapClose = 515; private static final int ID_mPGFolderFeelAutoClose = 93; private static final int ID_mPGFolderFeelAnimGlitchFix = 94; private static final int ID_mPGMisc = 95; diff --git a/app/llx/core/src/main/java/net/pierrox/lightning_launcher/configuration/FolderConfig.java b/app/llx/core/src/main/java/net/pierrox/lightning_launcher/configuration/FolderConfig.java index 1e4a080..c8cecbf 100644 --- a/app/llx/core/src/main/java/net/pierrox/lightning_launcher/configuration/FolderConfig.java +++ b/app/llx/core/src/main/java/net/pierrox/lightning_launcher/configuration/FolderConfig.java @@ -47,6 +47,7 @@ public class FolderConfig extends JsonLoader { public FolderAnimation animationIn=FolderAnimation.OPEN_CLOSE; public FolderAnimation animationOut=FolderAnimation.OPEN_CLOSE; public FolderIconStyle iconStyle=FolderIconStyle.GRID_2_2; + public boolean outsideTapClose=true; public boolean autoClose=false; public boolean closeOther=false; public boolean animationGlitchFix=false; diff --git a/app/llx/core/src/main/java/net/pierrox/lightning_launcher/engine/Screen.java b/app/llx/core/src/main/java/net/pierrox/lightning_launcher/engine/Screen.java index f96aeaf..a7b553b 100644 --- a/app/llx/core/src/main/java/net/pierrox/lightning_launcher/engine/Screen.java +++ b/app/llx/core/src/main/java/net/pierrox/lightning_launcher/engine/Screen.java @@ -84,7 +84,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; -public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.ItemViewListener, Page.PageListener { +public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.ItemViewListener, Page.PageListener, FolderView.OnTapOutsideListener { public static final int PAGE_DIRECTION_HINT_BACKWARD = -1; public static final int PAGE_DIRECTION_HINT_FORWARD = 1; @@ -837,6 +837,7 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView. return runAction(engine, "C_LONG_CLICK", ea.action==GlobalConfig.UNSET ? engine.getGlobalConfig().bgLongTap : ea); } }); + fv.setOnTapOutsideListener(this); mFolderContainer.addView(fv); mFolderViews.add(fv); } @@ -1021,6 +1022,11 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView. } } + @Override + public void onTapOutside(FolderView fv) { + closeFolder(fv, true); + } + /***************************************** GEOMETRY ***********************************/ @TargetApi(Build.VERSION_CODES.HONEYCOMB) diff --git a/app/llx/core/src/main/java/net/pierrox/lightning_launcher/script/api/PropertySet.java b/app/llx/core/src/main/java/net/pierrox/lightning_launcher/script/api/PropertySet.java index 921cb4d..9546716 100644 --- a/app/llx/core/src/main/java/net/pierrox/lightning_launcher/script/api/PropertySet.java +++ b/app/llx/core/src/main/java/net/pierrox/lightning_launcher/script/api/PropertySet.java @@ -198,6 +198,7 @@ import java.lang.reflect.Field; * f.animationOut string Read/Write NONE|OPEN_CLOSE|SLIDE_FROM_LEFT|SLIDE_FROM_RIGHT|SLIDE_FROM_TOP|SLIDE_FROM_BOTTOM * f.animFade boolean Read/Write true/false * f.iconStyle string Read/Write NORMAL|GRID_2_2|STACK + * f.outsideTapClose boolean Read/Write true/false * f.autoClose boolean Read/Write true/false * f.closeOther boolean Read/Write true/false * f.wAH string Read/Write LEFT|CENTER|RIGHT|CUSTOM diff --git a/app/llx/core/src/main/java/net/pierrox/lightning_launcher/views/FolderView.java b/app/llx/core/src/main/java/net/pierrox/lightning_launcher/views/FolderView.java index 91532f6..6192848 100644 --- a/app/llx/core/src/main/java/net/pierrox/lightning_launcher/views/FolderView.java +++ b/app/llx/core/src/main/java/net/pierrox/lightning_launcher/views/FolderView.java @@ -15,6 +15,7 @@ import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; import android.view.Gravity; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.AlphaAnimation; @@ -26,11 +27,22 @@ import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.TextView; -public class FolderView extends BoxLayout { +public class FolderView extends FrameLayout { + public interface OnTapOutsideListener { + void onTapOutside(FolderView fv); + } private static final int ANIM_DURATION=400; - - private LinearLayout mContainer; - private FrameLayout mInnerContainer; + + // the innermost container where the item layout is attached (no title, no border) + private FrameLayout mContentContainer; + + // the container for title and content (without borders) + private LinearLayout mInnerContainer; + + // the outer container adds borders around the inner container + private BoxLayout mOuterContainer; + + private TextView mEmptyMsg; private TextView mTitle; private View mSeparator; @@ -50,35 +62,40 @@ public class FolderView extends BoxLayout { private boolean mAllowEmptyMessage = true; + private OnTapOutsideListener mOnTapOutsideListener; + public FolderView(Context context) { - super(context, null, true); + super(context); setVisibility(View.GONE); - mContainer=new LinearLayout(context); - mContainer.setOrientation(LinearLayout.VERTICAL); - mContainer.setGravity(Gravity.CENTER_HORIZONTAL); + mInnerContainer = new LinearLayout(context); + mInnerContainer.setOrientation(LinearLayout.VERTICAL); + mInnerContainer.setGravity(Gravity.CENTER_HORIZONTAL); - mInnerContainer=new FrameLayout(context); + mContentContainer = new FrameLayout(context); mItemLayout=new ItemLayout(context, null); - mInnerContainer.addView(mItemLayout, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + mContentContainer.addView(mItemLayout, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); mEmptyMsg=new TextView(context); mEmptyMsg.setGravity(Gravity.CENTER); mEmptyMsg.setPadding(20, 20, 20, 20); FrameLayout.LayoutParams elp=new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); elp.gravity=Gravity.CENTER; - mInnerContainer.addView(mEmptyMsg, elp); + mContentContainer.addView(mEmptyMsg, elp); mTitle=new MyTextView(context); mTitle.setGravity(Gravity.CENTER); - mContainer.addView(mTitle, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + mInnerContainer.addView(mTitle, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); mSeparator=new View(context); mSeparator.setBackgroundColor(0xffffffff); - mContainer.addView(mSeparator, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1)); - mContainer.addView(mInnerContainer, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + mInnerContainer.addView(mSeparator, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1)); + mInnerContainer.addView(mContentContainer, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + + mOuterContainer = new BoxLayout(context, null, true); + addView(mOuterContainer, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); } /** @@ -103,24 +120,12 @@ public class FolderView extends BoxLayout { if(box.size[Box.MR]==0) box.size[Box.MR]=1; if(box.size[Box.MB]==0) box.size[Box.MB]=1; } - setChild(mContainer, box); -// if(mFolderConfig.borderStyle==FolderBorderStyle.PLAIN) { -// setPadding(mFolderConfig.borderPlainLeft, mFolderConfig.borderPlainTop, mFolderConfig.borderPlainRight, mFolderConfig.borderPlainBottom); -// setBackgroundColor(mFolderConfig.borderPlainColor); -// } else { -// if(mFolderConfig.animationGlitchFix) { -// // fix for an animation glitch that leaves some unrefreshed pixels sometime -// setPadding(1, 1, 1, 1); -// } -// } + mOuterContainer.setChild(mInnerContainer, box); - int visibility=mFolderConfig.titleVisibility ? View.VISIBLE : View.GONE; mTitle.setVisibility(visibility); mSeparator.setVisibility(visibility); -// mContainer.setBackgroundColor(mFolderConfig.fbackgroundColor); -// mContainer.setPadding(mFolderConfig.paddingLeft, mFolderConfig.paddingTop, mFolderConfig.paddingRight, mFolderConfig.paddingBottom); if(mFolderConfig.titleVisibility) { mTitle.setText(folder.getLabel()); mTitle.setTextSize(mFolderConfig.titleFontSize); @@ -149,6 +154,10 @@ public class FolderView extends BoxLayout { } } + public void setOnTapOutsideListener(OnTapOutsideListener onTapOutsideListener) { + mOnTapOutsideListener = onTapOutsideListener; + } + public void updateEmptyMessageVisibility() { if(mPage.items.size()==0 && mAllowEmptyMessage) { mEmptyMsg.setVisibility(View.VISIBLE); @@ -163,23 +172,25 @@ public class FolderView extends BoxLayout { if(mEditMode) { int[] offset=new int[2]; - getLocationInWindow(offset); + mOuterContainer.getLocationInWindow(offset); offset[0]-=container_offset[0]; offset[1]-=container_offset[1]; Matrix m=mItemLayout.getLocalTransform(); m.postTranslate(offset[0], offset[1]); mItemLayout.setLocalTransform(m); + mOuterContainer.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + mContentContainer.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); mInnerContainer.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); - mContainer.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); mItemLayout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); } else { if(mFolderConfig.autoFindOrigin) { mItemLayout.setAutoFindOrigin(true); } + mOuterContainer.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + mContentContainer.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); mInnerContainer.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); - mContainer.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); mItemLayout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); } @@ -208,25 +219,27 @@ public class FolderView extends BoxLayout { if(animate) { Animation animation = getAnimation(false); if(animation != null) { - startAnimation(animation); + mOuterContainer.startAnimation(animation); return; } } setVisibility(View.GONE); } - @Override public void resume() { - super.resume(); + mOuterContainer.resume(); mItemLayout.resume(); } - @Override public void pause() { - super.pause(); + mOuterContainer.pause(); mItemLayout.pause(); } + public void destroy() { + mOuterContainer.destroy(); + } + public Folder getOpener() { return mOpener; } @@ -277,8 +290,9 @@ public class FolderView extends BoxLayout { } lp.gravity = gravity; - setLayoutParams(lp); - requestLayout(); + mOuterContainer.setLayoutParams(lp); + + requestLayout(); } @Override @@ -288,12 +302,29 @@ public class FolderView extends BoxLayout { if(mWaitingForLayoutToBeginAnimation) { Animation animation = getAnimation(true); if(animation != null) { - startAnimation(animation); + mOuterContainer.startAnimation(animation); } mWaitingForLayoutToBeginAnimation = false; } } + @Override + public void setOnLongClickListener(View.OnLongClickListener l) { + // redirect events on the real folder container + mOuterContainer.setOnLongClickListener(l); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if(mFolderConfig.outsideTapClose && event.getAction() == MotionEvent.ACTION_DOWN) { + if(mOnTapOutsideListener != null) { + mOnTapOutsideListener.onTapOutside(this); + } + return true; + } + return false; + } + private Animation getAnimation(final boolean in) { AnimationSet a=new AnimationSet(true); diff --git a/app/llx/core/src/main/res/values/strings.xml b/app/llx/core/src/main/res/values/strings.xml index 8d2e174..72d92be 100644 --- a/app/llx/core/src/main/res/values/strings.xml +++ b/app/llx/core/src/main/res/values/strings.xml @@ -296,6 +296,7 @@ Disable diagonal scrolling Only scroll in one direction at a time Pinch to zoom in or out +Tap outside to close Auto close Close the folder as soon as one of its app is launched Animation glitch fix