diff --git a/app/build.gradle b/app/build.gradle index 6f320b89..caeac46c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -120,11 +120,11 @@ dependencies { // compile 'com.github.hyb1996:android-multi-level-listview:1.1' compile 'de.psdev.licensesdialog:licensesdialog:1.8.1' - compile 'io.mattcarroll.hover:hover:0.9.7' compile 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1' compile 'com.yqritc:recyclerview-flexibledivider:1.4.0' compile 'com.wang.avi:library:2.1.3' compile 'org.apache.commons:commons-lang3:3.5' + compile 'com.github.hyb1996:FloatingCircularActionMenu:0.0.1' // RxJava compile "io.reactivex.rxjava2:rxjava:2.1.0" compile 'io.reactivex.rxjava2:rxandroid:2.0.1' diff --git a/app/src/main/java/com/stardust/hover/HoverMenuBuilder.java b/app/src/main/java/com/stardust/hover/HoverMenuBuilder.java deleted file mode 100644 index 30079ec3..00000000 --- a/app/src/main/java/com/stardust/hover/HoverMenuBuilder.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.stardust.hover; - -import android.content.Context; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.view.ViewGroup; -import android.view.WindowManager; - -import io.mattcarroll.hover.HoverMenu; -import io.mattcarroll.hover.HoverMenuAdapter; -import io.mattcarroll.hover.Navigator; -import io.mattcarroll.hover.defaulthovermenu.view.ViewHoverMenu; - -/** - * Created by Stardust on 2017/3/11. - */ - -public class HoverMenuBuilder { - - public static final int DISPLAY_MODE_WINDOW = 1; // Display directly in a window. - public static final int DISPLAY_MODE_VIEW = 2; // Display within View hierarchy. - - private Context mContext; - private int mDisplayMode = DISPLAY_MODE_WINDOW; - private WindowManager mWindowManager; - private Navigator mNavigator; - private HoverMenuAdapter mAdapter; - private String mSavedVisualState = null; - - public HoverMenuBuilder(@NonNull Context context) { - mContext = context; - } - - public HoverMenuBuilder displayWithinWindow() { - mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); - mDisplayMode = DISPLAY_MODE_WINDOW; - return this; - } - - public HoverMenuBuilder displayWithinView(@NonNull ViewGroup container) { - mDisplayMode = DISPLAY_MODE_VIEW; - return this; - } - - public HoverMenuBuilder useNavigator(@Nullable Navigator navigator) { - mNavigator = navigator; - return this; - } - - public HoverMenuBuilder useAdapter(@Nullable HoverMenuAdapter adapter) { - mAdapter = adapter; - return this; - } - - public HoverMenuBuilder restoreVisualState(@NonNull String visualState) { - mSavedVisualState = visualState; - return this; - } - - public HoverMenu build() { - if (DISPLAY_MODE_WINDOW == mDisplayMode) { - WindowHoverMenu windowHoverMenu = new WindowHoverMenu(mContext, mWindowManager, mNavigator, mSavedVisualState); - windowHoverMenu.setAdapter(mAdapter); - return windowHoverMenu; - } else { - ViewHoverMenu viewHoverMenu = new ViewHoverMenu(mContext); - viewHoverMenu.setAdapter(mAdapter); - return viewHoverMenu; - } - } -} diff --git a/app/src/main/java/com/stardust/hover/SimpleHoverMenuTransitionListener.java b/app/src/main/java/com/stardust/hover/SimpleHoverMenuTransitionListener.java deleted file mode 100644 index 085bc41d..00000000 --- a/app/src/main/java/com/stardust/hover/SimpleHoverMenuTransitionListener.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.stardust.hover; - -import io.mattcarroll.hover.defaulthovermenu.*; -import io.mattcarroll.hover.defaulthovermenu.HoverMenuView; - -/** - * Created by Stardust on 2017/3/12. - */ - -public class SimpleHoverMenuTransitionListener implements HoverMenuView.HoverMenuTransitionListener { - @Override - public void onCollapsing() { - - } - - @Override - public void onCollapsed() { - - } - - @Override - public void onExpanding() { - - } - - @Override - public void onExpanded() { - - } -} diff --git a/app/src/main/java/com/stardust/hover/WindowHoverMenu.java b/app/src/main/java/com/stardust/hover/WindowHoverMenu.java deleted file mode 100644 index 04569bc7..00000000 --- a/app/src/main/java/com/stardust/hover/WindowHoverMenu.java +++ /dev/null @@ -1,254 +0,0 @@ -package com.stardust.hover; - -import android.content.Context; -import android.graphics.PointF; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.view.ViewConfiguration; -import android.view.WindowManager; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import io.mattcarroll.hover.HoverMenu; -import io.mattcarroll.hover.HoverMenuAdapter; -import io.mattcarroll.hover.Navigator; -import io.mattcarroll.hover.defaulthovermenu.HoverMenuView; -import io.mattcarroll.hover.defaulthovermenu.window.InWindowDragger; - -/** - * Created by Stardust on 2017/3/11. - */ - -public class WindowHoverMenu implements HoverMenu { - - private HoverMenuView.HoverMenuTransitionListener mHoverMenuTransitionListener; - - private static final String TAG = "WindowHoverMenu"; - - public WindowViewController getWindowViewController() { - return mWindowViewController; - } - - private WindowViewController mWindowViewController; // Shows/hides/positions Views in a Window. - - - private HoverMenuView mHoverMenuView; // The visual presentation of the Hover menu. - private boolean mIsShowingHoverMenu; // Are we currently display mHoverMenuView? - private boolean mIsInDragMode; // If we're not in drag mode then we're in menu mode. - private Set mOnExitListeners = new HashSet<>(); - - private HoverMenuView.HoverMenuTransitionListener mHoverMenuTransitionListenerProxy = new HoverMenuView.HoverMenuTransitionListener() { - @Override - public void onCollapsing() { - if (mHoverMenuTransitionListener != null) - mHoverMenuTransitionListener.onCollapsing(); - } - - @Override - public void onCollapsed() { - mIsInDragMode = true; - // When collapsed, we make mHoverMenuView untouchable so that the WindowDragWatcher can - // take over. We do this so that touch events outside the drag area can propagate to - // applications on screen. - mWindowViewController.makeUntouchable(mHoverMenuView); - if (mHoverMenuTransitionListener != null) - mHoverMenuTransitionListener.onCollapsed(); - } - - @Override - public void onExpanding() { - mIsInDragMode = false; - if (mHoverMenuTransitionListener != null) - mHoverMenuTransitionListener.onExpanding(); - } - - @Override - public void onExpanded() { - mWindowViewController.makeTouchable(mHoverMenuView); - if (mHoverMenuTransitionListener != null) - mHoverMenuTransitionListener.onExpanded(); - } - }; - - private HoverMenuView.HoverMenuExitRequestListener mMenuExitRequestListener = new HoverMenuView.HoverMenuExitRequestListener() { - @Override - public void onExitRequested() { - hide(); - } - }; - - public WindowHoverMenu(@NonNull Context context, @NonNull WindowManager windowManager, @Nullable Navigator navigator, @Nullable String savedVisualState) { - mWindowViewController = new WindowViewController(windowManager); - - InWindowDragger inWindowDragger = new InWindowDragger( - context, - mWindowViewController, - ViewConfiguration.get(context).getScaledTouchSlop() - ); - - PointF anchorState = new PointF(2, 0.5f); // Default to right side, half way down. See CollapsedMenuAnchor. - if (null != savedVisualState) { - try { - VisualStateMemento visualStateMemento = VisualStateMemento.fromJsonString(savedVisualState); - anchorState.set(visualStateMemento.getAnchorSide(), visualStateMemento.getNormalizedPositionY()); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - mHoverMenuView = new HoverMenuView(context, navigator, inWindowDragger, anchorState); - mHoverMenuView.setHoverMenuExitRequestListener(mMenuExitRequestListener); - mHoverMenuView.setHoverMenuTransitionListener(mHoverMenuTransitionListenerProxy); - } - - - public void setHoverMenuTransitionListener(HoverMenuView.HoverMenuTransitionListener hoverMenuTransitionListener) { - mHoverMenuTransitionListener = hoverMenuTransitionListener; - } - - public HoverMenuView getHoverMenuView() { - return mHoverMenuView; - } - - @Override - public String getVisualState() { - PointF anchor = mHoverMenuView.getAnchorState(); - return new VisualStateMemento((int) anchor.x, anchor.y).toJsonString(); - } - - @Override - public void restoreVisualState(@NonNull String savedVisualState) { - try { - VisualStateMemento memento = VisualStateMemento.fromJsonString(savedVisualState); - mHoverMenuView.setAnchorState(new PointF(memento.getAnchorSide(), memento.getNormalizedPositionY())); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - @Override - public void setAdapter(@Nullable HoverMenuAdapter adapter) { - mHoverMenuView.setAdapter(adapter); - } - - /** - * Initializes and displays the Hover menu. To destroy and remove the Hover menu, use {@link #hide()}. - */ - @Override - public void show() { - if (!mIsShowingHoverMenu) { - mWindowViewController.addView(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, false, mHoverMenuView); - - // Sync our control state with the HoverMenuView state. - if (mHoverMenuView.isExpanded()) { - mWindowViewController.makeTouchable(mHoverMenuView); - } else { - collapseMenu(); - } - - mIsShowingHoverMenu = true; - } - } - - /** - * Exits the Hover menu system. This method is the inverse of {@link #show()}. - */ - @Override - public void hide() { - if (mIsShowingHoverMenu) { - mIsShowingHoverMenu = false; - - // Notify our exit listeners that we're exiting. - notifyOnExitListeners(); - - // Cleanup the control structures and Views. - mWindowViewController.removeView(mHoverMenuView); - mHoverMenuView.release(); - } - } - - /** - * Expands the Hover menu to show all of its tabs and a content area for the selected tab. To - * collapse the menu down a single active tab, use {@link #collapseMenu()}. - */ - @Override - public void expandMenu() { - if (mIsInDragMode) { - mHoverMenuView.expand(); - } - } - - /** - * Collapses the Hover menu down to its single active tab and allows the tab to be dragged - * around the display. This method is the inverse of {@link #expandMenu()}. - */ - @Override - public void collapseMenu() { - if (!mIsInDragMode) { - mHoverMenuView.collapse(); - } - } - - - @Override - public void addOnExitListener(@NonNull OnExitListener onExitListener) { - mOnExitListeners.add(onExitListener); - } - - @Override - public void removeOnExitListener(@NonNull OnExitListener onExitListener) { - mOnExitListeners.remove(onExitListener); - } - - private void notifyOnExitListeners() { - for (OnExitListener listener : mOnExitListeners) { - listener.onExitByUserRequest(); - } - } - - private static class VisualStateMemento { - - private static final String JSON_KEY_ANCHOR_SIDE = "anchor_side"; - private static final String JSON_KEY_NORMALIZED_POSITION_Y = "normalized_position_y"; - - public static VisualStateMemento fromJsonString(@NonNull String jsonString) throws JSONException { - JSONObject jsonObject = new JSONObject(jsonString); - int anchorSide = jsonObject.getInt(JSON_KEY_ANCHOR_SIDE); - float normalizedPositionY = (float) jsonObject.getDouble(JSON_KEY_NORMALIZED_POSITION_Y); - return new VisualStateMemento(anchorSide, normalizedPositionY); - } - - private int mAnchorSide; - private float mNormalizedPositionY; - - public VisualStateMemento(int anchorSide, float normalizedPositionY) { - mAnchorSide = anchorSide; - mNormalizedPositionY = normalizedPositionY; - } - - public int getAnchorSide() { - return mAnchorSide; - } - - public float getNormalizedPositionY() { - return mNormalizedPositionY; - } - - public String toJsonString() { - try { - JSONObject jsonObject = new JSONObject(); - jsonObject.put(JSON_KEY_ANCHOR_SIDE, mAnchorSide); - jsonObject.put(JSON_KEY_NORMALIZED_POSITION_Y, mNormalizedPositionY); - return jsonObject.toString(); - } catch (JSONException e) { - e.printStackTrace(); - return null; - } - } - } -} diff --git a/app/src/main/java/com/stardust/hover/WindowViewController.java b/app/src/main/java/com/stardust/hover/WindowViewController.java deleted file mode 100644 index b2f2841d..00000000 --- a/app/src/main/java/com/stardust/hover/WindowViewController.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.stardust.hover; - -import android.graphics.PixelFormat; -import android.support.annotation.NonNull; -import android.view.Gravity; -import android.view.View; -import android.view.WindowManager; - -/** - * Created by Stardust on 2017/7/2. - */ - -public class WindowViewController extends io.mattcarroll.hover.defaulthovermenu.window.WindowViewController { - - private WindowManager mWindowManager; - - public WindowViewController(@NonNull WindowManager windowManager) { - super(windowManager); - mWindowManager = windowManager; - } - - @Override - public void addView(int width, int height, boolean isTouchable, @NonNull View view) { - int touchableFlag = isTouchable ? 0 : WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; - - WindowManager.LayoutParams params = new WindowManager.LayoutParams( - width, - height, - WindowManager.LayoutParams.TYPE_PHONE, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | touchableFlag, - PixelFormat.TRANSLUCENT - ); - params.gravity = Gravity.TOP | Gravity.LEFT; - params.x = 0; - params.y = 0; - - mWindowManager.addView(view, params); - } -} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/FloatyWindowManger.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/FloatyWindowManger.java index bec75d9c..b57b8432 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/FloatyWindowManger.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/FloatyWindowManger.java @@ -2,13 +2,16 @@ package com.stardust.scriptdroid.external.floatingwindow; import android.content.Context; import android.content.Intent; -import android.view.WindowManager; import android.widget.Toast; import com.stardust.enhancedfloaty.FloatyService; import com.stardust.enhancedfloaty.FloatyWindow; import com.stardust.enhancedfloaty.util.FloatingWindowPermissionUtil; +import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.R; +import com.stardust.scriptdroid.ui.floating.CircularMenu; + +import java.lang.ref.WeakReference; import ezy.assist.compat.SettingsCompat; @@ -18,6 +21,8 @@ import ezy.assist.compat.SettingsCompat; public class FloatyWindowManger { + private static WeakReference sCircularMenu; + public static void addWindow(Context context, FloatyWindow window) { context.startService(new Intent(context, FloatyService.class)); if (!SettingsCompat.canDrawOverlays(context)) { @@ -49,4 +54,23 @@ public class FloatyWindowManger { public static void closeWindow(FloatyWindow window) { window.close(); } + + + public static boolean isCircularMenuShowing() { + return sCircularMenu != null && sCircularMenu.get() != null; + } + + public static void showCircularMenu() { + App.getApp().startService(new Intent(App.getApp(), FloatyService.class)); + CircularMenu menu = new CircularMenu(App.getApp()); + sCircularMenu = new WeakReference<>(menu); + } + + public static void hideCircularMenu() { + if (sCircularMenu == null) + return; + CircularMenu menu = sCircularMenu.get(); + menu.close(); + sCircularMenu = null; + } } diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/HoverMenuManger.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/HoverMenuManger.java deleted file mode 100644 index ccf24900..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/HoverMenuManger.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.stardust.scriptdroid.external.floatingwindow; - -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Build; -import android.preference.PreferenceManager; -import android.provider.Settings; -import android.support.annotation.RequiresApi; -import android.util.Log; -import android.widget.Toast; - -import com.stardust.scriptdroid.App; -import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService; -import com.stardust.util.IntentUtil; - -import ezy.assist.compat.SettingsCompat; - -/** - * Created by Stardust on 2017/3/10. - */ - -public class HoverMenuManger { - - private static final String KEY_FLOATING_WINDOW_PERMISSION = "May we go back..I...miss..you..Eating..17.5.9"; - private static final String TAG = "HoverMenuManger"; - - public static void showHoverMenu() { - if (!HoverMenuService.isServiceRunning()) { - if (!SettingsCompat.canDrawOverlays(App.getApp())) { - Toast.makeText(App.getApp(), R.string.text_no_floating_window_permission, Toast.LENGTH_SHORT).show(); - try { - SettingsCompat.manageDrawOverlays(App.getApp()); - } catch (Exception e) { - e.printStackTrace(); - IntentUtil.goToAppDetailSettings(App.getApp()); - } - } else { - HoverMenuService.startService(App.getApp()); - } - } - } - - public static boolean isHoverMenuShowing() { - return HoverMenuService.isServiceRunning(); - } - - - public static void hideHoverMenu() { - App.getApp().stopService(new Intent(App.getApp(), HoverMenuService.class)); - } -} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/HoverMenuAdapter.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/HoverMenuAdapter.java deleted file mode 100644 index 2cbb0745..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/HoverMenuAdapter.java +++ /dev/null @@ -1,216 +0,0 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.PorterDuff; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.ShapeDrawable; -import android.graphics.drawable.shapes.OvalShape; -import android.os.Build; -import android.support.annotation.ColorInt; -import android.support.annotation.DrawableRes; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.util.TypedValue; -import android.view.View; - -import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.external.floatingwindow.menu.content.MainMenuNavigatorContent; -import com.stardust.scriptdroid.external.floatingwindow.menu.content.RecordNavigatorContent; -import com.stardust.scriptdroid.external.floatingwindow.menu.content.ScriptListNavigatorContent; -import com.stardust.theme.ThemeColorManagerCompat; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import io.mattcarroll.hover.NavigatorContent; - - -/** - * Created by Stardust on 2017/3/11. - */ - -public class HoverMenuAdapter implements io.mattcarroll.hover.HoverMenuAdapter { - - - public static final String ID_MAIN = "main"; - public static final String ID_RECORD = "record"; - public static final String ID_SCRIPT_LIST = "script_list"; - - private final Context mContext; - private final List mTabIds; - private final Map mData = new LinkedHashMap<>(); - private final Set mContentChangeListeners = new HashSet<>(); - private View[] mViews; - - public HoverMenuAdapter(@NonNull HoverMenuService context) { - mContext = context; - - mData.put(HoverMenuAdapter.ID_MAIN, new MainMenuNavigatorContent(context)); - mData.put(HoverMenuAdapter.ID_RECORD, new RecordNavigatorContent(context)); - mData.put(HoverMenuAdapter.ID_SCRIPT_LIST, new ScriptListNavigatorContent(context)); - - mTabIds = new ArrayList<>(); - for (String tabId : mData.keySet()) { - mTabIds.add(tabId); - } - mViews = new View[mTabIds.size()]; - } - - @Override - public int getTabCount() { - return mTabIds.size(); - } - - @Override - public View getTabView(int index) { - mViews[index] = getTabViewInner(index); - return mViews[index]; - } - - private View getTabViewInner(int index) { - String menuItemId = mTabIds.get(index); - if (ID_MAIN.equals(menuItemId)) { - return createTabView(R.drawable.ic_android_eat_js_64); - } else if (ID_RECORD.equals(menuItemId)) { - return createTabView(R.drawable.ic_ali_record); - } else if (ID_SCRIPT_LIST.equals(menuItemId)) { - return createTabView(R.drawable.ic_menu); - } else { - throw new RuntimeException("Unknown tab selected: " + index); - } - } - - @Override - public long getTabId(int position) { - return position; - } - - @Override - public NavigatorContent getNavigatorContent(int index) { - String tabId = mTabIds.get(index); - return mData.get(tabId); - } - - @Override - public void addContentChangeListener(@NonNull ContentChangeListener listener) { - mContentChangeListeners.add(listener); - } - - @Override - public void removeContentChangeListener(@NonNull ContentChangeListener listener) { - mContentChangeListeners.remove(listener); - } - - public void selectTab(String id) { - int i = mTabIds.indexOf(id); - mViews[i].performClick(); - } - - protected void notifyDataSetChanged() { - for (ContentChangeListener listener : mContentChangeListeners) { - listener.onContentChange(this); - } - } - - private View createTabView(@DrawableRes int tabBitmapRes) { - return createTabView(tabBitmapRes, ThemeColorManagerCompat.getColorPrimary(), Color.WHITE); - } - - private View createTabView(@DrawableRes int tabBitmapRes, @ColorInt int backgroundColor, @ColorInt Integer iconColor) { - Resources resources = mContext.getResources(); - int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, resources.getDisplayMetrics()); - - DemoTabView view = new DemoTabView(mContext, getCircleDrawable(), resources.getDrawable(tabBitmapRes)); - view.setTabBackgroundColor(backgroundColor); - view.setTabForegroundColor(iconColor); - view.setPadding(padding, padding, padding, padding); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - view.setElevation(padding); - } - return view; - } - - private Drawable getCircleDrawable() { - ShapeDrawable oval = new ShapeDrawable(new OvalShape()); - return oval; - } - - - public class DemoTabView extends View { - - private int mBackgroundColor; - private Integer mForegroundColor; - - private Drawable mCircleDrawable; - private Drawable mIconDrawable; - private int mIconInsetLeft, mIconInsetTop, mIconInsetRight, mIconInsetBottom; - - public DemoTabView(Context context, Drawable backgroundDrawable, Drawable iconDrawable) { - super(context); - mCircleDrawable = backgroundDrawable; - mIconDrawable = iconDrawable; - init(); - } - - private void init() { - int insetsDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getContext().getResources().getDisplayMetrics()); - mIconInsetLeft = mIconInsetTop = mIconInsetRight = mIconInsetBottom = insetsDp; - } - - public void setTabBackgroundColor(@ColorInt int backgroundColor) { - mBackgroundColor = backgroundColor; - mCircleDrawable.setColorFilter(mBackgroundColor, PorterDuff.Mode.SRC_ATOP); - } - - public void setTabForegroundColor(@ColorInt Integer foregroundColor) { - mForegroundColor = foregroundColor; - if (null != mForegroundColor) { - mIconDrawable.setColorFilter(mForegroundColor, PorterDuff.Mode.SRC_ATOP); - } else { - mIconDrawable.setColorFilter(null); - } - } - - public void setIcon(@Nullable Drawable icon) { - mIconDrawable = icon; - if (null != mForegroundColor && null != mIconDrawable) { - mIconDrawable.setColorFilter(mForegroundColor, PorterDuff.Mode.SRC_ATOP); - } - updateIconBounds(); - - invalidate(); - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - mCircleDrawable.setBounds(getPaddingLeft(), getPaddingTop(), w - getPaddingRight(), h - getPaddingBottom()); - updateIconBounds(); - invalidate(); - } - - private void updateIconBounds() { - if (null != mIconDrawable) { - Rect bounds = new Rect(mCircleDrawable.getBounds()); - bounds.set(bounds.left + mIconInsetLeft, bounds.top + mIconInsetTop, bounds.right - mIconInsetRight, bounds.bottom - mIconInsetBottom); - mIconDrawable.setBounds(bounds); - } - } - - @Override - protected void onDraw(Canvas canvas) { - mCircleDrawable.draw(canvas); - if (null != mIconDrawable) { - mIconDrawable.draw(canvas); - } - } - } -} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/HoverMenuService.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/HoverMenuService.java deleted file mode 100644 index f33a831e..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/HoverMenuService.java +++ /dev/null @@ -1,267 +0,0 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu; - - -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.IBinder; -import android.support.annotation.Nullable; -import android.view.ContextThemeWrapper; -import android.view.View; -import android.view.WindowManager; -import android.widget.Toast; - -import com.stardust.hover.HoverMenuBuilder; -import com.stardust.hover.SimpleHoverMenuTransitionListener; -import com.stardust.hover.WindowHoverMenu; -import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.autojs.AutoJs; -import com.stardust.view.accessibility.NodeInfo; -import com.stardust.scriptdroid.external.floatingwindow.menu.view.FloatingLayoutBoundsView; -import com.stardust.scriptdroid.external.floatingwindow.menu.view.FloatingLayoutHierarchyView; -import com.stardust.theme.ThemeColorManagerCompat; -import com.stardust.util.IntentUtil; -import com.stardust.util.MessageEvent; -import com.stardust.util.MessageIntent; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import ezy.assist.compat.SettingsCompat; -import io.mattcarroll.hover.HoverMenu; -import io.mattcarroll.hover.defaulthovermenu.window.WindowViewController; - -/** - * Created by Stardust on 2017/3/11. - */ - -public class HoverMenuService extends Service { - - - public static class ServiceStateChangedEvent { - ServiceStateChangedEvent(boolean state) { - this.state = state; - } - - public boolean state; - } - - public static final String ACTION_SHOW_AND_EXPAND_MENU = "ACTION_SHOW_AND_EXPAND_MENU"; - public static final String ACTION_SHOW_LAYOUT_HIERARCHY = "ACTION_SHOW_LAYOUT_HIERARCHY"; - public static final String ACTION_SHOW_LAYOUT_BOUNDS = "ACTION_SHOW_LAYOUT_BOUNDS"; - public static final String ACTION_COLLAPSE_MENU = "ACTION_COLLAPSE_MENU"; - public static final String ACTION_MENU_COLLAPSING = "ACTION_MENU_COLLAPSING"; - public static final String ACTION_MENU_EXPANDING = "ACTION_MENU_EXPANDING"; - public static final String ACTION_MENU_EXIT = "ACTION_MENU_EXIT"; - public static final String ACTION_SHOW_NODE_LAYOUT_HIERARCHY = "ACTION_SHOW_NODE_LAYOUT_HIERARCHY"; - public static final String ACTION_SHOW_NODE_LAYOUT_BOUNDS = "ACTION_SHOW_NODE_LAYOUT_BOUNDS"; - - public static final String EXTRA_NODE_INFO = "EXTRA_NODE_INFO"; - - - private static boolean sIsRunning; - private static EventBus eventBus = new EventBus(); - - public static void startService(Context context) { - context.startService(new Intent(context, HoverMenuService.class)); - setIsRunning(true); - } - - public static boolean isServiceRunning() { - return sIsRunning; - } - - private static void setIsRunning(boolean isRunning) { - sIsRunning = isRunning; - eventBus.post(new ServiceStateChangedEvent(sIsRunning)); - } - - public static void postIntent(Intent intent) { - eventBus.post(new MessageIntent(intent)); - } - - public static void postMessageIntent(MessageIntent intent) { - eventBus.post(intent); - } - - - public static EventBus getEventBus() { - return eventBus; - } - - private static final String TAG = "HoverMenuService"; - - private static final String PREF_FILE = "hover_menu"; - private static final String PREF_HOVER_MENU_VISUAL_STATE = "hover_menu_visual_state"; - - private SharedPreferences mPrefs; - - private WindowViewController mWindowViewController; - - private ContextThemeWrapper mThemeWrapper; - private FloatingLayoutHierarchyView mFloatingLayoutHierarchyView; - private FloatingLayoutBoundsView mFloatingLayoutBoundsView; - - private WindowHoverMenu mWindowHoverMenu; - private HoverMenu.OnExitListener mWindowHoverMenuMenuExitListener = new HoverMenu.OnExitListener() { - @Override - public void onExitByUserRequest() { - eventBus.post(new MessageEvent(ACTION_MENU_EXIT)); - savePreferredLocation(); - mWindowHoverMenu.hide(); - stopSelf(); - } - - }; - - @Override - public void onCreate() { - super.onCreate(); - eventBus.register(this); - mPrefs = getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE); - tryInitViews(); - } - - private void tryInitViews() { - try { - initViews(); - } catch (Exception e) { - e.printStackTrace(); - Toast.makeText(this, R.string.text_no_floating_window_permission, Toast.LENGTH_SHORT).show(); - try { - SettingsCompat.manageDrawOverlays(this); - } catch (Exception ex) { - ex.printStackTrace(); - IntentUtil.goToAppDetailSettings(this); - } - } - } - - private void initViews() { - mThemeWrapper = new ContextThemeWrapper(this, R.style.AppTheme); - mFloatingLayoutHierarchyView = new FloatingLayoutHierarchyView(mThemeWrapper); - mFloatingLayoutBoundsView = new FloatingLayoutBoundsView(mThemeWrapper); - initWindowMenu(); - mWindowViewController.addView(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, true, mFloatingLayoutHierarchyView); - mWindowViewController.addView(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, true, mFloatingLayoutBoundsView); - } - - private void initWindowMenu() { - mWindowHoverMenu = (WindowHoverMenu) new HoverMenuBuilder(mThemeWrapper) - .displayWithinWindow() - .useAdapter(new HoverMenuAdapter(this)) - .restoreVisualState(loadPreferredLocation()) - .build(); - mWindowHoverMenu.getHoverMenuView().setContentBackgroundColor(ThemeColorManagerCompat.getColorPrimary()); - mWindowHoverMenu.addOnExitListener(mWindowHoverMenuMenuExitListener); - mWindowViewController = mWindowHoverMenu.getWindowViewController(); - mWindowHoverMenu.setHoverMenuTransitionListener(new SimpleHoverMenuTransitionListener() { - @Override - public void onExpanding() { - eventBus.post(new MessageEvent(ACTION_MENU_EXPANDING)); - captureCurrentWindow(); - } - - @Override - public void onCollapsing() { - AutoJs.getInstance().getLayoutInspector().clearCapture(); - eventBus.post(new MessageEvent(ACTION_MENU_COLLAPSING)); - } - }); - } - - private void captureCurrentWindow() { - AutoJs.getInstance().getLayoutInspector().captureCurrentWindow(); - } - - @Nullable - @Override - public IBinder onBind(Intent intent) { - return null; - } - - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if (mWindowHoverMenu == null) - tryInitViews(); - if (mWindowHoverMenu != null) - mWindowHoverMenu.show(); - return START_STICKY; - } - - @Override - public void onDestroy() { - if (mWindowHoverMenu != null) - mWindowHoverMenu.hide(); - if (eventBus.isRegistered(this)) - eventBus.unregister(this); - setIsRunning(false); - if (mWindowViewController == null) - return; - mWindowViewController.removeView(mFloatingLayoutBoundsView); - mWindowViewController.removeView(mFloatingLayoutHierarchyView); - } - - - private void savePreferredLocation() { - String memento = mWindowHoverMenu.getVisualState(); - mPrefs.edit().putString(PREF_HOVER_MENU_VISUAL_STATE, memento).apply(); - } - - private String loadPreferredLocation() { - return mPrefs.getString(PREF_HOVER_MENU_VISUAL_STATE, null); - } - - @Subscribe - public void handleMessageIntent(MessageIntent intent) { - switch (intent.getAction()) { - case ACTION_SHOW_AND_EXPAND_MENU: - showAndExpandMenu(); - break; - case ACTION_SHOW_LAYOUT_HIERARCHY: - showLayoutHierarchy(); - break; - case ACTION_SHOW_LAYOUT_BOUNDS: - showLayoutBounds(); - break; - case ACTION_COLLAPSE_MENU: - mWindowHoverMenu.collapseMenu(); - break; - case ACTION_SHOW_NODE_LAYOUT_BOUNDS: - mFloatingLayoutHierarchyView.setVisibility(View.GONE); - showLayoutBounds(); - mFloatingLayoutBoundsView.setSelectedNode((NodeInfo) intent.getObjectExtra(EXTRA_NODE_INFO)); - break; - case ACTION_SHOW_NODE_LAYOUT_HIERARCHY: - mFloatingLayoutBoundsView.setVisibility(View.GONE); - showLayoutHierarchy(); - mFloatingLayoutHierarchyView.setSelectedNode((NodeInfo) intent.getObjectExtra(EXTRA_NODE_INFO)); - break; - } - } - - private void showLayoutBounds() { - mFloatingLayoutBoundsView.setRootNode(AutoJs.getInstance().getLayoutInspector().getCapture()); - mWindowHoverMenu.getHoverMenuView().setVisibility(View.GONE); - showView(mFloatingLayoutBoundsView); - } - - public void showLayoutHierarchy() { - mFloatingLayoutHierarchyView.setRootNode(AutoJs.getInstance().getLayoutInspector().getCapture()); - mWindowHoverMenu.getHoverMenuView().setVisibility(View.GONE); - showView(mFloatingLayoutHierarchyView); - } - - public void showAndExpandMenu() { - showView(mWindowHoverMenu.getHoverMenuView()); - } - - - private void showView(View view) { - view.setVisibility(View.VISIBLE); - mWindowViewController.makeTouchable(view); - } - -} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/MainMenuNavigatorContent.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/MainMenuNavigatorContent.java deleted file mode 100644 index bcc261ab..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/MainMenuNavigatorContent.java +++ /dev/null @@ -1,146 +0,0 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.content; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.Intent; -import android.support.annotation.NonNull; -import android.view.View; -import android.widget.TextView; -import android.widget.Toast; - -import com.stardust.scriptdroid.App; -import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.autojs.AutoJs; -import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService; -import com.stardust.scriptdroid.tool.AccessibilityServiceTool; -import com.stardust.scriptdroid.ui.main.MainActivity_; -import com.stardust.util.ClipboardUtil; -import com.stardust.util.MessageEvent; -import com.stardust.view.accessibility.AccessibilityService; -import com.stardust.view.accessibility.LayoutInspector; - -import org.greenrobot.eventbus.Subscribe; - -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; -import io.mattcarroll.hover.Navigator; -import io.mattcarroll.hover.NavigatorContent; - -/** - * Created by Stardust on 2017/3/12. - */ - -public class MainMenuNavigatorContent implements NavigatorContent { - - private View mView; - @BindView(R.id.current_package) - TextView mCurrentPackageTextView; - @BindView(R.id.current_activity) - TextView mCurrentActivityTextView; - private String mCurrentPackage, mCurrentActivity; - private Context mContext; - - public MainMenuNavigatorContent(Context context) { - mContext = context; - mView = View.inflate(context, R.layout.floating_window_main_menu, null); - ButterKnife.bind(this, mView); - HoverMenuService.getEventBus().register(this); - } - - @OnClick(R.id.layout_hierarchy) - void showLayoutHierarchy() { - if (!ensureCapture()) { - return; - } - HoverMenuService.postIntent(new Intent(HoverMenuService.ACTION_SHOW_LAYOUT_HIERARCHY)); - } - - private boolean ensureCapture() { - LayoutInspector inspector = AutoJs.getInstance().getLayoutInspector(); - if (inspector.isDumping()) { - Toast.makeText(mView.getContext(), R.string.text_layout_inspector_is_dumping, Toast.LENGTH_SHORT).show(); - return false; - } - if (AccessibilityService.getInstance() == null) { - Toast.makeText(mView.getContext(), R.string.text_no_accessibility_permission_to_capture, Toast.LENGTH_SHORT).show(); - return false; - } - if (inspector.getCapture() == null) { - Toast.makeText(mView.getContext(), R.string.text_inspect_failed, Toast.LENGTH_SHORT).show(); - return false; - } - return true; - } - - @OnClick(R.id.layout_bounds) - void showLayoutBounds() { - if (!ensureCapture()) { - return; - } - HoverMenuService.postIntent(new Intent(HoverMenuService.ACTION_SHOW_LAYOUT_BOUNDS)); - } - - @OnClick(R.id.stop_all_running_scripts) - void stopAllRunningScripts() { - AutoJs.getInstance().getScriptEngineService().stopAllAndToast(); - } - - @OnClick(R.id.open_launcher) - void openMainActivity() { - App.getApp().startActivity(new Intent(App.getApp(), MainActivity_.class) - .addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY | Intent.FLAG_ACTIVITY_NEW_TASK)); - HoverMenuService.postIntent(new Intent(HoverMenuService.ACTION_COLLAPSE_MENU)); - } - - @OnClick(R.id.open_accessibility_settings) - void openAccessibilitySettings() { - AccessibilityServiceTool.enableAccessibilityService(); - HoverMenuService.postIntent(new Intent(HoverMenuService.ACTION_COLLAPSE_MENU)); - } - - @NonNull - @Override - public View getView() { - return mView; - } - - @Override - public void onShown(@NonNull Navigator navigator) { - } - - @SuppressLint("SetTextI18n") - private void syncCurrentInfo() { - mCurrentPackage = AutoJs.getInstance().getInfoProvider().getLatestPackage(); - mCurrentActivity = AutoJs.getInstance().getInfoProvider().getLatestActivity(); - mCurrentActivityTextView.setText(mContext.getString(R.string.text_current_activity) + mCurrentActivity); - mCurrentPackageTextView.setText(mContext.getString(R.string.text_current_package) + mCurrentPackage); - } - - @OnClick(R.id.current_activity) - void copyCurrentActivity() { - ClipboardUtil.setClip(mContext, mCurrentActivity); - Toast.makeText(mContext, R.string.text_copied, Toast.LENGTH_SHORT).show(); - } - - @OnClick(R.id.current_package) - void copyCurrentPackage() { - ClipboardUtil.setClip(mContext, mCurrentPackage); - Toast.makeText(mContext, R.string.text_copied, Toast.LENGTH_SHORT).show(); - } - - @Override - public void onHidden() { - - } - - @Subscribe - public void onMessageEvent(MessageEvent event) { - if (event.message.equals(HoverMenuService.ACTION_MENU_EXPANDING)) { - syncCurrentInfo(); - } else if (event.message.equals(HoverMenuService.ACTION_MENU_EXIT)) { - HoverMenuService.getEventBus().unregister(this); - } - } - -} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java deleted file mode 100644 index b2934cce..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java +++ /dev/null @@ -1,205 +0,0 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.content; - -import android.content.Context; -import android.content.Intent; -import android.support.annotation.NonNull; -import android.support.v7.widget.SwitchCompat; -import android.view.ContextThemeWrapper; -import android.view.KeyEvent; -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; -import android.widget.Toast; - -import com.afollestad.materialdialogs.DialogAction; -import com.afollestad.materialdialogs.MaterialDialog; -import com.stardust.app.DialogUtils; -import com.stardust.autojs.core.record.Recorder; -import com.stardust.autojs.core.record.accessibility.AccessibilityActionRecorder; -import com.stardust.autojs.core.inputevent.InputEventObserver; -import com.stardust.autojs.core.inputevent.ShellKeyObserver; -import com.stardust.autojs.core.record.inputevent.TouchRecorder; -import com.stardust.scriptdroid.App; -import com.stardust.scriptdroid.Pref; -import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.accessibility.AccessibilityEventHelper; -import com.stardust.scriptdroid.autojs.AutoJs; -import com.stardust.scriptdroid.autojs.key.GlobalKeyObserver; -import com.stardust.scriptdroid.autojs.record.GlobalRecorder; -import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService; -import com.stardust.scriptdroid.ui.common.ScriptOperations; -import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder; -import com.stardust.util.ClipboardUtil; -import com.stardust.util.MessageEvent; -import com.stardust.view.accessibility.AccessibilityService; -import com.stardust.view.accessibility.OnKeyListener; -import com.stardust.widget.PrefSwitch; -import com.stardust.widget.ViewSwitcher; - -import org.greenrobot.eventbus.Subscribe; - -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; -import io.mattcarroll.hover.Navigator; -import io.mattcarroll.hover.NavigatorContent; - - -/** - * Created by Stardust on 2017/3/12. - */ - -public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStateChangedListener, GlobalKeyObserver.OnVolumeDownListener { - - private View mView; - @BindView(R.id.sw_recorded_by_root) - PrefSwitch mRecordedByRootSwitch; - - @BindView(R.id.sw_record_toast) - PrefSwitch mRecordToastSwitch; - - @BindView(R.id.img_pause_or_resume) - ImageView mPauseOrResumeImage; - - @BindView(R.id.text_pause_or_resume) - TextView mPauseOrResumeText; - - @BindView(R.id.view_switcher) - ViewSwitcher mViewSwitcher; - - private GlobalRecorder mRecorder; - private Context mContext; - private long mLastVolumeDownEventTime; - - public RecordNavigatorContent(Context context) { - mContext = new ContextThemeWrapper(context, R.style.AppTheme); - mView = View.inflate(mContext, R.layout.floating_window_record, null); - ButterKnife.bind(this, mView); - HoverMenuService.getEventBus().register(this); - mRecorder = GlobalRecorder.getSingleton(context); - mRecorder.addOnStateChangedListener(this); - setState(mRecorder.getState()); - GlobalKeyObserver.getSingleton().addVolumeDownListener(this); - } - - public void onVolumeDown() { - if (!Pref.isRecordVolumeControlEnable()) { - return; - } - if (System.currentTimeMillis() - mLastVolumeDownEventTime < 300) { - return; - } - mLastVolumeDownEventTime = System.currentTimeMillis(); - int state = mRecorder.getState(); - if (state == Recorder.STATE_RECORDING || state == Recorder.STATE_PAUSED) { - mRecorder.stop(); - } else { - mRecorder.start(); - } - } - - - @NonNull - @Override - public View getView() { - return mView; - } - - @Override - public void onShown(@NonNull Navigator navigator) { - } - - @Override - public void onHidden() { - - } - - @OnClick(R.id.sw_root_container) - void toggleRecordedByRootSwitch() { - mRecordedByRootSwitch.toggle(); - } - - @OnClick(R.id.sw_record_toast_container) - void toggleRecordToastSwitch() { - mRecordToastSwitch.toggle(); - } - - @OnClick(R.id.start_record) - void startRecord() { - mRecorder.start(); - HoverMenuService.postIntent(new Intent(HoverMenuService.ACTION_COLLAPSE_MENU)); - } - - @OnClick(R.id.discard_record) - void discardRecord() { - mRecorder.discard(); - } - - - @OnClick(R.id.pause_or_resume_record) - void pauseOrResumeRecord() { - if (mRecorder.getState() == Recorder.STATE_PAUSED) { - mRecorder.resume(); - } else { - mRecorder.pause(); - } - HoverMenuService.postIntent(new Intent(HoverMenuService.ACTION_COLLAPSE_MENU)); - } - - private void setState(int state) { - if (state == Recorder.STATE_NOT_START || state == Recorder.STATE_STOPPED) { - mViewSwitcher.showFirst(); - } else { - mViewSwitcher.showSecond(); - } - mPauseOrResumeImage.setImageResource(state == Recorder.STATE_RECORDING ? R.drawable.ic_pause_white_24dp : - R.drawable.ic_play_arrow_white_48dp); - mPauseOrResumeText.setText( - state == Recorder.STATE_RECORDING ? R.string.text_pause_record : R.string.text_resume_record); - } - - @OnClick(R.id.stop_record) - void stopRecord() { - mRecorder.stop(); - setState(Recorder.STATE_STOPPED); - HoverMenuService.postIntent(new Intent(HoverMenuService.ACTION_COLLAPSE_MENU)); - } - - - @Subscribe - public void onMessageEvent(MessageEvent event) { - if (event.message.equals(HoverMenuService.ACTION_MENU_EXPANDING)) { - if (mRecorder.getState() == Recorder.STATE_RECORDING) - mRecorder.pause(); - } else if (event.message.equals(HoverMenuService.ACTION_MENU_EXIT)) { - onMenuExit(); - } - } - - public void onMenuExit() { - HoverMenuService.getEventBus().unregister(this); - mRecorder.removeOnStateChangedListener(this); - } - - @Override - public void onStart() { - setState(Recorder.STATE_RECORDING); - } - - @Override - public void onStop() { - setState(Recorder.STATE_STOPPED); - } - - @Override - public void onPause() { - setState(Recorder.STATE_PAUSED); - } - - @Override - public void onResume() { - setState(Recorder.STATE_RECORDING); - } - - -} \ No newline at end of file diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/ScriptListNavigatorContent.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/ScriptListNavigatorContent.java deleted file mode 100644 index dcc4c914..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/ScriptListNavigatorContent.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.content; - -import android.content.Context; -import android.content.Intent; -import android.support.annotation.NonNull; -import android.view.ContextThemeWrapper; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.widget.ImageView; -import android.workground.WrapContentLinearLayoutManager; - -import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService; -import com.stardust.scriptdroid.script.ScriptFile; -import com.stardust.scriptdroid.script.Scripts; -import com.stardust.scriptdroid.script.StorageFileProvider; -import com.stardust.scriptdroid.ui.common.ScriptLoopDialog; -import com.stardust.scriptdroid.ui.edit.EditActivity; -import com.stardust.scriptdroid.ui.main.scripts.ScriptListRecyclerView; -import com.stardust.scriptdroid.ui.main.scripts.ScriptListWithProgressBarView; -import com.stardust.widget.ViewHolderSupplier; - -import io.mattcarroll.hover.Navigator; -import io.mattcarroll.hover.NavigatorContent; - -/** - * Created by Stardust on 2017/3/12. - */ - -public class ScriptListNavigatorContent implements NavigatorContent { - - private ViewHolderSupplier mViewHolderSupplier = new ViewHolderSupplier() { - @Override - public ScriptListRecyclerView.ViewHolder createViewHolder(ViewGroup parent, int viewType) { - switch (viewType) { - case ScriptListRecyclerView.VIEW_TYPE_FILE: - return new FileViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.floating_script_list_recycler_view_file, parent, false)); - case ScriptListRecyclerView.VIEW_TYPE_DIRECTORY: - return new DirectoryViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.floating_script_list_recycler_view_directory, parent, false)); - - } - return null; - } - }; - private ScriptListRecyclerView mFloatingScriptFileListView; - private ScriptListWithProgressBarView mScriptListWithProgressBarView; - - public ScriptListNavigatorContent(Context context) { - mScriptListWithProgressBarView = new ScriptListWithProgressBarView(new ContextThemeWrapper(context, R.style.AppTheme)); - mFloatingScriptFileListView = mScriptListWithProgressBarView.getScriptAndFolderListRecyclerView(); - mFloatingScriptFileListView.setViewHolderSupplier(mViewHolderSupplier); - mFloatingScriptFileListView.setLayoutManager(new WrapContentLinearLayoutManager(context)); - mFloatingScriptFileListView.setStorageFileProvider(StorageFileProvider.getDefault()); - mFloatingScriptFileListView.setOnItemClickListener(new ScriptListRecyclerView.OnScriptFileClickListener() { - - @Override - public void onClick(ScriptFile file, int position) { - Scripts.run(file); - HoverMenuService.postIntent(new Intent(HoverMenuService.ACTION_COLLAPSE_MENU)); - } - - }); - } - - @NonNull - @Override - public View getView() { - return mScriptListWithProgressBarView; - } - - @Override - public void onShown(@NonNull Navigator navigator) { - - } - - @Override - public void onHidden() { - - } - - private class DirectoryViewHolder extends ScriptListRecyclerView.ViewHolder { - - DirectoryViewHolder(View itemView) { - super(itemView); - itemView.setOnClickListener(mFloatingScriptFileListView.getOnItemClickListenerProxy()); - itemView.setOnLongClickListener(mFloatingScriptFileListView.getOnItemLongClickListenerProxy()); - } - } - - private class FileViewHolder extends DirectoryViewHolder { - - private ImageView mIcon; - private View mEdit; - - FileViewHolder(final View itemView) { - super(itemView); - mIcon = (ImageView) itemView.findViewById(R.id.icon); - mEdit = itemView.findViewById(R.id.edit); - mEdit.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - EditActivity.editFile(v.getContext(), getScriptFile()); - HoverMenuService.postIntent(new Intent(HoverMenuService.ACTION_COLLAPSE_MENU)); - } - }); - itemView.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - new ScriptLoopDialog(v.getContext(), getScriptFile()) - .windowType(WindowManager.LayoutParams.TYPE_PHONE) - .show(); - HoverMenuService.postIntent(new Intent(HoverMenuService.ACTION_COLLAPSE_MENU)); - return true; - } - }); - } - - @Override - public void bind(ScriptFile file) { - super.bind(file); - mIcon.setImageResource(file.getType() == ScriptFile.TYPE_AUTO ? R.drawable.record_icon_18 - : R.drawable.ic_node_js_black); - mEdit.setVisibility(file.getType() == ScriptFile.TYPE_JAVA_SCRIPT ? View.VISIBLE : View.INVISIBLE); - } - - private ScriptFile getScriptFile() { - return mFloatingScriptFileListView.getAdapter().getScriptFileAt(getAdapterPosition()); - - } - - } - - -} \ No newline at end of file diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutBoundsView.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutBoundsView.java deleted file mode 100644 index f6c6ba1a..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutBoundsView.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.view; - -import android.content.Context; -import android.content.Intent; -import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; - -import com.afollestad.materialdialogs.MaterialDialog; -import com.afollestad.materialdialogs.Theme; -import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService; -import com.stardust.view.accessibility.NodeInfo; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.LayoutBoundsView; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.NodeInfoView; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.OnNodeInfoSelectListener; -import com.stardust.util.MessageIntent; -import com.stardust.widget.BubblePopupMenu; - -import java.util.Arrays; - -/** - * Created by Stardust on 2017/3/12. - */ - -public class FloatingLayoutBoundsView extends LayoutBoundsView { - - private MaterialDialog mNodeInfoDialog; - private BubblePopupMenu mBubblePopMenu; - private NodeInfoView mNodeInfoView; - private NodeInfo mSelectedNode; - - public FloatingLayoutBoundsView(Context context) { - super(context); - init(); - } - - private void init() { - setOnNodeInfoSelectListener(new OnNodeInfoSelectListener() { - @Override - public void onNodeSelect(NodeInfo info) { - mSelectedNode = info; - ensureOperationPopMenu(); - if (mBubblePopMenu.getContentView().getMeasuredWidth() <= 0) - mBubblePopMenu.preMeasure(); - mBubblePopMenu.showAsDropDownAtLocation(FloatingLayoutBoundsView.this, info.getBoundsInScreen().height(), info.getBoundsInScreen().centerX() - mBubblePopMenu.getContentView().getMeasuredWidth() / 2, info.getBoundsInScreen().bottom - getStatusBarHeight()); - } - }); - setVisibility(GONE); - getBoundsPaint().setStrokeWidth(2f); - } - - - private void showNodeInfo() { - ensureDialog(); - mNodeInfoView.setNodeInfo(mSelectedNode); - mNodeInfoDialog.show(); - } - - private void ensureOperationPopMenu() { - if (mBubblePopMenu != null) - return; - mBubblePopMenu = new BubblePopupMenu(getContext(), Arrays.asList( - getResources().getString(R.string.text_show_widget_infomation), - getResources().getString(R.string.text_show_layout_hierarchy))); - mBubblePopMenu.setOnItemClickListener(new BubblePopupMenu.OnItemClickListener() { - @Override - public void onClick(View view, int position) { - mBubblePopMenu.dismiss(); - if (position == 0) { - showNodeInfo(); - } else { - HoverMenuService.postMessageIntent(new MessageIntent(HoverMenuService.ACTION_SHOW_NODE_LAYOUT_HIERARCHY) - .putExtra(HoverMenuService.EXTRA_NODE_INFO, mSelectedNode)); - } - } - }); - mBubblePopMenu.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); - mBubblePopMenu.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); - } - - private void ensureDialog() { - if (mNodeInfoDialog == null) { - mNodeInfoView = new NodeInfoView(getContext()); - mNodeInfoDialog = new MaterialDialog.Builder(getContext()) - .customView(mNodeInfoView, false) - .theme(Theme.LIGHT) - .build(); - mNodeInfoDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE); - } - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { - HoverMenuService.postIntent(new Intent(HoverMenuService.ACTION_SHOW_AND_EXPAND_MENU)); - setVisibility(GONE); - return true; - } - return super.dispatchKeyEvent(event); - } - - -} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutHierarchyView.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutHierarchyView.java deleted file mode 100644 index 1ad55694..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutHierarchyView.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.view; - -import android.content.Context; -import android.content.Intent; -import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; - -import com.afollestad.materialdialogs.MaterialDialog; -import com.afollestad.materialdialogs.Theme; -import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService; -import com.stardust.view.accessibility.NodeInfo; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.LayoutHierarchyView; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view.NodeInfoView; -import com.stardust.util.MessageIntent; -import com.stardust.widget.BubblePopupMenu; - -import java.util.Arrays; - -/** - * Created by Stardust on 2017/3/12. - */ - -public class FloatingLayoutHierarchyView extends LayoutHierarchyView { - - private static final String TAG = "FloatingHierarchyView"; - private static final int COLOR_SHADOW = 0xddffffff; - - private MaterialDialog mNodeInfoDialog; - private BubblePopupMenu mBubblePopMenu; - private NodeInfoView mNodeInfoView; - private NodeInfo mSelectedNodeInfo; - - public FloatingLayoutHierarchyView(Context context) { - super(context); - init(); - } - - private void init() { - setBackgroundColor(COLOR_SHADOW); - setVisibility(GONE); - setShowClickedNodeBounds(true); - getBoundsPaint().setStrokeWidth(3); - getBoundsPaint().setColor(0xFFD32F2F); - setOnItemLongClickListener(new OnItemLongClickListener() { - @Override - public void onItemLongClick(View view, NodeInfo nodeInfo) { - mSelectedNodeInfo = nodeInfo; - ensureOperationPopMenu(); - if (mBubblePopMenu.getContentView().getMeasuredWidth() <= 0) - mBubblePopMenu.preMeasure(); - mBubblePopMenu.showAsDropDown(view, view.getWidth() / 2 - mBubblePopMenu.getContentView().getMeasuredWidth() / 2, 0); - } - }); - } - - private void ensureOperationPopMenu() { - if (mBubblePopMenu != null) - return; - mBubblePopMenu = new BubblePopupMenu(getContext(), Arrays.asList( - getResources().getString(R.string.text_show_widget_infomation), - getResources().getString(R.string.text_show_layout_bounds))); - mBubblePopMenu.setOnItemClickListener(new BubblePopupMenu.OnItemClickListener() { - @Override - public void onClick(View view, int position) { - mBubblePopMenu.dismiss(); - if (position == 0) { - showNodeInfo(); - } else { - HoverMenuService.postMessageIntent(new MessageIntent(HoverMenuService.ACTION_SHOW_NODE_LAYOUT_BOUNDS) - .putExtra(HoverMenuService.EXTRA_NODE_INFO, mSelectedNodeInfo)); - } - } - }); - mBubblePopMenu.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); - mBubblePopMenu.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); - } - - - void showNodeInfo() { - ensureNodeInfoDialog(); - mNodeInfoView.setNodeInfo(mSelectedNodeInfo); - mNodeInfoDialog.show(); - } - - private void ensureNodeInfoDialog() { - if (mNodeInfoDialog == null) { - mNodeInfoView = new NodeInfoView(getContext()); - mNodeInfoDialog = new MaterialDialog.Builder(getContext()) - .customView(mNodeInfoView, false) - .theme(Theme.LIGHT) - .build(); - if (mNodeInfoDialog.getWindow() != null) - mNodeInfoDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE); - } - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { - HoverMenuService.postIntent(new Intent(HoverMenuService.ACTION_SHOW_AND_EXPAND_MENU)); - setVisibility(GONE); - return true; - } - return super.dispatchKeyEvent(event); - } - - -} diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/floating/CircularMenu.java b/app/src/main/java/com/stardust/scriptdroid/ui/floating/CircularMenu.java new file mode 100644 index 00000000..c177dea8 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/floating/CircularMenu.java @@ -0,0 +1,161 @@ +package com.stardust.scriptdroid.ui.floating; + +import android.content.Context; +import android.view.ContextThemeWrapper; +import android.view.View; +import android.widget.ImageView; +import android.widget.Toast; + +import com.stardust.enhancedfloaty.FloatyService; +import com.stardust.floatingcircularactionmenu.CircularActionMenu; +import com.stardust.floatingcircularactionmenu.CircularActionMenuFloatingWindow; +import com.stardust.floatingcircularactionmenu.CircularActionMenuFloaty; +import com.stardust.scriptdroid.R; +import com.stardust.scriptdroid.accessibility.AccessibilityService; +import com.stardust.scriptdroid.autojs.AutoJs; +import com.stardust.scriptdroid.ui.floating.layoutinspector.LayoutBoundsFloatyWindow; +import com.stardust.scriptdroid.ui.floating.layoutinspector.LayoutHierarchyFloatyWindow; +import com.stardust.scriptdroid.ui.floating.layoutinspector.LayoutHierarchyView; +import com.stardust.view.accessibility.LayoutInspector; + +import org.androidannotations.annotations.Click; + +import butterknife.ButterKnife; +import butterknife.OnClick; + +/** + * Created by Stardust on 2017/10/18. + */ + +public class CircularMenu { + + + private static final int STATE_NORMAL = 0; + private static final int STATE_RECORDING = 1; + + CircularActionMenuFloatingWindow mWindow; + private int mState; + private ImageView mActionViewIcon; + private Context mContext; + + + public CircularMenu(Context context) { + mContext = context; + initFloaty(); + setupListeners(); + FloatyService.addWindow(mWindow); + } + + private void setupListeners() { + mWindow.setOnActionViewClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mState == STATE_RECORDING) { + stopRecord(); + } else if (mWindow.isExpanded()) { + mWindow.collapse(); + } else { + AutoJs.getInstance().getLayoutInspector().captureCurrentWindow(); + mWindow.expand(); + } + } + + + }); + } + + private void initFloaty() { + mWindow = new CircularActionMenuFloatingWindow(new CircularActionMenuFloaty() { + + @Override + public View inflateActionView(FloatyService service, CircularActionMenuFloatingWindow window) { + View actionView = View.inflate(service, R.layout.circular_action_view, null); + mActionViewIcon = (ImageView) actionView.findViewById(R.id.icon); + return actionView; + } + + @Override + public CircularActionMenu inflateMenuItems(FloatyService service, CircularActionMenuFloatingWindow window) { + CircularActionMenu menu = (CircularActionMenu) View.inflate(new ContextThemeWrapper(service, R.style.AppTheme), R.layout.circular_action_menu, null); + ButterKnife.bind(CircularMenu.this, menu); + return menu; + } + }); + + } + + + @OnClick(R.id.script_list) + void showScriptList() { + mWindow.collapse(); + } + + @OnClick(R.id.record) + void startRecord() { + mWindow.collapse(); + mState = STATE_RECORDING; + mActionViewIcon.setImageResource(R.drawable.ic_ali_record); + mActionViewIcon.setBackgroundResource(R.drawable.circle_red); + mActionViewIcon.setPadding(28, 28, 28, 28); + } + + private void stopRecord() { + mWindow.collapse(); + mState = STATE_NORMAL; + mActionViewIcon.setImageResource(R.drawable.autojs_logo); + mActionViewIcon.setBackground(null); + mActionViewIcon.setPadding(0, 0, 0, 0); + } + + @OnClick(R.id.layout_bounds) + void showLayoutBounds() { + mWindow.collapse(); + if (!ensureCapture()) { + return; + } + LayoutBoundsFloatyWindow window = new LayoutBoundsFloatyWindow( + AutoJs.getInstance().getLayoutInspector().getCapture() + ); + FloatyService.addWindow(window); + } + + @OnClick(R.id.layout_hierarchy) + void showLayoutHierarchy() { + mWindow.collapse(); + if (!ensureCapture()) { + return; + } + LayoutHierarchyFloatyWindow window = new LayoutHierarchyFloatyWindow( + AutoJs.getInstance().getLayoutInspector().getCapture() + ); + FloatyService.addWindow(window); + } + + @OnClick(R.id.settings) + void settings() { + mWindow.collapse(); + + } + + private boolean ensureCapture() { + LayoutInspector inspector = AutoJs.getInstance().getLayoutInspector(); + if (inspector.isDumping()) { + Toast.makeText(mContext, R.string.text_layout_inspector_is_dumping, Toast.LENGTH_SHORT).show(); + return false; + } + if (AccessibilityService.getInstance() == null) { + Toast.makeText(mContext, R.string.text_no_accessibility_permission_to_capture, Toast.LENGTH_SHORT).show(); + return false; + } + if (inspector.getCapture() == null) { + Toast.makeText(mContext, R.string.text_inspect_failed, Toast.LENGTH_SHORT).show(); + return false; + } + return true; + } + + + public void close() { + mWindow.close(); + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/floating/FullScreenFloatyWindow.java b/app/src/main/java/com/stardust/scriptdroid/ui/floating/FullScreenFloatyWindow.java new file mode 100644 index 00000000..5c8d62d1 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/floating/FullScreenFloatyWindow.java @@ -0,0 +1,45 @@ +package com.stardust.scriptdroid.ui.floating; + +import android.graphics.PixelFormat; +import android.view.View; +import android.view.WindowManager; + +import com.stardust.enhancedfloaty.FloatyService; +import com.stardust.enhancedfloaty.FloatyWindow; + +/** + * Created by Stardust on 2017/10/18. + */ + +public abstract class FullScreenFloatyWindow implements FloatyWindow { + + private WindowManager mWindowManager; + private WindowManager.LayoutParams mLayoutParams; + private View mView; + + @Override + public void onCreate(FloatyService floatyService, WindowManager windowManager) { + mWindowManager = windowManager; + mView = inflateView(floatyService); + mLayoutParams = new WindowManager.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.TYPE_PHONE, + WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, + PixelFormat.TRANSLUCENT); + mWindowManager.addView(mView, mLayoutParams); + } + + protected abstract View inflateView(FloatyService service); + + @Override + public void onServiceDestroy(FloatyService floatyService) { + close(); + } + + @Override + public void close() { + mWindowManager.removeView(mView); + FloatyService.removeWindow(this); + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutBoundsFloatyWindow.java b/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutBoundsFloatyWindow.java new file mode 100644 index 00000000..5316ee63 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutBoundsFloatyWindow.java @@ -0,0 +1,121 @@ +package com.stardust.scriptdroid.ui.floating.layoutinspector; + +import android.content.Context; +import android.view.ContextThemeWrapper; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.afollestad.materialdialogs.Theme; +import com.stardust.enhancedfloaty.FloatyService; +import com.stardust.scriptdroid.R; +import com.stardust.scriptdroid.ui.floating.FullScreenFloatyWindow; +import com.stardust.view.accessibility.NodeInfo; +import com.stardust.widget.BubblePopupMenu; + +import java.util.Arrays; + +/** + * Created by Stardust on 2017/3/12. + */ + +public class LayoutBoundsFloatyWindow extends FullScreenFloatyWindow { + + private LayoutBoundsView mLayoutBoundsView; + private MaterialDialog mNodeInfoDialog; + private BubblePopupMenu mBubblePopMenu; + private NodeInfoView mNodeInfoView; + private NodeInfo mSelectedNode; + private Context mContext; + private NodeInfo mRootNode; + + public LayoutBoundsFloatyWindow(NodeInfo rootNode) { + mRootNode = rootNode; + } + + @Override + protected View inflateView(FloatyService service) { + mContext = new ContextThemeWrapper(service, R.style.AppTheme); + mLayoutBoundsView = new LayoutBoundsView(mContext) { + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { + close(); + return true; + } + return super.dispatchKeyEvent(event); + } + }; + setupView(); + return mLayoutBoundsView; + } + + private void setupView() { + mLayoutBoundsView.setOnNodeInfoSelectListener(new OnNodeInfoSelectListener() { + @Override + public void onNodeSelect(NodeInfo info) { + mSelectedNode = info; + ensureOperationPopMenu(); + if (mBubblePopMenu.getContentView().getMeasuredWidth() <= 0) + mBubblePopMenu.preMeasure(); + mBubblePopMenu.showAsDropDownAtLocation(mLayoutBoundsView, info.getBoundsInScreen().height(), info.getBoundsInScreen().centerX() - mBubblePopMenu.getContentView().getMeasuredWidth() / 2, info.getBoundsInScreen().bottom - mLayoutBoundsView.getStatusBarHeight()); + } + }); + mLayoutBoundsView.getBoundsPaint().setStrokeWidth(2f); + mLayoutBoundsView.setRootNode(mRootNode); + if (mSelectedNode != null) + mLayoutBoundsView.setSelectedNode(mSelectedNode); + } + + + private void showNodeInfo() { + ensureDialog(); + mNodeInfoView.setNodeInfo(mSelectedNode); + mNodeInfoDialog.show(); + } + + private void ensureOperationPopMenu() { + if (mBubblePopMenu != null) + return; + mBubblePopMenu = new BubblePopupMenu(mContext, Arrays.asList( + mContext.getString(R.string.text_show_widget_infomation), + mContext.getString(R.string.text_show_layout_hierarchy))); + mBubblePopMenu.setOnItemClickListener(new BubblePopupMenu.OnItemClickListener() { + @Override + public void onClick(View view, int position) { + mBubblePopMenu.dismiss(); + if (position == 0) { + showNodeInfo(); + } else { + showLayoutHierarchy(); + } + } + }); + mBubblePopMenu.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); + mBubblePopMenu.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); + } + + private void showLayoutHierarchy() { + close(); + LayoutHierarchyFloatyWindow window = new LayoutHierarchyFloatyWindow(mRootNode); + window.setSelectedNode(mSelectedNode); + FloatyService.addWindow(window); + } + + private void ensureDialog() { + if (mNodeInfoDialog == null) { + mNodeInfoView = new NodeInfoView(mContext); + mNodeInfoDialog = new MaterialDialog.Builder(mContext) + .customView(mNodeInfoView, false) + .theme(Theme.LIGHT) + .build(); + mNodeInfoDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE); + } + } + + public void setSelectedNode(NodeInfo selectedNode) { + mSelectedNode = selectedNode; + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutBoundsView.java b/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutBoundsView.java similarity index 98% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutBoundsView.java rename to app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutBoundsView.java index 95750881..5eea1349 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutBoundsView.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutBoundsView.java @@ -1,4 +1,4 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view; +package com.stardust.scriptdroid.ui.floating.layoutinspector; import android.content.Context; import android.graphics.Canvas; diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutHierarchyFloatyWindow.java b/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutHierarchyFloatyWindow.java new file mode 100644 index 00000000..aba7b08f --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutHierarchyFloatyWindow.java @@ -0,0 +1,132 @@ +package com.stardust.scriptdroid.ui.floating.layoutinspector; + +import android.content.Context; +import android.view.ContextThemeWrapper; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.afollestad.materialdialogs.Theme; +import com.stardust.enhancedfloaty.FloatyService; +import com.stardust.scriptdroid.R; +import com.stardust.scriptdroid.autojs.AutoJs; +import com.stardust.scriptdroid.ui.floating.FullScreenFloatyWindow; +import com.stardust.view.accessibility.NodeInfo; +import com.stardust.widget.BubblePopupMenu; + +import java.util.Arrays; + +/** + * Created by Stardust on 2017/3/12. + */ + +public class LayoutHierarchyFloatyWindow extends FullScreenFloatyWindow { + + private static final String TAG = "FloatingHierarchyView"; + private static final int COLOR_SHADOW = 0xddffffff; + + private LayoutHierarchyView mLayoutHierarchyView; + private MaterialDialog mNodeInfoDialog; + private BubblePopupMenu mBubblePopMenu; + private NodeInfoView mNodeInfoView; + private NodeInfo mSelectedNodeInfo; + private Context mContext; + private NodeInfo mRootNode; + private NodeInfo mSelectedNode; + + public LayoutHierarchyFloatyWindow(NodeInfo rootNode) { + mRootNode = rootNode; + } + + + @Override + protected View inflateView(FloatyService service) { + mContext = new ContextThemeWrapper(service, R.style.AppTheme); + mLayoutHierarchyView = new LayoutHierarchyView(mContext) { + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { + close(); + return true; + } + return super.dispatchKeyEvent(event); + } + }; + setupView(); + return mLayoutHierarchyView; + } + + private void setupView() { + mLayoutHierarchyView.setBackgroundColor(COLOR_SHADOW); + mLayoutHierarchyView.setShowClickedNodeBounds(true); + mLayoutHierarchyView.getBoundsPaint().setStrokeWidth(3); + mLayoutHierarchyView.getBoundsPaint().setColor(0xFFD32F2F); + mLayoutHierarchyView.setOnItemLongClickListener(new LayoutHierarchyView.OnItemLongClickListener() { + @Override + public void onItemLongClick(View view, NodeInfo nodeInfo) { + mSelectedNodeInfo = nodeInfo; + ensureOperationPopMenu(); + if (mBubblePopMenu.getContentView().getMeasuredWidth() <= 0) + mBubblePopMenu.preMeasure(); + mBubblePopMenu.showAsDropDown(view, view.getWidth() / 2 - mBubblePopMenu.getContentView().getMeasuredWidth() / 2, 0); + } + }); + mLayoutHierarchyView.setRootNode(mRootNode); + if (mSelectedNode != null) + mLayoutHierarchyView.setSelectedNode(mSelectedNode); + } + + private void ensureOperationPopMenu() { + if (mBubblePopMenu != null) + return; + mBubblePopMenu = new BubblePopupMenu(mContext, Arrays.asList( + mContext.getString(R.string.text_show_widget_infomation), + mContext.getString(R.string.text_show_layout_bounds))); + mBubblePopMenu.setOnItemClickListener(new BubblePopupMenu.OnItemClickListener() { + @Override + public void onClick(View view, int position) { + mBubblePopMenu.dismiss(); + if (position == 0) { + showNodeInfo(); + } else { + showLayoutBounds(); + } + } + }); + mBubblePopMenu.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); + mBubblePopMenu.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); + } + + private void showLayoutBounds() { + close(); + LayoutBoundsFloatyWindow window = new LayoutBoundsFloatyWindow(mRootNode); + window.setSelectedNode(mSelectedNode); + FloatyService.addWindow(window); + } + + + void showNodeInfo() { + ensureNodeInfoDialog(); + mNodeInfoView.setNodeInfo(mSelectedNodeInfo); + mNodeInfoDialog.show(); + } + + private void ensureNodeInfoDialog() { + if (mNodeInfoDialog == null) { + mNodeInfoView = new NodeInfoView(mContext); + mNodeInfoDialog = new MaterialDialog.Builder(mContext) + .customView(mNodeInfoView, false) + .theme(Theme.LIGHT) + .build(); + if (mNodeInfoDialog.getWindow() != null) + mNodeInfoDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE); + } + } + + + public void setSelectedNode(NodeInfo selectedNode) { + mSelectedNode = selectedNode; + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutHierarchyView.java b/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutHierarchyView.java similarity index 99% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutHierarchyView.java rename to app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutHierarchyView.java index c0381c7e..5efb03c5 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutHierarchyView.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutHierarchyView.java @@ -1,4 +1,4 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view; +package com.stardust.scriptdroid.ui.floating.layoutinspector; import android.content.Context; import android.graphics.Canvas; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/NodeInfoView.java b/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/NodeInfoView.java similarity index 98% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/NodeInfoView.java rename to app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/NodeInfoView.java index 2a8c68e3..ae9ceac5 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/NodeInfoView.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/NodeInfoView.java @@ -1,4 +1,4 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view; +package com.stardust.scriptdroid.ui.floating.layoutinspector; import android.content.Context; import android.support.annotation.Nullable; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/OnNodeInfoSelectListener.java b/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/OnNodeInfoSelectListener.java similarity index 68% rename from app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/OnNodeInfoSelectListener.java rename to app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/OnNodeInfoSelectListener.java index 5fb29295..be787a54 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/OnNodeInfoSelectListener.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/OnNodeInfoSelectListener.java @@ -1,4 +1,4 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view; +package com.stardust.scriptdroid.ui.floating.layoutinspector; import com.stardust.view.accessibility.NodeInfo; diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java index 0c38a784..61648e16 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java @@ -26,8 +26,9 @@ import com.stardust.scriptdroid.BuildConfig; import com.stardust.scriptdroid.Pref; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.autojs.AutoJs; -import com.stardust.scriptdroid.external.floatingwindow.HoverMenuManger; +import com.stardust.scriptdroid.external.floatingwindow.FloatyWindowManger; import com.stardust.scriptdroid.script.StorageFileProvider; +import com.stardust.scriptdroid.ui.floating.CircularMenu; import com.stardust.scriptdroid.ui.main.community.CommunityFragment_; import com.stardust.scriptdroid.ui.main.doc.OnlineDocsFragment_; import com.stardust.scriptdroid.ui.main.scripts.MyScriptListFragment_; @@ -184,7 +185,7 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega @Click(R.id.exit) public void exitCompletely() { - HoverMenuManger.hideHoverMenu(); + FloatyWindowManger.hideCircularMenu(); stopService(new Intent(this, FloatyService.class)); AutoJs.getInstance().getScriptEngineService().stopAll(); finish(); diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/drawer/DrawerFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/drawer/DrawerFragment.java index c211a57d..1df040f3 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/drawer/DrawerFragment.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/drawer/DrawerFragment.java @@ -14,15 +14,13 @@ import com.afollestad.materialdialogs.MaterialDialog; import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.Pref; import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.external.floatingwindow.HoverMenuManger; -import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService; +import com.stardust.scriptdroid.external.floatingwindow.FloatyWindowManger; import com.stardust.scriptdroid.network.NodeBB; import com.stardust.scriptdroid.network.VersionService; import com.stardust.scriptdroid.network.api.UserApi; import com.stardust.scriptdroid.network.entity.User; import com.stardust.scriptdroid.network.entity.VersionInfo; import com.stardust.scriptdroid.tool.SimpleObserver; -import com.stardust.scriptdroid.ui.login.LoginActivity; import com.stardust.scriptdroid.ui.login.LoginActivity_; import com.stardust.scriptdroid.ui.settings.SettingsActivity; import com.stardust.scriptdroid.ui.update.UpdateInfoDialogBuilder; @@ -39,7 +37,6 @@ import org.androidannotations.annotations.EFragment; import org.androidannotations.annotations.ViewById; import org.greenrobot.eventbus.Subscribe; -import java.io.IOException; import java.util.concurrent.Callable; import io.reactivex.Observable; @@ -47,11 +44,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; import io.reactivex.functions.Consumer; import io.reactivex.schedulers.Schedulers; -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.OkHttpClient; -import okhttp3.Response; -import okhttp3.WebSocket; /** @@ -166,13 +158,13 @@ public class DrawerFragment extends android.support.v4.app.Fragment { @Click(R.id.floating_window) void showOrDismissFloatingWindow() { - boolean isFloatingWindowShowing = HoverMenuManger.isHoverMenuShowing(); + boolean isFloatingWindowShowing = FloatyWindowManger.isCircularMenuShowing(); boolean checked = mFloatingWindowItem.getSwitchCompat().isChecked(); if (checked && !isFloatingWindowShowing) { - HoverMenuManger.showHoverMenu(); + FloatyWindowManger.showCircularMenu(); enableAccessibilityServiceByRootIfNeeded(); } else if (!checked && isFloatingWindowShowing) { - HoverMenuManger.hideHoverMenu(); + FloatyWindowManger.hideCircularMenu(); } } @@ -298,7 +290,6 @@ public class DrawerFragment extends android.support.v4.app.Fragment { private void syncSwitchState() { mAccessibilityServiceItem.getSwitchCompat().setChecked( AccessibilityServiceTool.isAccessibilityServiceEnabled(getActivity())); - mFloatingWindowItem.getSwitchCompat().setChecked(HoverMenuManger.isHoverMenuShowing()); } private void enableAccessibilityService() { @@ -337,8 +328,4 @@ public class DrawerFragment extends android.support.v4.app.Fragment { mConnectionStateDisposable.dispose(); } - @Subscribe - public void onHoverMenuServiceStateChanged(HoverMenuService.ServiceStateChangedEvent event) { - mAccessibilityServiceItem.getSwitchCompat().setChecked(event.state); - } } diff --git a/app/src/main/res/drawable/autojs_logo.png b/app/src/main/res/drawable/autojs_logo.png new file mode 100644 index 00000000..e95d6565 Binary files /dev/null and b/app/src/main/res/drawable/autojs_logo.png differ diff --git a/app/src/main/res/drawable/circle_blue.xml b/app/src/main/res/drawable/circle_blue.xml new file mode 100644 index 00000000..4b132251 --- /dev/null +++ b/app/src/main/res/drawable/circle_blue.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/circle_gray.xml b/app/src/main/res/drawable/circle_gray.xml new file mode 100644 index 00000000..dd9b7323 --- /dev/null +++ b/app/src/main/res/drawable/circle_gray.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/circle_green.xml b/app/src/main/res/drawable/circle_green.xml index 95376eb4..50194cc2 100644 --- a/app/src/main/res/drawable/circle_green.xml +++ b/app/src/main/res/drawable/circle_green.xml @@ -1,11 +1,8 @@ - - - - - - - + + \ No newline at end of file diff --git a/app/src/main/res/drawable/circle_light_green.xml b/app/src/main/res/drawable/circle_light_green.xml new file mode 100644 index 00000000..95376eb4 --- /dev/null +++ b/app/src/main/res/drawable/circle_light_green.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/circle_red.xml b/app/src/main/res/drawable/circle_red.xml new file mode 100644 index 00000000..11b9d0e7 --- /dev/null +++ b/app/src/main/res/drawable/circle_red.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/circle_white.xml b/app/src/main/res/drawable/circle_white.xml new file mode 100644 index 00000000..50194cc2 --- /dev/null +++ b/app/src/main/res/drawable/circle_white.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/circle_yellow.xml b/app/src/main/res/drawable/circle_yellow.xml new file mode 100644 index 00000000..9973ba04 --- /dev/null +++ b/app/src/main/res/drawable/circle_yellow.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_circular_menu_bounds.png b/app/src/main/res/drawable/ic_circular_menu_bounds.png new file mode 100644 index 00000000..a3335411 Binary files /dev/null and b/app/src/main/res/drawable/ic_circular_menu_bounds.png differ diff --git a/app/src/main/res/drawable/ic_circular_menu_hierarchy.png b/app/src/main/res/drawable/ic_circular_menu_hierarchy.png new file mode 100644 index 00000000..f2fbba8f Binary files /dev/null and b/app/src/main/res/drawable/ic_circular_menu_hierarchy.png differ diff --git a/app/src/main/res/drawable/ic_circular_menu_settings.png b/app/src/main/res/drawable/ic_circular_menu_settings.png new file mode 100644 index 00000000..c62bd809 Binary files /dev/null and b/app/src/main/res/drawable/ic_circular_menu_settings.png differ diff --git a/app/src/main/res/layout/circular_action_menu.xml b/app/src/main/res/layout/circular_action_menu.xml new file mode 100644 index 00000000..8683d964 --- /dev/null +++ b/app/src/main/res/layout/circular_action_menu.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/circular_action_view.xml b/app/src/main/res/layout/circular_action_view.xml new file mode 100644 index 00000000..f7d9b816 --- /dev/null +++ b/app/src/main/res/layout/circular_action_view.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/script_file_list_file.xml b/app/src/main/res/layout/script_file_list_file.xml index c4b811f2..0e584f9e 100644 --- a/app/src/main/res/layout/script_file_list_file.xml +++ b/app/src/main/res/layout/script_file_list_file.xml @@ -26,7 +26,7 @@ android:layout_height="40dp" android:layout_gravity="center_vertical" android:layout_marginLeft="8dp" - android:background="@drawable/circle_green" + android:background="@drawable/circle_light_green" android:gravity="center" android:textColor="@android:color/white" android:textSize="24sp" diff --git a/app/src/main/res/layout/task_list_recycler_view_item.xml b/app/src/main/res/layout/task_list_recycler_view_item.xml index b40328a8..1d1b71d7 100644 --- a/app/src/main/res/layout/task_list_recycler_view_item.xml +++ b/app/src/main/res/layout/task_list_recycler_view_item.xml @@ -17,7 +17,7 @@ android:layout_height="40dp" android:layout_gravity="center_vertical" android:layout_marginLeft="8dp" - android:background="@drawable/circle_green" + android:background="@drawable/circle_light_green" android:gravity="center" android:textColor="@android:color/white" android:textSize="24sp" diff --git a/autojs/src/main/assets/modules/__http__.js b/autojs/src/main/assets/modules/__http__.js index 7c09d755..1dde8abf 100644 --- a/autojs/src/main/assets/modules/__http__.js +++ b/autojs/src/main/assets/modules/__http__.js @@ -31,7 +31,7 @@ module.exports = function(runtime, scope){ } http.request = function(url, options, callback){ - var call = http.newCall(buildRequest(url, options)); + var call = http.client().newCall(http.buildRequest(url, options)); if(!callback){ return wrapResponse(call.execute()); } @@ -74,7 +74,7 @@ module.exports = function(runtime, scope){ }else if(options.contentType == "application/json"){ options.body = JSON.stringify(data); }else{ - //todo what? + options.body = data; } } diff --git a/autojs/src/main/java/com/stardust/autojs/core/templatematching/Test.java b/autojs/src/main/java/com/stardust/autojs/core/templatematching/Test.java new file mode 100644 index 00000000..8c406c65 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/core/templatematching/Test.java @@ -0,0 +1,18 @@ +package com.stardust.autojs.core.templatematching; + +import android.graphics.Color; +import android.media.Image; + +import com.stardust.autojs.runtime.api.image.Images; + +/** + * Created by Stardust on 2017/10/5. + */ + +public class Test { + + public void test(Image image) { + + } + +}