OSDN Git Service

More progress on desktop icons + minor cleanup
authorBraden Farmer <farmerbb@gmail.com>
Sun, 28 Jul 2019 06:53:42 +0000 (00:53 -0600)
committerBraden Farmer <farmerbb@gmail.com>
Sun, 28 Jul 2019 06:53:42 +0000 (00:53 -0600)
29 files changed:
app/src/androidx86/AndroidManifest.xml
app/src/main/java/com/farmerbb/taskbar/activity/ContextMenuActivity.java
app/src/main/java/com/farmerbb/taskbar/activity/DashboardActivity.java
app/src/main/java/com/farmerbb/taskbar/activity/DesktopIconSelectAppActivity.java [new file with mode: 0644]
app/src/main/java/com/farmerbb/taskbar/activity/HomeActivityDelegate.java
app/src/main/java/com/farmerbb/taskbar/activity/InvisibleActivityAlt.java
app/src/main/java/com/farmerbb/taskbar/activity/KeyboardShortcutActivity.java
app/src/main/java/com/farmerbb/taskbar/activity/MainActivity.java
app/src/main/java/com/farmerbb/taskbar/activity/TouchAbsorberActivity.java
app/src/main/java/com/farmerbb/taskbar/activity/dark/DesktopIconSelectAppActivityDark.java [new file with mode: 0644]
app/src/main/java/com/farmerbb/taskbar/adapter/DesktopIconAppListAdapter.java [new file with mode: 0644]
app/src/main/java/com/farmerbb/taskbar/adapter/StartMenuAdapter.java
app/src/main/java/com/farmerbb/taskbar/ui/DashboardController.java
app/src/main/java/com/farmerbb/taskbar/ui/StartMenuController.java
app/src/main/java/com/farmerbb/taskbar/ui/TaskbarController.java
app/src/main/java/com/farmerbb/taskbar/util/DesktopIconInfo.java [new file with mode: 0644]
app/src/main/java/com/farmerbb/taskbar/util/DisplayInfo.java
app/src/main/java/com/farmerbb/taskbar/util/IconPack.java
app/src/main/res/layout/desktop_icon_row.xml [new file with mode: 0644]
app/src/main/res/layout/desktop_icon_select_app.xml [new file with mode: 0644]
app/src/main/res/values-de/strings.xml
app/src/main/res/values-ja/strings.xml
app/src/main/res/values-nl/strings.xml
app/src/main/res/values-ru/strings.xml
app/src/main/res/values-tr/strings.xml
app/src/main/res/values-zh-rCN/strings.xml
app/src/main/res/values/strings.xml
app/src/main/res/xml/pref_context_menu_desktop_icons.xml [new file with mode: 0644]
app/src/playstore/AndroidManifest.xml

index e8e60d3..ff849f9 100644 (file)
             android:name=".activity.dark.SelectAppActivityDark"
             android:theme="@style/AppTheme.Dialog.Blacklist.Dark"/>
         <activity
+            android:name=".activity.DesktopIconSelectAppActivity"
+            android:theme="@style/AppTheme.Dialog.Blacklist"/>
+        <activity
+            android:name=".activity.dark.DesktopIconSelectAppActivityDark"
+            android:theme="@style/AppTheme.Dialog.Blacklist.Dark"/>
+        <activity
             android:name=".activity.DummyActivity"
             android:documentLaunchMode="always"
             android:excludeFromRecents="true"
index 9235b01..8c8018a 100644 (file)
@@ -45,10 +45,13 @@ import android.view.WindowManager;
 
 import com.farmerbb.taskbar.BuildConfig;
 import com.farmerbb.taskbar.R;
+import com.farmerbb.taskbar.activity.dark.DesktopIconSelectAppActivityDark;
 import com.farmerbb.taskbar.activity.dark.SelectAppActivityDark;
 import com.farmerbb.taskbar.util.AppEntry;
 import com.farmerbb.taskbar.util.ApplicationType;
+import com.farmerbb.taskbar.util.DesktopIconInfo;
 import com.farmerbb.taskbar.util.DisplayInfo;
+import com.farmerbb.taskbar.util.FeatureFlags;
 import com.farmerbb.taskbar.util.FreeformHackHelper;
 import com.farmerbb.taskbar.util.IconCache;
 import com.farmerbb.taskbar.util.LauncherHelper;
@@ -68,10 +71,13 @@ public class ContextMenuActivity extends PreferenceActivity implements Preferenc
     String appName;
     long userId = 0;
 
+    DesktopIconInfo desktopIcon;
+
     boolean showStartMenu = false;
     boolean shouldHideTaskbar = false;
     boolean isStartButton = false;
     boolean isOverflowMenu = false;
+    boolean isNonAppMenu = false;
     boolean secondaryMenu = false;
     boolean dashboardOrStartMenuAppearing = false;
     boolean contextMenuFix = false;
@@ -95,7 +101,6 @@ public class ContextMenuActivity extends PreferenceActivity implements Preferenc
 
 
     @SuppressLint("RtlHardcoded")
-    @SuppressWarnings("deprecation")
     @Override
     protected void onPostCreate(Bundle savedInstanceState) {
         super.onPostCreate(savedInstanceState);
@@ -104,8 +109,10 @@ public class ContextMenuActivity extends PreferenceActivity implements Preferenc
         MenuHelper.getInstance().setContextMenuOpen(true);
 
         args = getIntent().getBundleExtra("args");
-        
-        boolean isNonAppMenu = !args.containsKey("package_name") && !args.containsKey("app_name");
+
+        desktopIcon = (DesktopIconInfo) args.getSerializable("desktop_icon");
+
+        isNonAppMenu = !args.containsKey("package_name") && !args.containsKey("app_name");
         showStartMenu = args.getBoolean("launched_from_start_menu", false);
         isStartButton = isNonAppMenu && args.getBoolean("is_start_button", false);
         isOverflowMenu = isNonAppMenu && args.getBoolean("is_overflow_menu", false);
@@ -120,7 +127,7 @@ public class ContextMenuActivity extends PreferenceActivity implements Preferenc
         if(resourceId > 0)
             statusBarHeight = getResources().getDimensionPixelSize(resourceId);
 
-        if(showStartMenu) {
+        if(showStartMenu || desktopIcon != null) {
             int x = args.getInt("x", 0);
             int y = args.getInt("y", 0);
             int offset = getResources().getDimensionPixelSize(isOverflowMenu ? R.dimen.context_menu_offset_overflow : R.dimen.context_menu_offset);
@@ -244,6 +251,7 @@ public class ContextMenuActivity extends PreferenceActivity implements Preferenc
             findPreference("start_menu_apps").setOnPreferenceClickListener(this);
 
             if(pref.getBoolean("freeform_hack", false)
+                    && !FeatureFlags.desktopIcons(this)
                     && ((U.launcherIsDefault(this)
                     && !U.isOverridingFreeformHack(this)
                     && FreeformHackHelper.getInstance().isInFreeformWorkspace())
@@ -275,6 +283,11 @@ public class ContextMenuActivity extends PreferenceActivity implements Preferenc
                 findPreference("file_manager").setOnPreferenceClickListener(this);
             else
                 getPreferenceScreen().removePreference(findPreference("file_manager"));
+        } else if(desktopIcon != null && isNonAppMenu) {
+            addPreferencesFromResource(R.xml.pref_context_menu_desktop_icons);
+            findPreference("add_icon_to_desktop").setOnPreferenceClickListener(this);
+            findPreference("arrange_icons").setOnPreferenceClickListener(this);
+            findPreference("change_wallpaper").setOnPreferenceClickListener(this);
         } else {
             appName = args.getString("app_name");
             packageName = args.getString("package_name");
@@ -646,6 +659,42 @@ public class ContextMenuActivity extends PreferenceActivity implements Preferenc
                 shouldHideTaskbar = true;
                 contextMenuFix = false;
                 break;
+            case "add_icon_to_desktop":
+                Intent intent2 = null;
+
+                SharedPreferences pref4 = U.getSharedPreferences(this);
+                switch(pref4.getString("theme", "light")) {
+                    case "light":
+                        intent2 = new Intent(this, DesktopIconSelectAppActivity.class);
+                        break;
+                    case "dark":
+                        intent2 = new Intent(this, DesktopIconSelectAppActivityDark.class);
+                        break;
+                }
+
+                if(intent2 != null)
+                    intent2.putExtra("desktop_icon", desktopIcon);
+
+                if(U.hasFreeformSupport(this)
+                        && pref4.getBoolean("freeform_hack", false)
+                        && intent2 != null && isInMultiWindowMode()) {
+                    intent2.putExtra("no_shadow", true);
+                    intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
+
+                    U.startActivityMaximized(getApplicationContext(), intent2);
+                } else {
+                    try {
+                        startActivity(intent2);
+                    } catch (IllegalArgumentException e) { /* Gracefully fail */ }
+                }
+
+                showStartMenu = false;
+                shouldHideTaskbar = true;
+                contextMenuFix = false;
+                break;
+            case "arrange_icons":
+                // TODO implement
+                break;
             case "change_wallpaper":
                 Intent intent3 = Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER), getString(R.string.set_wallpaper));
                 intent3.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
index 13e16d6..df9f89d 100644 (file)
@@ -117,7 +117,6 @@ public class DashboardActivity extends Activity {
         }
     };
 
-    @SuppressWarnings("deprecation")
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
diff --git a/app/src/main/java/com/farmerbb/taskbar/activity/DesktopIconSelectAppActivity.java b/app/src/main/java/com/farmerbb/taskbar/activity/DesktopIconSelectAppActivity.java
new file mode 100644 (file)
index 0000000..becc067
--- /dev/null
@@ -0,0 +1,162 @@
+/* Copyright 2019 Braden Farmer
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.farmerbb.taskbar.activity;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v4.content.LocalBroadcastManager;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.ListView;
+import android.widget.ProgressBar;
+
+import com.farmerbb.taskbar.R;
+import com.farmerbb.taskbar.activity.dark.DesktopIconSelectAppActivityDark;
+import com.farmerbb.taskbar.adapter.DesktopIconAppListAdapter;
+import com.farmerbb.taskbar.util.AppEntry;
+import com.farmerbb.taskbar.util.DesktopIconInfo;
+import com.farmerbb.taskbar.util.U;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class DesktopIconSelectAppActivity extends AppCompatActivity {
+
+    private DesktopIconAppListGenerator appListGenerator;
+    private ProgressBar progressBar;
+    private ListView appList;
+
+    private DesktopIconInfo desktopIcon;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        desktopIcon = (DesktopIconInfo) getIntent().getSerializableExtra("desktop_icon");
+        boolean noShadow = getIntent().hasExtra("no_shadow");
+
+        if(savedInstanceState == null) {
+            setContentView(R.layout.desktop_icon_select_app);
+            setFinishOnTouchOutside(false);
+            setTitle(getString(R.string.select_an_app));
+
+            if(noShadow) {
+                WindowManager.LayoutParams params = getWindow().getAttributes();
+                params.dimAmount = 0;
+                getWindow().setAttributes(params);
+
+                if(U.isChromeOs(this) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1)
+                    getWindow().setElevation(0);
+            }
+
+            progressBar = findViewById(R.id.progress_bar);
+            appList = findViewById(R.id.list);
+
+            appListGenerator = new DesktopIconAppListGenerator();
+            appListGenerator.execute();
+        } else {
+            finish();
+
+            if(!noShadow)
+                new Handler().post(() -> {
+                    Intent intent = null;
+                    SharedPreferences pref = U.getSharedPreferences(this);
+
+                    switch(pref.getString("theme", "light")) {
+                        case "light":
+                            intent = new Intent(this, DesktopIconSelectAppActivity.class);
+                            break;
+                        case "dark":
+                            intent = new Intent(this, DesktopIconSelectAppActivityDark.class);
+                            break;
+                    }
+
+                    if(intent != null)
+                        intent.putExtra("desktop_icon", desktopIcon);
+
+                    startActivity(intent);
+                });
+        }
+    }
+
+    @Override
+    public void finish() {
+        if(appListGenerator != null && appListGenerator.getStatus() == AsyncTask.Status.RUNNING)
+            appListGenerator.cancel(true);
+
+        super.finish();
+    }
+
+    public void selectApp(AppEntry entry) {
+        desktopIcon.entry = entry;
+
+        try {
+            SharedPreferences pref = U.getSharedPreferences(this);
+            JSONArray icons = new JSONArray(pref.getString("desktop_icons", "[]"));
+            icons.put(desktopIcon.toJson(this));
+
+            pref.edit().putString("desktop_icons", icons.toString()).apply();
+            LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.REFRESH_DESKTOP_ICONS"));
+        } catch (JSONException e) { /* Gracefully fail */ }
+
+        finish();
+    }
+
+    private final class DesktopIconAppListGenerator extends AsyncTask<Void, Void, DesktopIconAppListAdapter> {
+        @Override
+        protected DesktopIconAppListAdapter doInBackground(Void... params) {
+            final PackageManager pm = getPackageManager();
+
+            Intent intent = new Intent(Intent.ACTION_MAIN);
+            intent.addCategory(Intent.CATEGORY_LAUNCHER);
+            List<ResolveInfo> info = pm.queryIntentActivities(intent, 0);
+
+            Collections.sort(info, (ai1, ai2) -> ai1.activityInfo.loadLabel(pm).toString().compareTo(ai2.activityInfo.loadLabel(pm).toString()));
+
+            final List<AppEntry> entries = new ArrayList<>();
+            for(ResolveInfo appInfo : info) {
+                entries.add(new AppEntry(
+                        appInfo.activityInfo.applicationInfo.packageName,
+                        new ComponentName(
+                                appInfo.activityInfo.applicationInfo.packageName,
+                                appInfo.activityInfo.name).flattenToString(),
+                        appInfo.loadLabel(pm).toString(),
+                        appInfo.loadIcon(pm),
+                        false));
+            }
+
+            return new DesktopIconAppListAdapter(DesktopIconSelectAppActivity.this, R.layout.desktop_icon_row, entries);
+        }
+
+        @Override
+        protected void onPostExecute(DesktopIconAppListAdapter adapter) {
+            progressBar.setVisibility(View.GONE);
+            appList.setAdapter(adapter);
+        }
+    }
+}
\ No newline at end of file
index fb4ea67..b7dc36f 100644 (file)
@@ -32,6 +32,7 @@ import android.os.Bundle;
 import android.os.Handler;
 import android.support.v4.content.ContextCompat;
 import android.support.v4.content.LocalBroadcastManager;
+import android.util.SparseArray;
 import android.view.DragEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -56,6 +57,7 @@ import com.farmerbb.taskbar.ui.StartMenuController;
 import com.farmerbb.taskbar.ui.TaskbarController;
 import com.farmerbb.taskbar.util.AppEntry;
 import com.farmerbb.taskbar.util.CompatUtils;
+import com.farmerbb.taskbar.util.DesktopIconInfo;
 import com.farmerbb.taskbar.util.DisplayInfo;
 import com.farmerbb.taskbar.util.FeatureFlags;
 import com.farmerbb.taskbar.util.FreeformHackHelper;
@@ -63,6 +65,9 @@ import com.farmerbb.taskbar.util.IconCache;
 import com.farmerbb.taskbar.util.LauncherHelper;
 import com.farmerbb.taskbar.util.U;
 
+import org.json.JSONArray;
+import org.json.JSONException;
+
 public class HomeActivityDelegate extends Activity implements UIHost {
     private TaskbarController taskbarController;
     private StartMenuController startMenuController;
@@ -108,6 +113,13 @@ public class HomeActivityDelegate extends Activity implements UIHost {
         }
     };
 
+    private BroadcastReceiver refreshDesktopIconsReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            refreshDesktopIcons();
+        }
+    };
+
     @SuppressLint("RestrictedApi")
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -154,23 +166,25 @@ public class HomeActivityDelegate extends Activity implements UIHost {
             }
         };
 
-        layout.setOnClickListener(view1 -> LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU")));
+        if(!FeatureFlags.desktopIcons(this)) {
+            layout.setOnClickListener(view1 -> LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU")));
 
-        layout.setOnLongClickListener(view2 -> {
-            if(!pref.getBoolean("freeform_hack", false))
-                setWallpaper();
+            layout.setOnLongClickListener(view2 -> {
+                if(!pref.getBoolean("freeform_hack", false))
+                    setWallpaper();
 
-            return false;
-        });
+                return false;
+            });
 
-        layout.setOnGenericMotionListener((view3, motionEvent) -> {
-            if(motionEvent.getAction() == MotionEvent.ACTION_BUTTON_PRESS
-                    && motionEvent.getButtonState() == MotionEvent.BUTTON_SECONDARY
-                    && !pref.getBoolean("freeform_hack", false))
-                setWallpaper();
+            layout.setOnGenericMotionListener((view3, motionEvent) -> {
+                if(motionEvent.getAction() == MotionEvent.ACTION_BUTTON_PRESS
+                        && motionEvent.getButtonState() == MotionEvent.BUTTON_SECONDARY
+                        && !pref.getBoolean("freeform_hack", false))
+                    setWallpaper();
 
-            return false;
-        });
+                return false;
+            });
+        }
 
         layout.setFitsSystemWindows(true);
 
@@ -196,6 +210,9 @@ public class HomeActivityDelegate extends Activity implements UIHost {
         if(FeatureFlags.homeActivityUIHost())
             lbm.registerReceiver(restartReceiver, new IntentFilter("com.farmerbb.taskbar.RESTART"));
 
+        if(FeatureFlags.desktopIcons(this))
+            lbm.registerReceiver(refreshDesktopIconsReceiver, new IntentFilter("com.farmerbb.taskbar.REFRESH_DESKTOP_ICONS"));
+
         U.initPrefs(this);
     }
 
@@ -364,6 +381,9 @@ public class HomeActivityDelegate extends Activity implements UIHost {
 
         if(FeatureFlags.homeActivityUIHost())
             lbm.unregisterReceiver(restartReceiver);
+
+        if(FeatureFlags.desktopIcons(this))
+            lbm.unregisterReceiver(refreshDesktopIconsReceiver);
     }
 
     @Override
@@ -440,58 +460,88 @@ public class HomeActivityDelegate extends Activity implements UIHost {
     }
 
     private void initDesktopIcons() {
+        desktopIcons = new GridLayout(this);
+        refreshDesktopIcons();
+
+        layout.addView(desktopIcons, 0);
+        layout.invalidate();
+    }
+
+    private void refreshDesktopIcons() {
         int desktopIconSize = getResources().getDimensionPixelSize(R.dimen.start_menu_grid_width)
                 + getResources().getDimensionPixelSize(R.dimen.start_menu_grid_padding);
 
         int columns = layout.getWidth() / desktopIconSize;
         int rows = layout.getHeight() / desktopIconSize;
 
-        desktopIcons = new GridLayout(this);
+        desktopIcons.removeAllViews();
         desktopIcons.setColumnCount(columns);
         desktopIcons.setRowCount(rows);
 
+        SparseArray<DesktopIconInfo> icons = new SparseArray<>();
+
+        try {
+            SharedPreferences pref = U.getSharedPreferences(this);
+            JSONArray jsonIcons = new JSONArray(pref.getString("desktop_icons", "[]"));
+
+            for(int i = 0; i < jsonIcons.length(); i++) {
+                DesktopIconInfo info = DesktopIconInfo.fromJson(jsonIcons.getJSONObject(i));
+                if(info != null)
+                    icons.put(getIndex(info), info);
+            }
+        } catch (JSONException e) { /* Gracefully fail */ }
+
         for(int i = 0; i < columns * rows; i++) {
             FrameLayout iconContainer = new FrameLayout(this);
             iconContainer.setLayoutParams(new GridLayout.LayoutParams(new ViewGroup.LayoutParams(desktopIconSize, desktopIconSize)));
             iconContainer.setOnDragListener(new DesktopIconDragListener());
 
-            if(i == 0) {
-                AppEntry entry = new AppEntry(
-                        "com.farmerbb.taskbar",
-                        "com.farmerbb.taskbar/.MainActivity",
-                        "Taskbar",
-                        getResources().getDrawable(R.mipmap.ic_launcher),
-                        false
-                );
+            int index = i;
 
-                iconContainer.addView(inflateDesktopIcon(iconContainer, entry));
-            }
+            iconContainer.setOnLongClickListener(view -> {
+                int[] location = new int[2];
+                view.getLocationOnScreen(location);
+                openContextMenu(null, location, getDesktopIconInfo(index));
+                return true;
+            });
+
+            iconContainer.setOnGenericMotionListener((view, motionEvent) -> {
+                int action = motionEvent.getAction();
+
+                if(action == MotionEvent.ACTION_BUTTON_PRESS
+                        && motionEvent.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
+                    int[] location = new int[2];
+                    view.getLocationOnScreen(location);
+                    openContextMenu(null, location, getDesktopIconInfo(index));
+                }
+
+                return false;
+            });
+
+            DesktopIconInfo info = icons.get(index);
+            if(info != null && info.entry != null)
+                iconContainer.addView(inflateDesktopIcon(iconContainer, info.entry));
 
             desktopIcons.addView(iconContainer);
         }
-
-        layout.addView(desktopIcons, 0);
-        layout.invalidate();
     }
 
-    private int getIndexForColumnAndRow(int column, int row) {
-        return (row * desktopIcons.getColumnCount()) + column;
+    private int getIndex(DesktopIconInfo info) {
+        return (info.row * desktopIcons.getColumnCount()) + info.column;
     }
 
-    private int getColumnForIndex(int index) {
-        return index % desktopIcons.getColumnCount();
-    }
+    private DesktopIconInfo getDesktopIconInfo(int index) {
+        int column = index % desktopIcons.getColumnCount();
 
-    private int getRowForIndex(int index) {
         int pos = index;
-        int rowCount = -1;
+        int row = -1;
 
         while(pos >= 0) {
             pos -= desktopIcons.getColumnCount();
-            rowCount++;
+            row++;
         }
 
-        return rowCount;
+        return new DesktopIconInfo(column, row, null);
     }
 
     private View inflateDesktopIcon(ViewGroup parent, AppEntry entry) {
@@ -516,28 +566,25 @@ public class HomeActivityDelegate extends Activity implements UIHost {
                 false
         ));
 
-        layout.setOnLongClickListener(view -> {
-            int[] location = new int[2];
-            view.getLocationOnScreen(location);
-            // TODO openContextMenu(entry, location);
-            return true;
-        });
+        icon.setOnTouchListener(new DesktopIconTouchListener());
+        return icon;
+    }
 
-        layout.setOnGenericMotionListener((view, motionEvent) -> {
-            int action = motionEvent.getAction();
+    private void openContextMenu(final AppEntry entry, final int[] location, DesktopIconInfo info) {
+        Bundle args = new Bundle();
 
-            if(action == MotionEvent.ACTION_BUTTON_PRESS
-                    && motionEvent.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
-                int[] location = new int[2];
-                view.getLocationOnScreen(location);
-                // TODO openContextMenu(entry, location);
-            }
+        if(entry != null) {
+            args.putString("package_name", entry.getPackageName());
+            args.putString("app_name", entry.getLabel());
+            args.putString("component_name", entry.getComponentName());
+            args.putLong("user_id", entry.getUserId(this));
+        }
 
-            return false;
-        });
+        args.putSerializable("desktop_icon", info);
+        args.putInt("x", location[0]);
+        args.putInt("y", location[1]);
 
-        icon.setOnTouchListener(new DesktopIconTouchListener());
-        return icon;
+        U.startContextMenuActivity(this, args);
     }
 
     private final class DesktopIconTouchListener implements View.OnTouchListener {
index 7ca444c..6f75c58 100644 (file)
@@ -33,7 +33,6 @@ import com.farmerbb.taskbar.util.U;
 public class InvisibleActivityAlt extends InvisibleActivity {
 
     @SuppressLint("HardwareIds")
-    @SuppressWarnings("deprecation")
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
index ec53d35..0cc8b4a 100644 (file)
@@ -33,7 +33,6 @@ import java.util.Set;
 
 public class KeyboardShortcutActivity extends Activity {
 
-    @SuppressWarnings("deprecation")
     @TargetApi(Build.VERSION_CODES.N)
     @Override
     protected void onCreate(Bundle savedInstanceState) {
index 28df0d1..e72a4be 100644 (file)
@@ -310,7 +310,6 @@ public class MainActivity extends AppCompatActivity {
         super.onDestroy();
     }
 
-    @SuppressWarnings("deprecation")
     @TargetApi(Build.VERSION_CODES.N)
     private void startTaskbarService() {
         SharedPreferences pref = U.getSharedPreferences(this);
index ee5599b..044316f 100644 (file)
@@ -48,7 +48,6 @@ public class TouchAbsorberActivity extends Activity {
     };
 
     @SuppressLint("HardwareIds")
-    @SuppressWarnings("deprecation")
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
diff --git a/app/src/main/java/com/farmerbb/taskbar/activity/dark/DesktopIconSelectAppActivityDark.java b/app/src/main/java/com/farmerbb/taskbar/activity/dark/DesktopIconSelectAppActivityDark.java
new file mode 100644 (file)
index 0000000..58a2974
--- /dev/null
@@ -0,0 +1,20 @@
+/* Copyright 2019 Braden Farmer
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.farmerbb.taskbar.activity.dark;
+
+import com.farmerbb.taskbar.activity.DesktopIconSelectAppActivity;
+
+public class DesktopIconSelectAppActivityDark extends DesktopIconSelectAppActivity {}
diff --git a/app/src/main/java/com/farmerbb/taskbar/adapter/DesktopIconAppListAdapter.java b/app/src/main/java/com/farmerbb/taskbar/adapter/DesktopIconAppListAdapter.java
new file mode 100644 (file)
index 0000000..f27947b
--- /dev/null
@@ -0,0 +1,61 @@
+/* Copyright 2019 Braden Farmer
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.farmerbb.taskbar.adapter;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.farmerbb.taskbar.R;
+import com.farmerbb.taskbar.activity.DesktopIconSelectAppActivity;
+import com.farmerbb.taskbar.util.AppEntry;
+
+import java.util.List;
+
+public class DesktopIconAppListAdapter extends ArrayAdapter<AppEntry> {
+    public DesktopIconAppListAdapter(Context context, int layout, List<AppEntry> list) {
+        super(context, layout, list);
+    }
+
+    @Override
+    public View getView(int position, View convertView, final ViewGroup parent) {
+        // Check if an existing view is being reused, otherwise inflate the view
+        if(convertView == null)
+            convertView = LayoutInflater.from(getContext()).inflate(R.layout.desktop_icon_row, parent, false);
+
+        final AppEntry entry = getItem(position);
+        assert entry != null;
+
+        TextView textView = convertView.findViewById(R.id.name);
+        textView.setText(entry.getLabel());
+
+        ImageView imageView = convertView.findViewById(R.id.icon);
+        imageView.setImageDrawable(entry.getIcon(getContext()));
+
+        LinearLayout layout = convertView.findViewById(R.id.entry);
+        layout.setOnClickListener(view -> {
+            DesktopIconSelectAppActivity activity = (DesktopIconSelectAppActivity) getContext();
+            activity.selectApp(entry);
+        });
+
+        return convertView;
+    }
+}
\ No newline at end of file
index e2723ca..ef202ef 100644 (file)
@@ -188,7 +188,6 @@ public class StartMenuAdapter extends ArrayAdapter<AppEntry> implements SectionI
         return false;
     }
 
-    @SuppressWarnings("deprecation")
     private void openContextMenu(final AppEntry entry, final int[] location) {
         LocalBroadcastManager.getInstance(getContext()).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU_NO_RESET"));
 
index a19a0de..b909402 100644 (file)
@@ -305,7 +305,6 @@ public class DashboardController implements UIController {
             hideDashboard();
     }
 
-    @SuppressWarnings("deprecation")
     @TargetApi(Build.VERSION_CODES.N)
     private void showDashboard() {
         if(layout.getVisibility() == View.GONE) {
index 94bac86..3f1d400 100644 (file)
@@ -572,7 +572,6 @@ public class StartMenuController implements UIController {
             hideStartMenu(true);
     }
 
-    @SuppressWarnings("deprecation")
     @TargetApi(Build.VERSION_CODES.N)
     private void showStartMenu() {
         if(layout.getVisibility() == View.GONE) {
@@ -726,7 +725,6 @@ public class StartMenuController implements UIController {
         }
     }
 
-    @SuppressWarnings("deprecation")
     private void openContextMenu(final int[] location) {
         LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU_NO_RESET"));
 
index 8ffec00..94ebe3a 100644 (file)
@@ -1133,7 +1133,6 @@ public class TaskbarController implements UIController {
         isFirstStart = true;
     }
 
-    @SuppressWarnings("deprecation")
     private void openContextMenu() {
         SharedPreferences pref = U.getSharedPreferences(context);
 
@@ -1271,7 +1270,6 @@ public class TaskbarController implements UIController {
         return convertView;
     }
 
-    @SuppressWarnings("deprecation")
     private void openContextMenu(AppEntry entry, int[] location) {
         Bundle args = new Bundle();
         args.putString("package_name", entry.getPackageName());
diff --git a/app/src/main/java/com/farmerbb/taskbar/util/DesktopIconInfo.java b/app/src/main/java/com/farmerbb/taskbar/util/DesktopIconInfo.java
new file mode 100644 (file)
index 0000000..d1d37be
--- /dev/null
@@ -0,0 +1,68 @@
+/* Copyright 2019 Braden Farmer
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.farmerbb.taskbar.util;
+
+import android.content.Context;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.Serializable;
+
+public class DesktopIconInfo implements Serializable {
+    public int column;
+    public int row;
+    public AppEntry entry;
+
+    public DesktopIconInfo(int column, int row, AppEntry entry) {
+        this.column = column;
+        this.row = row;
+        this.entry = entry;
+    }
+
+    public JSONObject toJson(Context context) {
+        JSONObject json = new JSONObject();
+
+        try {
+            json.put("column", column);
+            json.put("row", row);
+            json.put("package_name", entry.getPackageName());
+            json.put("app_name", entry.getLabel());
+            json.put("component_name", entry.getComponentName());
+            json.put("user_id", entry.getUserId(context));
+        } catch (JSONException e) { /* Gracefully fail */ }
+
+        return json;
+    }
+
+    public static DesktopIconInfo fromJson(JSONObject json) {
+        try {
+            int column = json.getInt("column");
+            int row = json.getInt("row");
+            String packageName = json.getString("package_name");
+            String label = json.getString("app_name");
+            String componentName = json.getString("component_name");
+            long userId = json.getLong("user_id");
+
+            AppEntry entry = new AppEntry(packageName, componentName, label, null, false);
+            entry.setUserId(userId);
+
+            return new DesktopIconInfo(column, row, entry);
+        } catch (JSONException e) {
+            return null;
+        }
+    }
+}
index 56d4b1d..cc750de 100644 (file)
@@ -18,7 +18,7 @@ package com.farmerbb.taskbar.util;
 public class DisplayInfo {
     public int width;
     public int height;
-    public int density;
+    int density;
 
     DisplayInfo(int width, int height, int density) {
         this.width = width;
index 759812a..77fc9dd 100644 (file)
@@ -160,7 +160,6 @@ public class IconPack {
         }
     }
 
-    @SuppressWarnings("deprecation")
     private Bitmap loadBitmap(Context context, String drawableName) {
         int id = getResources(context).getIdentifier(drawableName, "drawable", packageName);
         if(id > 0) {
@@ -170,7 +169,7 @@ public class IconPack {
         }
         return null;
     }
-    @SuppressWarnings("deprecation")
+
     private Drawable loadDrawable(Context context, String drawableName) {
         int id = getResources(context).getIdentifier(drawableName, "drawable", packageName);
         if(id > 0) {
diff --git a/app/src/main/res/layout/desktop_icon_row.xml b/app/src/main/res/layout/desktop_icon_row.xml
new file mode 100644 (file)
index 0000000..86f36fe
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 Braden Farmer
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout
+    android:id="@+id/entry"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:paddingLeft="8dp"
+    android:paddingRight="8dp"
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <ImageView
+        android:id="@+id/icon"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:padding="8dp" />
+
+    <TextView
+        android:id="@+id/name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="4dp"
+        android:layout_marginLeft="4dp"
+        android:layout_gravity="center_vertical"
+        android:textSize="18sp"
+        android:maxLines="1"
+        android:ellipsize="end" />
+
+</LinearLayout>
diff --git a/app/src/main/res/layout/desktop_icon_select_app.xml b/app/src/main/res/layout/desktop_icon_select_app.xml
new file mode 100644 (file)
index 0000000..8342df5
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Copyright 2019 Braden Farmer\r
+\r
+     Licensed under the Apache License, Version 2.0 (the "License");\r
+     you may not use this file except in compliance with the License.\r
+     You may obtain a copy of the License at\r
+\r
+          http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+     Unless required by applicable law or agreed to in writing, software\r
+     distributed under the License is distributed on an "AS IS" BASIS,\r
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+     See the License for the specific language governing permissions and\r
+     limitations under the License.\r
+-->\r
+\r
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
+    android:layout_width="match_parent"\r
+    android:layout_height="match_parent" >\r
+\r
+    <ProgressBar\r
+        android:id="@+id/progress_bar"\r
+        android:layout_width="wrap_content"\r
+        android:layout_height="wrap_content"\r
+        android:layout_marginTop="48dp"\r
+        android:layout_marginBottom="48dp"\r
+        android:layout_gravity="center" />\r
+\r
+    <ListView\r
+        android:id="@+id/list"\r
+        android:layout_width="match_parent"\r
+        android:layout_height="match_parent" />\r
+\r
+</FrameLayout>
\ No newline at end of file
index 55887a7..a092ce6 100644 (file)
     <string name="force_activities_resizable">Erzwingen, dass Apps in der Größe veränderbar sind.</string>
     <string name="enable_freeform_windows">Freiform-Fenster aktivieren</string>
 
+    <string name="filepicker_select_an_image_file">Select an image file</string>
+    <string name="filepicker_install_file_manager">Please install a file manager.</string>
+    <string name="error_reading_custom_start_image">Error reading the custom image for the start menu. Try another file.</string>
+
+    <string name="add_icon_to_desktop">Add icon to desktop</string>
+    <string name="arrange_icons">Arrange icons</string>
+    <string name="select_an_app">Select an app</string>
+
 </resources>
index ed585d5..4f88a8d 100644 (file)
     <string name="force_activities_resizable">強制的にアクティビティをリサイズ可能にする</string>
     <string name="enable_freeform_windows">Enable freeform windows</string>
 
+    <string name="filepicker_select_an_image_file">Select an image file</string>
+    <string name="filepicker_install_file_manager">Please install a file manager.</string>
+    <string name="error_reading_custom_start_image">Error reading the custom image for the start menu. Try another file.</string>
+
+    <string name="add_icon_to_desktop">Add icon to desktop</string>
+    <string name="arrange_icons">Arrange icons</string>
+    <string name="select_an_app">Select an app</string>
+
 </resources>
\ No newline at end of file
index 66bde1f..816d590 100644 (file)
     <string name="force_activities_resizable">Formaat activiteiten geforceerd aanpasbaar maken</string>
     <string name="enable_freeform_windows">Enable freeform windows</string>
 
+    <string name="filepicker_select_an_image_file">Select an image file</string>
+    <string name="filepicker_install_file_manager">Please install a file manager.</string>
+    <string name="error_reading_custom_start_image">Error reading the custom image for the start menu. Try another file.</string>
+
+    <string name="add_icon_to_desktop">Add icon to desktop</string>
+    <string name="arrange_icons">Arrange icons</string>
+    <string name="select_an_app">Select an app</string>
+
 </resources>
index 8ad87ee..ac9d1c0 100644 (file)
     <string name="force_activities_resizable">Изменение размера в многооконном режиме</string>
     <string name="enable_freeform_windows">Enable freeform windows</string>
 
+    <string name="filepicker_select_an_image_file">Select an image file</string>
+    <string name="filepicker_install_file_manager">Please install a file manager.</string>
+    <string name="error_reading_custom_start_image">Error reading the custom image for the start menu. Try another file.</string>
+
+    <string name="add_icon_to_desktop">Add icon to desktop</string>
+    <string name="arrange_icons">Arrange icons</string>
+    <string name="select_an_app">Select an app</string>
+
 </resources>
\ No newline at end of file
index aaa7220..d2ec32f 100644 (file)
@@ -357,4 +357,12 @@ Bu durumda, bu cihazdaki serbest biçimli modu kullanmak için özel bir ROM fla
     <string name="force_activities_resizable">Yeniden boyutlandırılacak etkinlikleri zorla</string>
     <string name="enable_freeform_windows">Enable freeform windows</string>
 
+    <string name="filepicker_select_an_image_file">Select an image file</string>
+    <string name="filepicker_install_file_manager">Please install a file manager.</string>
+    <string name="error_reading_custom_start_image">Error reading the custom image for the start menu. Try another file.</string>
+
+    <string name="add_icon_to_desktop">Add icon to desktop</string>
+    <string name="arrange_icons">Arrange icons</string>
+    <string name="select_an_app">Select an app</string>
+
 </resources>
\ No newline at end of file
index d9e7ba3..2d7c57f 100644 (file)
     <string name="force_activities_resizable">强制将活动设为可调整大小</string>
     <string name="enable_freeform_windows">Enable freeform windows</string>
 
+    <string name="filepicker_select_an_image_file">Select an image file</string>
+    <string name="filepicker_install_file_manager">Please install a file manager.</string>
+    <string name="error_reading_custom_start_image">Error reading the custom image for the start menu. Try another file.</string>
+
+    <string name="add_icon_to_desktop">Add icon to desktop</string>
+    <string name="arrange_icons">Arrange icons</string>
+    <string name="select_an_app">Select an app</string>
+
 </resources>
\ No newline at end of file
index fc7c884..6774b23 100644 (file)
     <string name="force_activities_resizable">Force activities to be resizable</string>
     <string name="enable_freeform_windows">Enable freeform windows</string>
 
-    <string name="filepicker_select_an_image_file">Select an Image File</string>
-    <string name="filepicker_install_file_manager">"Please install a File Manager."</string>
+    <string name="filepicker_select_an_image_file">Select an image file</string>
+    <string name="filepicker_install_file_manager">Please install a file manager.</string>
     <string name="error_reading_custom_start_image">Error reading the custom image for the start menu. Try another file.</string>
 
+    <string name="add_icon_to_desktop">Add icon to desktop</string>
+    <string name="arrange_icons">Arrange icons</string>
+    <string name="select_an_app">Select an app</string>
+
 </resources>
diff --git a/app/src/main/res/xml/pref_context_menu_desktop_icons.xml b/app/src/main/res/xml/pref_context_menu_desktop_icons.xml
new file mode 100644 (file)
index 0000000..19a01d5
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 Braden Farmer
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <Preference
+        android:key="add_icon_to_desktop"
+        android:title="@string/add_icon_to_desktop" />
+
+    <Preference
+        android:key="arrange_icons"
+        android:title="@string/arrange_icons" />
+
+    <Preference
+        android:key="change_wallpaper"
+        android:title="@string/change_wallpaper" />
+
+</PreferenceScreen>
index 3aeeece..2270eeb 100644 (file)
             android:name=".activity.dark.SelectAppActivityDark"
             android:theme="@style/AppTheme.Dialog.Blacklist.Dark"/>
         <activity
+            android:name=".activity.DesktopIconSelectAppActivity"
+            android:theme="@style/AppTheme.Dialog.Blacklist"/>
+        <activity
+            android:name=".activity.dark.DesktopIconSelectAppActivityDark"
+            android:theme="@style/AppTheme.Dialog.Blacklist.Dark"/>
+        <activity
             android:name=".activity.DummyActivity"
             android:documentLaunchMode="always"
             android:excludeFromRecents="true"