Skip to content

Commit

Permalink
App groups
Browse files Browse the repository at this point in the history
  • Loading branch information
barnabwhy committed May 8, 2023
1 parent eb01a6a commit 8a47d67
Show file tree
Hide file tree
Showing 11 changed files with 258 additions and 23 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ android {
applicationId "com.barnabwhy.picozen"
minSdk 29
targetSdk 33
versionCode 5
versionName "0.0.5"
versionCode 10
versionName "0.1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
125 changes: 111 additions & 14 deletions app/src/main/java/com/barnabwhy/picozen/AppsAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
Expand Down Expand Up @@ -52,6 +53,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

public class AppsAdapter extends BaseAdapter
Expand All @@ -61,25 +63,42 @@ public class AppsAdapter extends BaseAdapter
private static String packageName;
private static long lastClickTime;
private static MainActivity mainActivityContext;
private final List<ApplicationInfo> appList;
private List<ApplicationInfo> appList;
private final Set<String> favoriteList;
private final Set<String> hiddenList;

public enum SORT_FIELD { APP_NAME, RECENT_DATE, INSTALL_DATE }
public enum SORT_ORDER { ASCENDING, DESCENDING }

private static int itemScale;
private final SettingsProvider settingsProvider;
public static SharedPreferences sharedPreferences;
private GridView appGridView;

public AppsAdapter(MainActivity context)
{
mainActivityContext = context;

appGridView = mainActivityContext.findViewById(R.id.app_grid);
TextView appGridEmpty = mainActivityContext.findViewById(R.id.app_grid_empty);
itemScale = getPixelFromDip(200);
appGridView.setColumnWidth(itemScale);
sharedPreferences = context.getSharedPreferences(context.getPackageName() + "_preferences", Context.MODE_PRIVATE);
settingsProvider = SettingsProvider.getInstance(mainActivityContext);

appList = getInstalledApps();
favoriteList = sharedPreferences.getStringSet(SettingsProvider.KEY_FAVORITE_APPS, new HashSet<String> ());
hiddenList = sharedPreferences.getStringSet(SettingsProvider.KEY_HIDDEN_APPS, new HashSet<String> ());

appList = getAppList(sharedPreferences.getInt(SettingsProvider.KEY_GROUP_SPINNER, 0));

if(appList.size() == 0) {
appGridView.setVisibility(View.GONE);
appGridEmpty.setVisibility(View.VISIBLE);
} else {
appGridView.setVisibility(View.VISIBLE);
appGridEmpty.setVisibility(View.GONE);
}

SORT_FIELD sortField = SORT_FIELD.values()[0];
SORT_ORDER sortOrder = SORT_ORDER.values()[0];
this.sort(sortField, sortOrder);
Expand All @@ -94,6 +113,8 @@ private static class ViewHolder {
ImageView imageView;
TextView textView;
ImageView progressBar;
View favoriteBtn;
View hiddenBtn;
}

public int getCount()
Expand All @@ -111,12 +132,19 @@ public long getItemId(int position)
return position;
}

public ArrayList<ApplicationInfo> getInstalledApps() {
public ArrayList<ApplicationInfo> getAppList(int group) {
final List<String> hiddenApps = Arrays.asList(mainActivityContext.getPackageName(), "com.android.traceur", "com.picovr.init.overlay", "com.picovr.provision", "com.pvr.appmanager", "com.pvr.seethrough.setting", "com.pvr.scenemanager");

ArrayList<ApplicationInfo> installedApps = new ArrayList<>();
PackageManager pm = mainActivityContext.getPackageManager();
for (ApplicationInfo app : pm.getInstalledApplications(PackageManager.GET_META_DATA)) {
if (hiddenApps.contains(app.packageName))
if (group == 0 && hiddenList.contains(app.packageName))
continue;
if (group == 1 && !favoriteList.contains(app.packageName))
continue;
if (group == 2 && !hiddenList.contains(app.packageName))
continue;
if(hiddenApps.contains(app.packageName))
continue;

if (!SettingsProvider.launchIntents.containsKey(app.packageName)) {
Expand Down Expand Up @@ -170,21 +198,83 @@ public View getView(int position, View convertView, ViewGroup parent)
holder.imageView = convertView.findViewById(R.id.imageLabel);
holder.textView = convertView.findViewById(R.id.textLabel);
holder.progressBar = convertView.findViewById(R.id.progress_bar);
holder.favoriteBtn = convertView.findViewById(R.id.favorite_btn);
holder.hiddenBtn = convertView.findViewById(R.id.hidden_btn);
convertView.setTag(holder);

AtomicInteger textVisible = new AtomicInteger(View.INVISIBLE);
convertView.setOnHoverListener((View view, MotionEvent event) -> {
holder.favoriteBtn.setForeground(ResourcesCompat.getDrawable(mainActivityContext.getResources(), favoriteList.contains(currentApp.packageName) ? R.drawable.ic_favorite_active : R.drawable.ic_favorite, mainActivityContext.getTheme()));
holder.hiddenBtn.setForeground(ResourcesCompat.getDrawable(mainActivityContext.getResources(), hiddenList.contains(currentApp.packageName) ? R.drawable.ic_hidden_active : R.drawable.ic_hidden, mainActivityContext.getTheme()));

holder.favoriteBtn.setOnClickListener(view -> {
ApplicationInfo app = appList.get(position);
boolean isFavorite = favoriteList.contains(app.packageName);

if(isFavorite) {
favoriteList.remove(app.packageName);
} else {
favoriteList.add(app.packageName);
if (hiddenList.contains(app.packageName)) {
hiddenList.remove(app.packageName);
}
}
sharedPreferences.edit().putStringSet(SettingsProvider.KEY_FAVORITE_APPS, favoriteList).apply();
sharedPreferences.edit().putStringSet(SettingsProvider.KEY_HIDDEN_APPS, hiddenList).apply();

if(sharedPreferences.getInt(SettingsProvider.KEY_GROUP_SPINNER, 0) == 0) {
holder.favoriteBtn.setForeground(ResourcesCompat.getDrawable(mainActivityContext.getResources(), isFavorite ? R.drawable.ic_favorite : R.drawable.ic_favorite_active, mainActivityContext.getTheme()));
} else {
// Reload view if state of current group changes
appList = getAppList(sharedPreferences.getInt(SettingsProvider.KEY_GROUP_SPINNER, 0));
this.sort(SORT_FIELD.values()[sharedPreferences.getInt(SettingsProvider.KEY_SORT_FIELD, 0)], SORT_ORDER.values()[sharedPreferences.getInt(SettingsProvider.KEY_SORT_ORDER, 0)]);
}
});

holder.hiddenBtn.setOnClickListener(view -> {
ApplicationInfo app = appList.get(position);
boolean isHidden = hiddenList.contains(app.packageName);

if(isHidden) {
hiddenList.remove(app.packageName);
} else {
hiddenList.add(app.packageName);
if (favoriteList.contains(app.packageName)) {
favoriteList.remove(app.packageName);
}
}
sharedPreferences.edit().putStringSet(SettingsProvider.KEY_FAVORITE_APPS, favoriteList).apply();
sharedPreferences.edit().putStringSet(SettingsProvider.KEY_HIDDEN_APPS, hiddenList).apply();

// Reload view if state of current group changes
appList = getAppList(sharedPreferences.getInt(SettingsProvider.KEY_GROUP_SPINNER, 0));
this.sort(SORT_FIELD.values()[sharedPreferences.getInt(SettingsProvider.KEY_SORT_FIELD, 0)], SORT_ORDER.values()[sharedPreferences.getInt(SettingsProvider.KEY_SORT_ORDER, 0)]);
});

AtomicInteger hovering = new AtomicInteger();
View.OnGenericMotionListener listener = (View view, MotionEvent event) -> {
if (event.getActionMasked() == MotionEvent.ACTION_HOVER_ENTER) {
view.findViewById(R.id.app_icon_overlay).setVisibility(View.VISIBLE);
textVisible.set(view.findViewById(R.id.textLabel).getVisibility());
view.findViewById(R.id.textLabel).setVisibility(View.VISIBLE);
hovering.getAndIncrement();

if(hovering.get() == 1) {
holder.layout.findViewById(R.id.app_icon_overlay).setVisibility(View.VISIBLE);
holder.layout.findViewById(R.id.textLabel).setVisibility(View.VISIBLE);
}
} else if (event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) {
view.findViewById(R.id.app_icon_overlay).setVisibility(View.INVISIBLE);
view.findViewById(R.id.textLabel).setVisibility(textVisible.get());
hovering.getAndDecrement();

if(hovering.get() == 0) {
holder.layout.findViewById(R.id.app_icon_overlay).setVisibility(View.INVISIBLE);
holder.layout.findViewById(R.id.textLabel).setVisibility((appList.size() > position && iconCache.containsKey("banners."+appList.get(position).packageName)) ? View.INVISIBLE : View.VISIBLE);
}
}
if(hovering.get() < 0) {
hovering.set(0);
}
return false;
});
};

convertView.setOnGenericMotionListener(listener);
holder.favoriteBtn.setOnGenericMotionListener(listener);
holder.hiddenBtn.setOnGenericMotionListener(listener);

// Set clipToOutline to true on imageView (Workaround for bug)
holder.layout.setClipToOutline(true);
Expand Down Expand Up @@ -387,6 +477,7 @@ public static File pkg2path(Context context, String pkg) {
private final String ICONS1_URL = "https://raw.githubusercontent.com/Veticia/binaries/main/banners/";
private static final String ICONS_FALLBACK_URL = "https://pilauncher.lwiczka.pl/get_icon.php?id=";
protected static final HashMap<String, Drawable> iconCache = new HashMap<>();
protected static final HashMap<String, GradientDrawable> gradientCache = new HashMap<>();
protected static final HashSet<String> ignoredIcons = new HashSet<>();

private void loadIcon(Activity activity, ViewHolder holder, ApplicationInfo app, String name) {
Expand Down Expand Up @@ -414,7 +505,12 @@ private void loadIcon(Activity activity, ViewHolder holder, ApplicationInfo app,
holder.imageView.setImageDrawable(appIcon);

Bitmap icon = drawableToBitmap(appIcon);
createIconPaletteAsync(icon, holder);

if(gradientCache.containsKey(pkg)) {
holder.layout.findViewById(R.id.app_color_bg).setBackground(gradientCache.get(pkg));
} else {
createIconPaletteAsync(pkg, icon, holder);
}
}

final File file = pkg2path(activity, "banners."+pkg);
Expand Down Expand Up @@ -625,14 +721,15 @@ public static boolean isPicoHeadset() {

// Generate palette asynchronously and use it on a different
// thread using onGenerated()
public static void createIconPaletteAsync(Bitmap bitmap, ViewHolder holder) {
public static void createIconPaletteAsync(String pkg, Bitmap bitmap, ViewHolder holder) {
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
public void onGenerated(Palette p) {
// Use generated instance
GradientDrawable gd = new GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
new int[] { p.getVibrantColor(mainActivityContext.getResources().getColor(R.color.bg_med)), p.getDarkVibrantColor(mainActivityContext.getResources().getColor(R.color.bg_dark)) });
gd.setCornerRadius(0f);
gradientCache.put(pkg, gd);
holder.layout.findViewById(R.id.app_color_bg).setBackground(gd);
}
});
Expand Down
24 changes: 24 additions & 0 deletions app/src/main/java/com/barnabwhy/picozen/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,30 @@ public void onNothingSelected(AdapterView<?> parent) {

}
});

// Set group button
Spinner groupSpinner = findViewById(R.id.group);
ArrayAdapter<CharSequence> groupApdater = ArrayAdapter.createFromResource(this, R.array.group_options, R.layout.spinner_item);
groupApdater.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
groupSpinner.setAdapter(groupApdater);
groupSpinner.setSelection(sharedPreferences.getInt(SettingsProvider.KEY_GROUP_SPINNER, 0));
groupSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
//persist sort settings
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(SettingsProvider.KEY_GROUP_SPINNER, pos);
editor.apply();

//update UI
appGridView.setAdapter(new AppsAdapter((MainActivity)mainContext));
}

@Override
public void onNothingSelected(AdapterView<?> parent) {

}
});
}

@SuppressLint("ClickableViewAccessibility")
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/com/barnabwhy/picozen/SettingsProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public class SettingsProvider
public static final String KEY_SORT_SPINNER = "KEY_SORT_SPINNER";
public static final String KEY_SORT_FIELD = "KEY_SORT_FIELD";
public static final String KEY_SORT_ORDER = "KEY_SORT_ORDER";
public static final String KEY_GROUP_SPINNER = "KEY_GROUP_SPINNER";
public static final String KEY_FAVORITE_APPS = "KEY_FAVORITE_APPS";
public static final String KEY_HIDDEN_APPS = "KEY_HIDDEN_APPS";
public static final String KEY_RECENTS = "KEY_RECENTS";

private final String KEY_APP_GROUPS = "prefAppGroups";
Expand Down
15 changes: 15 additions & 0 deletions app/src/main/res/drawable/ic_favorite.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:scaleX="0.67"
android:scaleY="0.67"
android:pivotX="12"
android:pivotY="12">
<path
android:pathData="M19.65,9.04l-4.84,-0.42 -1.89,-4.45c-0.34,-0.81 -1.5,-0.81 -1.84,0L9.19,8.63l-4.83,0.41c-0.88,0.07 -1.24,1.17 -0.57,1.75l3.67,3.18 -1.1,4.72c-0.2,0.86 0.73,1.54 1.49,1.08l4.15,-2.5 4.15,2.51c0.76,0.46 1.69,-0.22 1.49,-1.08l-1.1,-4.73 3.67,-3.18c0.67,-0.58 0.32,-1.68 -0.56,-1.75zM12,15.4l-3.76,2.27 1,-4.28 -3.32,-2.88 4.38,-0.38L12,6.1l1.71,4.04 4.38,0.38 -3.32,2.88 1,4.28L12,15.4z"
android:fillColor="@color/text"/>
</group>
</vector>
15 changes: 15 additions & 0 deletions app/src/main/res/drawable/ic_favorite_active.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:scaleX="0.67"
android:scaleY="0.67"
android:pivotX="12"
android:pivotY="12">
<path
android:pathData="m12,17.27 l4.15,2.51c0.76,0.46 1.69,-0.22 1.49,-1.08l-1.1,-4.72 3.67,-3.18c0.67,-0.58 0.31,-1.68 -0.57,-1.75l-4.83,-0.41 -1.89,-4.46c-0.34,-0.81 -1.5,-0.81 -1.84,0L9.19,8.63l-4.83,0.41c-0.88,0.07 -1.24,1.17 -0.57,1.75l3.67,3.18 -1.1,4.72c-0.2,0.86 0.73,1.54 1.49,1.08l4.15,-2.5z"
android:fillColor="@color/text"/>
</group>
</vector>
15 changes: 15 additions & 0 deletions app/src/main/res/drawable/ic_hidden.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:scaleX="0.67"
android:scaleY="0.67"
android:pivotX="12"
android:pivotY="12">
<path
android:pathData="M7,12c0,0.55 0.45,1 1,1h8c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L8,11c-0.55,0 -1,0.45 -1,1zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"
android:fillColor="@color/text"/>
</group>
</vector>
15 changes: 15 additions & 0 deletions app/src/main/res/drawable/ic_hidden_active.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:scaleX="0.67"
android:scaleY="0.67"
android:pivotX="12"
android:pivotY="12">
<path
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16,13L8,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"
android:fillColor="@color/text"/>
</group>
</vector>
25 changes: 24 additions & 1 deletion app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,23 @@
android:textSize="35sp"
android:padding="15dp" />

<Spinner
android:id="@+id/group"
android:theme="@style/spinnerItemStyle"
android:layout_width="160dp"
android:layout_height="40dp"
android:dropDownVerticalOffset="45dp"
android:popupBackground="@drawable/bg_list_item_hover_s"
android:background="@drawable/bg_list_item_s"
android:spinnerMode="dropdown"
android:textColor="@android:color/white"
android:scaleType="fitCenter"
android:layout_marginHorizontal="10dp" />

<Spinner
android:id="@+id/sort"
android:theme="@style/spinnerItemStyle"
android:layout_width="240dp"
android:layout_width="160dp"
android:layout_height="40dp"
android:dropDownVerticalOffset="45dp"
android:popupBackground="@drawable/bg_list_item_hover_s"
Expand All @@ -258,6 +271,16 @@
android:scrollbars="none"
android:overScrollMode="never">
</GridView>
<TextView
android:id="@+id/app_grid_empty"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="@string/empty_group"
android:gravity="center"
android:textStyle="bold"
android:textSize="20sp"
android:visibility="gone" />
</LinearLayout>

<LinearLayout
Expand Down
Loading

0 comments on commit 8a47d67

Please sign in to comment.