diff --git a/app_pojavlauncher/src/main/java/com/kdt/mcgui/mcVersionSpinner.java b/app_pojavlauncher/src/main/java/com/kdt/mcgui/mcVersionSpinner.java index ea0dd8a23..178663111 100644 --- a/app_pojavlauncher/src/main/java/com/kdt/mcgui/mcVersionSpinner.java +++ b/app_pojavlauncher/src/main/java/com/kdt/mcgui/mcVersionSpinner.java @@ -1,7 +1,6 @@ package com.kdt.mcgui; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; - import static net.kdt.pojavlaunch.fragments.ProfileEditorFragment.DELETED_PROFILE; import android.annotation.SuppressLint; @@ -9,6 +8,7 @@ import android.content.Context; import android.os.Build; import android.os.Bundle; import android.transition.Slide; +import android.transition.Transition; import android.util.AttributeSet; import android.util.TypedValue; import android.view.Gravity; @@ -19,15 +19,18 @@ import android.widget.PopupWindow; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.content.res.ResourcesCompat; import androidx.fragment.app.FragmentActivity; import net.kdt.pojavlaunch.R; import net.kdt.pojavlaunch.Tools; import net.kdt.pojavlaunch.extra.ExtraConstants; import net.kdt.pojavlaunch.extra.ExtraCore; +import net.kdt.pojavlaunch.fragments.ModdedProfileSelectFragment; +import net.kdt.pojavlaunch.fragments.ProfileEditorFragment; import net.kdt.pojavlaunch.prefs.LauncherPreferences; import net.kdt.pojavlaunch.profiles.ProfileAdapter; -import net.kdt.pojavlaunch.fragments.ProfileEditorFragment; +import net.kdt.pojavlaunch.profiles.ProfileAdapterExtra; import fr.spse.extended_view.ExtendedTextView; @@ -36,6 +39,8 @@ import fr.spse.extended_view.ExtendedTextView; * dropdown popup view with a custom direction. */ public class mcVersionSpinner extends ExtendedTextView { + private static final int VERSION_SPINNER_PROFILE_CREATE = 0; + private static final int VERSION_SPINNER_PROFILE_CREATE_MODDED = 1; public mcVersionSpinner(@NonNull Context context) { super(context); init(); @@ -52,8 +57,15 @@ public class mcVersionSpinner extends ExtendedTextView { /* The class is in charge of displaying its own list with adapter content being known in advance */ private ListView mListView = null; private PopupWindow mPopupWindow = null; - private final ProfileAdapter mProfileAdapter = new ProfileAdapter(getContext(), true); - private int mSelectedProfilePosition; + private Object mPopupAnimation; + private final ProfileAdapter mProfileAdapter = new ProfileAdapter(getContext(), new ProfileAdapterExtra[]{ + new ProfileAdapterExtra(VERSION_SPINNER_PROFILE_CREATE, + R.string.create_profile, + ResourcesCompat.getDrawable(getResources(), R.drawable.ic_add, null)), + new ProfileAdapterExtra(VERSION_SPINNER_PROFILE_CREATE_MODDED, + R.string.create_profile_modded, + ResourcesCompat.getDrawable(getResources(), R.drawable.ic_add_modded, null)) + }); /** Set the selection AND saves it as a shared preference */ @@ -63,11 +75,9 @@ public class mcVersionSpinner extends ExtendedTextView { .putString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE, mProfileAdapter.getItem(position).toString()) .apply(); - if(mPopupWindow != null) mPopupWindow.dismiss(); } public void setSelection(int position){ - mSelectedProfilePosition = position; if(mListView != null) mListView.setSelection(position); mProfileAdapter.setViewProfile(this, (String) mProfileAdapter.getItem(position), false); } @@ -115,13 +125,24 @@ public class mcVersionSpinner extends ExtendedTextView { mListView = (ListView) inflate(getContext(), R.layout.spinner_mc_version, null); mListView.setAdapter(mProfileAdapter); mListView.setOnItemClickListener((parent, view, position, id) -> { - if(position == mProfileAdapter.getCount() - 1){ - mPopupWindow.dismiss(); - Tools.swapFragment((FragmentActivity) getContext(), ProfileEditorFragment.class, - ProfileEditorFragment.TAG, true, new Bundle(1)); - return; + Object item = mProfileAdapter.getItem(position); + if(item instanceof String) { + hidePopup(true); + setProfileSelection(position); + }else if(item instanceof ProfileAdapterExtra) { + hidePopup(false); + ProfileAdapterExtra extra = (ProfileAdapterExtra) item; + switch (extra.id) { + case VERSION_SPINNER_PROFILE_CREATE: + Tools.swapFragment((FragmentActivity) getContext(), ProfileEditorFragment.class, + ProfileEditorFragment.TAG, true, new Bundle(1)); + break; + case VERSION_SPINNER_PROFILE_CREATE_MODDED: + Tools.swapFragment((FragmentActivity) getContext(), ModdedProfileSelectFragment.class, + ModdedProfileSelectFragment.TAG, true, null); + break; + } } - setProfileSelection(position); }); mPopupWindow = new PopupWindow(mListView, MATCH_PARENT, getContext().getResources().getDimensionPixelOffset(R.dimen._184sdp)); @@ -142,14 +163,26 @@ public class mcVersionSpinner extends ExtendedTextView { // Custom animation, nice slide in if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ - Slide transition = new Slide(Gravity.BOTTOM); - mPopupWindow.setEnterTransition(transition); - mPopupWindow.setExitTransition(transition); + mPopupAnimation = new Slide(Gravity.BOTTOM); + mPopupWindow.setEnterTransition((Transition) mPopupAnimation); + mPopupWindow.setExitTransition((Transition) mPopupAnimation); + } + } + + private void hidePopup(boolean animate) { + if(mPopupWindow == null) return; + if(!animate && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + mPopupWindow.setEnterTransition(null); + mPopupWindow.setExitTransition(null); + mPopupWindow.dismiss(); + mPopupWindow.setEnterTransition((Transition) mPopupAnimation); + mPopupWindow.setExitTransition((Transition) mPopupAnimation); + }else { + mPopupWindow.dismiss(); } } public ProfileAdapter getProfileAdapter() { return mProfileAdapter; } - } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ModdedProfileSelectFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ModdedProfileSelectFragment.java new file mode 100644 index 000000000..1c84a670f --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ModdedProfileSelectFragment.java @@ -0,0 +1,27 @@ +package net.kdt.pojavlaunch.fragments; + +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import net.kdt.pojavlaunch.R; +import net.kdt.pojavlaunch.Tools; + +public class ModdedProfileSelectFragment extends Fragment { + public static final String TAG = "ModdedProfileSelectFragment"; + public ModdedProfileSelectFragment() { + super(R.layout.fragment_mod_profile); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + view.findViewById(R.id.modded_profile_fabric).setOnClickListener((v)-> + Tools.swapFragment(requireActivity(), FabricInstallFragment.class, FabricInstallFragment.TAG, false, null)); + view.findViewById(R.id.modded_profile_forge).setOnClickListener((v)-> + Tools.swapFragment(requireActivity(), ForgeInstallFragment.class, ForgeInstallFragment.TAG, false, null)); + } +} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileEditorFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileEditorFragment.java index 85545cb53..5df28efa7 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileEditorFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileEditorFragment.java @@ -1,7 +1,5 @@ package net.kdt.pojavlaunch.fragments; -import static net.kdt.pojavlaunch.profiles.ProfileAdapter.CREATE_PROFILE_MAGIC; - import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; @@ -157,7 +155,7 @@ public class ProfileEditorFragment extends Fragment { private MinecraftProfile getProfile(@NonNull String profile){ MinecraftProfile minecraftProfile; - if(getArguments() == null && !profile.equals(CREATE_PROFILE_MAGIC)) { + if(getArguments() == null) { minecraftProfile = new MinecraftProfile(LauncherProfiles.mainProfileJson.profiles.get(profile)); mProfileKey = profile; }else{ diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapter.java index a9b719441..a3a9266da 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapter.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapter.java @@ -29,25 +29,17 @@ import fr.spse.extended_view.ExtendedTextView; */ public class ProfileAdapter extends BaseAdapter { private Map mProfiles; - public static final String CREATE_PROFILE_MAGIC = "___extra____profile-create"; private final MinecraftProfile dummy = new MinecraftProfile(); - private MinecraftProfile mCreateProfile; private List mProfileList; + private final ProfileAdapterExtra[] mExtraEntires; - public ProfileAdapter(Context context, boolean enableCreateButton) { + public ProfileAdapter(Context context, ProfileAdapterExtra[] extraEntries) { ProfileIconCache.initDefault(context); LauncherProfiles.update(); mProfiles = new HashMap<>(LauncherProfiles.mainProfileJson.profiles); - if(enableCreateButton) { - mCreateProfile = new MinecraftProfile(); - mCreateProfile.name = context.getString(R.string.create_profile); - mCreateProfile.lastVersionId = null; - } + if(extraEntries == null) mExtraEntires = new ProfileAdapterExtra[0]; + else mExtraEntires = extraEntries; mProfileList = new ArrayList<>(Arrays.asList(mProfiles.keySet().toArray(new String[0]))); - if(enableCreateButton) { - mProfileList.add(ProfileAdapter.CREATE_PROFILE_MAGIC); - mProfiles.put(CREATE_PROFILE_MAGIC, mCreateProfile); - } } /* * Gets how much profiles are loaded in the adapter right now @@ -55,7 +47,7 @@ public class ProfileAdapter extends BaseAdapter { */ @Override public int getCount() { - return mProfileList.size(); + return mProfileList.size() + mExtraEntires.length; } /* * Gets the profile at a given index @@ -64,12 +56,15 @@ public class ProfileAdapter extends BaseAdapter { */ @Override public Object getItem(int position) { - //safe since the second check in the and statement will be skipped if the first one fails - if(position < mProfileList.size() && mProfiles.containsKey(mProfileList.get(position))) { - return mProfileList.get(position); - }else{ - return null; + int profileListSize = mProfileList.size(); + int extraPosition = position - profileListSize; + if(position < profileListSize){ + String profileName = mProfileList.get(position); + if(mProfiles.containsKey(profileName)) return profileName; + }else if(extraPosition >= 0 && extraPosition < mExtraEntires.length) { + return mExtraEntires[extraPosition]; } + return null; } public int resolveProfileIndex(String name) { @@ -85,8 +80,6 @@ public class ProfileAdapter extends BaseAdapter { public void notifyDataSetChanged() { mProfiles = new HashMap<>(LauncherProfiles.mainProfileJson.profiles); mProfileList = new ArrayList<>(Arrays.asList(mProfiles.keySet().toArray(new String[0]))); - mProfileList.add(ProfileAdapter.CREATE_PROFILE_MAGIC); - mProfiles.put(CREATE_PROFILE_MAGIC, mCreateProfile); super.notifyDataSetChanged(); } @@ -94,7 +87,9 @@ public class ProfileAdapter extends BaseAdapter { public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if (v == null) v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_version_profile_layout,parent,false); - setViewProfile(v,mProfileList.get(position), true); + Object profileObject = getItem(position); + if(profileObject instanceof String) setViewProfile(v, (String) profileObject, true); + else if(profileObject instanceof ProfileAdapterExtra) setViewExtra(v, (ProfileAdapterExtra) profileObject); return v; } @@ -131,7 +126,12 @@ public class ProfileAdapter extends BaseAdapter { String selectedProfile = LauncherPreferences.DEFAULT_PREF.getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE,""); extendedTextView.setBackgroundColor(selectedProfile.equals(nm) ? ColorUtils.setAlphaComponent(Color.WHITE,60) : Color.TRANSPARENT); }else extendedTextView.setBackgroundColor(Color.TRANSPARENT); + } - + public void setViewExtra(View v, ProfileAdapterExtra extra) { + ExtendedTextView extendedTextView = (ExtendedTextView) v; + extendedTextView.setCompoundDrawablesRelative(extra.icon, null, extendedTextView.getCompoundsDrawables()[2], null); + extendedTextView.setText(extra.name); + extendedTextView.setBackgroundColor(Color.TRANSPARENT); } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapterExtra.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapterExtra.java new file mode 100644 index 000000000..b09d39b5c --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapterExtra.java @@ -0,0 +1,15 @@ +package net.kdt.pojavlaunch.profiles; + +import android.graphics.drawable.Drawable; + +public class ProfileAdapterExtra { + public final int id; + public final int name; + public final Drawable icon; + + public ProfileAdapterExtra(int id, int name, Drawable icon) { + this.id = id; + this.name = name; + this.icon = icon; + } +} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileIconCache.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileIconCache.java index 5cca10434..ccbd05470 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileIconCache.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileIconCache.java @@ -1,7 +1,5 @@ package net.kdt.pojavlaunch.profiles; -import static net.kdt.pojavlaunch.profiles.ProfileAdapter.CREATE_PROFILE_MAGIC; - import android.content.Context; import android.content.res.Resources; import android.graphics.BitmapFactory; @@ -46,21 +44,11 @@ public class ProfileIconCache { icon = ProfileIconCache.submitIcon(resources, profileName, b64Icon.substring(BASE64_PNG_HEADER.length())); }else{ Log.i("IconParser","Unsupported icon: "+b64Icon); - if(profileName.equals(CREATE_PROFILE_MAGIC)){ - icon = ProfileIconCache.pushAddProfileIcon(ResourcesCompat.getDrawable(resources, R.drawable.ic_add, null)); - }else{ - icon = ProfileIconCache.pushDefaultIcon(profileName); - } - + icon = ProfileIconCache.pushDefaultIcon(profileName); } return icon; } - public static Drawable pushAddProfileIcon(Drawable drawable){ - sIconCache.put(CREATE_PROFILE_MAGIC, drawable); - return drawable; - } - public static Drawable pushDefaultIcon(String key) { sIconCache.put(key, sDefaultIcon); diff --git a/app_pojavlauncher/src/main/res/drawable/ic_add_modded.xml b/app_pojavlauncher/src/main/res/drawable/ic_add_modded.xml new file mode 100644 index 000000000..70046c48f --- /dev/null +++ b/app_pojavlauncher/src/main/res/drawable/ic_add_modded.xml @@ -0,0 +1,5 @@ + + + diff --git a/app_pojavlauncher/src/main/res/layout/fragment_fabric_install.xml b/app_pojavlauncher/src/main/res/layout/fragment_fabric_install.xml index 50f2d1388..fa585fba0 100644 --- a/app_pojavlauncher/src/main/res/layout/fragment_fabric_install.xml +++ b/app_pojavlauncher/src/main/res/layout/fragment_fabric_install.xml @@ -1,35 +1,35 @@ + android:background="@color/background_app" + android:paddingHorizontal="@dimen/fragment_padding_medium"> + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toBottomOf="@+id/fabric_installer_loader_ver_spinner" + tools:layout_editor_absoluteX="13dp"> @@ -73,31 +73,27 @@ android:id="@+id/fabric_installer_game_version" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginTop="8dp" android:text="@string/fabric_dl_game_version" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/fabric_installer_retry_layout" /> + app:layout_constraintBottom_toTopOf="@+id/fabric_installer_version_select_label" + app:layout_constraintStart_toStartOf="@+id/fabric_installer_version_select_label" /> + app:layout_constraintTop_toBottomOf="@+id/fabric_installer_retry_layout" />