diff --git a/catroid/src/main/java/org/catrobat/catroid/ui/UiUtils.java b/catroid/src/main/java/org/catrobat/catroid/ui/UiUtils.java index be08d7786c6..6f595c517d0 100644 --- a/catroid/src/main/java/org/catrobat/catroid/ui/UiUtils.java +++ b/catroid/src/main/java/org/catrobat/catroid/ui/UiUtils.java @@ -1,6 +1,6 @@ /* * Catroid: An on-device visual programming system for Android devices - * Copyright (C) 2010-2022 The Catrobat Team + * Copyright (C) 2010-2024 The Catrobat Team * (<http://developer.catrobat.org/credits>) * * This program is free software: you can redistribute it and/or modify @@ -27,6 +27,7 @@ import android.content.Context; import android.content.ContextWrapper; import android.os.Build; +import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -164,4 +165,35 @@ public View getView(int position, @Nullable View convertView, @NonNull ViewGroup } }; } + + public static ArrayAdapter getAlertDialogAdapterForTextWithIcons(Activity activity, Context context, List<Pair<String, Integer>> items) { + return new ArrayAdapter<Pair<String, Integer>>(context, android.R.layout.simple_list_item_1, items) { + TextView item; + + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + final LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + if (convertView == null) { + convertView = inflater.inflate(R.layout.dialog_item_with_icon, parent, false); + item = (TextView) convertView.findViewById(R.id.item_text); + convertView.setTag(item); + } else { + item = (TextView) convertView.getTag(); + } + + item.setText(items.get(position).first); + + if (activity.getWindow().getDecorView().getLayoutDirection() == View.LAYOUT_DIRECTION_LTR) { + item.setCompoundDrawablesWithIntrinsicBounds(items.get(position).second, 0, 0, + 0); + } else { + item.setCompoundDrawablesWithIntrinsicBounds(0, 0, items.get(position).second, 0); + } + + return convertView; + } + }; + } } diff --git a/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/backpack/BackpackRecyclerViewFragment.java b/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/backpack/BackpackRecyclerViewFragment.java index 8dd3d3553f7..a79bd9c944c 100644 --- a/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/backpack/BackpackRecyclerViewFragment.java +++ b/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/backpack/BackpackRecyclerViewFragment.java @@ -1,6 +1,6 @@ /* * Catroid: An on-device visual programming system for Android devices - * Copyright (C) 2010-2022 The Catrobat Team + * Copyright (C) 2010-2024 The Catrobat Team * (<http://developer.catrobat.org/credits>) * * This program is free software: you can redistribute it and/or modify @@ -26,6 +26,7 @@ import android.content.DialogInterface; import android.os.Bundle; import android.preference.PreferenceManager; +import android.util.Pair; import android.view.ActionMode; import android.view.LayoutInflater; import android.view.Menu; @@ -33,7 +34,9 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ListAdapter; +import android.widget.ListView; import android.widget.PopupMenu; +import android.widget.TextView; import org.catrobat.catroid.R; import org.catrobat.catroid.ui.UiUtils; @@ -47,8 +50,10 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Objects; import androidx.annotation.IntDef; import androidx.annotation.PluralsRes; @@ -57,6 +62,8 @@ import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.RecyclerView; +import static org.catrobat.catroid.ui.UiUtils.getAlertDialogAdapterForTextWithIcons; + public abstract class BackpackRecyclerViewFragment<T> extends Fragment implements ActionMode.Callback, RVAdapter.SelectionListener, @@ -292,28 +299,41 @@ public void onItemClick(final T item, MultiSelectionManager selectionManager) { return; } - List<Integer> options = new ArrayList<>(); - options.add(R.string.unpack); - options.add(R.string.delete); - List<String> names = new ArrayList<>(); - for (Integer option: options) { - names.add(getString(option)); - } - ListAdapter arrayAdapter = UiUtils.getAlertDialogAdapterForMenuIcons(options, - names, requireContext(), requireActivity()); - - new AlertDialog.Builder(requireContext()) - .setTitle(getItemName(item)) - .setAdapter(arrayAdapter, (dialog, which) -> { - switch (which) { - case 0: - unpackItems(new ArrayList<>(Collections.singletonList(item))); - break; - case 1: - showDeleteAlert(new ArrayList<>(Collections.singletonList(item))); - } - }) - .show(); + List<Pair<String, Integer>> items = Arrays.asList( + new Pair<>(getString(R.string.unpack), R.drawable.ic_logout), + new Pair<>(getString(R.string.delete), R.drawable.ic_delete) + ); + + LayoutInflater inflater = LayoutInflater.from(requireContext()); + View customDialogView = inflater.inflate(R.layout.dialog_backpack_custom_alert, null); + ListAdapter listAdapter = getAlertDialogAdapterForTextWithIcons(requireActivity(), + requireContext(), items); + + AlertDialog dialog = new AlertDialog.Builder(requireContext()) + .setView(customDialogView) + .create(); + Objects.requireNonNull(dialog.getWindow()) + .setBackgroundDrawableResource(R.drawable.backpack_background_round); + + TextView textView = customDialogView.findViewById(R.id.backpack_dialog_title); + textView.setText(getItemName(item)); + + ListView listView = customDialogView.findViewById(R.id.backpack_item_list); + listView.setAdapter(listAdapter); + listView.setOnItemClickListener((parent, view, position, id) -> { + switch (position) { + case 0: + unpackItems(new ArrayList<>(Collections.singletonList(item))); + break; + case 1: + showDeleteAlert(new ArrayList<>(Collections.singletonList(item))); + break; + } + + dialog.dismiss(); + }); + + dialog.show(); } public void setShowProgressBar(boolean show) { diff --git a/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/RecyclerViewFragment.java b/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/RecyclerViewFragment.java index 8b4a895de33..d83ff2a7bfa 100644 --- a/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/RecyclerViewFragment.java +++ b/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/RecyclerViewFragment.java @@ -1,6 +1,6 @@ /* * Catroid: An on-device visual programming system for Android devices - * Copyright (C) 2010-2022 The Catrobat Team + * Copyright (C) 2010-2024 The Catrobat Team * (<http://developer.catrobat.org/credits>) * * This program is free software: you can redistribute it and/or modify @@ -27,12 +27,15 @@ import android.os.Bundle; import android.preference.PreferenceManager; import android.util.Log; +import android.util.Pair; import android.view.ActionMode; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.ListAdapter; +import android.widget.ListView; import android.widget.TextView; import org.catrobat.catroid.R; @@ -54,7 +57,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Arrays; import java.util.List; +import java.util.Objects; import androidx.annotation.IntDef; import androidx.annotation.NonNull; @@ -66,6 +71,7 @@ import androidx.recyclerview.widget.RecyclerView; import static org.catrobat.catroid.common.SharedPreferenceKeys.SORT_PROJECTS_PREFERENCE_KEY; +import static org.catrobat.catroid.ui.UiUtils.getAlertDialogAdapterForTextWithIcons; public abstract class RecyclerViewFragment<T extends Nameable> extends Fragment implements ActionMode.Callback, @@ -477,19 +483,38 @@ public void notifyDataSetChanged() { } protected void showBackpackModeChooser() { - CharSequence[] items = new CharSequence[] {getString(R.string.pack), getString(R.string.unpack)}; - new AlertDialog.Builder(requireContext()) - .setTitle(R.string.backpack_title) - .setItems(items, (dialog, which) -> { - switch (which) { - case 0: - startActionMode(BACKPACK); - break; - case 1: - switchToBackpack(); - } - }) - .show(); + List<Pair<String, Integer>> items = Arrays.asList( + new Pair<>(getString(R.string.pack), R.drawable.ic_login), + new Pair<>(getString(R.string.unpack), R.drawable.ic_logout) + ); + + LayoutInflater inflater = LayoutInflater.from(requireContext()); + View customDialogView = inflater.inflate(R.layout.dialog_backpack_custom_alert, null); + ListAdapter listAdapter = getAlertDialogAdapterForTextWithIcons(requireActivity(), + requireContext(), items); + + AlertDialog dialog = new AlertDialog.Builder(requireContext()) + .setView(customDialogView) + .create(); + Objects.requireNonNull(dialog.getWindow()) + .setBackgroundDrawableResource(R.drawable.backpack_background_round); + + ListView listView = customDialogView.findViewById(R.id.backpack_item_list); + listView.setAdapter(listAdapter); + listView.setOnItemClickListener((parent, view, position, id) -> { + switch (position) { + case 0: + startActionMode(BACKPACK); + break; + case 1: + switchToBackpack(); + break; + } + + dialog.dismiss(); + }); + + dialog.show(); } protected abstract void packItems(List<T> selectedItems); diff --git a/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/ScriptFragment.java b/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/ScriptFragment.java index 80223f287a5..73932239e03 100644 --- a/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/ScriptFragment.java +++ b/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/ScriptFragment.java @@ -1,6 +1,6 @@ /* * Catroid: An on-device visual programming system for Android devices - * Copyright (C) 2010-2023 The Catrobat Team + * Copyright (C) 2010-2024 The Catrobat Team * (<http://developer.catrobat.org/credits>) * * This program is free software: you can redistribute it and/or modify @@ -29,6 +29,7 @@ import android.os.Bundle; import android.os.Parcelable; import android.util.Log; +import android.util.Pair; import android.view.ActionMode; import android.view.LayoutInflater; import android.view.Menu; @@ -37,7 +38,10 @@ import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; +import android.widget.ArrayAdapter; import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.TextView; import org.catrobat.catroid.BuildConfig; import org.catrobat.catroid.ProjectManager; @@ -92,7 +96,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.UUID; import androidx.annotation.IntDef; @@ -107,6 +113,7 @@ import static org.catrobat.catroid.common.Constants.CODE_XML_FILE_NAME; import static org.catrobat.catroid.common.Constants.UNDO_CODE_XML_FILE_NAME; +import static org.catrobat.catroid.ui.UiUtils.getAlertDialogAdapterForTextWithIcons; public class ScriptFragment extends ListFragment implements ActionMode.Callback, @@ -847,19 +854,38 @@ public boolean onBrickLongClick(Brick brick, int position) { } private void showBackpackModeChooser() { - CharSequence[] items = new CharSequence[] {getString(R.string.pack), getString(R.string.unpack)}; - new AlertDialog.Builder(getContext()) - .setTitle(R.string.backpack_title) - .setItems(items, (dialog, which) -> { - switch (which) { - case 0: - startActionMode(BACKPACK); - break; - case 1: - switchToBackpack(); - } - }) - .show(); + List<Pair<String, Integer>> items = Arrays.asList( + new Pair<>(getString(R.string.pack), R.drawable.ic_login), + new Pair<>(getString(R.string.unpack), R.drawable.ic_logout) + ); + + LayoutInflater inflater = LayoutInflater.from(requireContext()); + View customDialogView = inflater.inflate(R.layout.dialog_backpack_custom_alert, null); + ListAdapter listAdapter = getAlertDialogAdapterForTextWithIcons(requireActivity(), + requireContext(), items); + + AlertDialog dialog = new AlertDialog.Builder(requireContext()) + .setView(customDialogView) + .create(); + Objects.requireNonNull(dialog.getWindow()) + .setBackgroundDrawableResource(R.drawable.backpack_background_round); + + ListView listView = customDialogView.findViewById(R.id.backpack_item_list); + listView.setAdapter(listAdapter); + listView.setOnItemClickListener((parent, view, position, id) -> { + switch (position) { + case 0: + startActionMode(BACKPACK); + break; + case 1: + switchToBackpack(); + break; + } + + dialog.dismiss(); + }); + + dialog.show(); } public void showNewScriptGroupAlert(List<Brick> selectedBricks) { diff --git a/catroid/src/main/res/drawable/backpack_background_round.xml b/catroid/src/main/res/drawable/backpack_background_round.xml new file mode 100644 index 00000000000..1ba16228456 --- /dev/null +++ b/catroid/src/main/res/drawable/backpack_background_round.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Catroid: An on-device visual programming system for Android devices + ~ Copyright (C) 2010-2024 The Catrobat Team + ~ (<http://developer.catrobat.org/credits>) + ~ + ~ This program is free software: you can redistribute it and/or modify + ~ it under the terms of the GNU Affero General Public License as + ~ published by the Free Software Foundation, either version 3 of the + ~ License, or (at your option) any later version. + ~ + ~ An additional term exception under section 7 of the GNU Affero + ~ General Public License, version 3, is available at + ~ http://developer.catrobat.org/license_additional_term + ~ + ~ This program is distributed in the hope that it will be useful, + ~ but WITHOUT ANY WARRANTY; without even the implied warranty of + ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ~ GNU Affero General Public License for more details. + ~ + ~ You should have received a copy of the GNU Affero General Public License + ~ along with this program. If not, see <http://www.gnu.org/licenses/>. + --> + +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <corners android:radius="30dp" /> + <solid android:color="@color/backpack_background" /> +</shape> \ No newline at end of file diff --git a/catroid/src/main/res/layout/dialog_backpack_custom_alert.xml b/catroid/src/main/res/layout/dialog_backpack_custom_alert.xml new file mode 100644 index 00000000000..59d4cf11bce --- /dev/null +++ b/catroid/src/main/res/layout/dialog_backpack_custom_alert.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Catroid: An on-device visual programming system for Android devices + ~ Copyright (C) 2010-2024 The Catrobat Team + ~ (<http://developer.catrobat.org/credits>) + ~ + ~ This program is free software: you can redistribute it and/or modify + ~ it under the terms of the GNU Affero General Public License as + ~ published by the Free Software Foundation, either version 3 of the + ~ License, or (at your option) any later version. + ~ + ~ An additional term exception under section 7 of the GNU Affero + ~ General Public License, version 3, is available at + ~ http://developer.catrobat.org/license_additional_term + ~ + ~ This program is distributed in the hope that it will be useful, + ~ but WITHOUT ANY WARRANTY; without even the implied warranty of + ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ~ GNU Affero General Public License for more details. + ~ + ~ You should have received a copy of the GNU Affero General Public License + ~ along with this program. If not, see <http://www.gnu.org/licenses/>. + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:paddingStart="5dp" + android:paddingEnd="5dp"> + + <TextView + android:id="@+id/backpack_dialog_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/backpack_title" + android:textAppearance="?android:textAppearanceLarge" + android:textSize="20sp" + android:padding="16dp"/> + + <View + android:id="@+id/backpack_title_divider" + android:layout_width="match_parent" + android:layout_height="2dp" + android:background="@color/accent"/> + + <ListView + android:id="@+id/backpack_item_list" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:divider="@null" + android:padding="16dp"/> +</LinearLayout> \ No newline at end of file diff --git a/catroid/src/main/res/layout/dialog_item_with_icon.xml b/catroid/src/main/res/layout/dialog_item_with_icon.xml new file mode 100644 index 00000000000..e37d24ae34b --- /dev/null +++ b/catroid/src/main/res/layout/dialog_item_with_icon.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Catroid: An on-device visual programming system for Android devices + ~ Copyright (C) 2010-2024 The Catrobat Team + ~ (<http://developer.catrobat.org/credits>) + ~ + ~ This program is free software: you can redistribute it and/or modify + ~ it under the terms of the GNU Affero General Public License as + ~ published by the Free Software Foundation, either version 3 of the + ~ License, or (at your option) any later version. + ~ + ~ An additional term exception under section 7 of the GNU Affero + ~ General Public License, version 3, is available at + ~ http://developer.catrobat.org/license_additional_term + ~ + ~ This program is distributed in the hope that it will be useful, + ~ but WITHOUT ANY WARRANTY; without even the implied warranty of + ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ~ GNU Affero General Public License for more details. + ~ + ~ You should have received a copy of the GNU Affero General Public License + ~ along with this program. If not, see <http://www.gnu.org/licenses/>. + --> + +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/item_text" + android:text="" + android:textAppearance="?android:textAppearanceLarge" + android:textSize="16sp" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingBottom="12dp" + android:paddingTop="12dp" + android:paddingStart="0dp" + android:paddingEnd="0dp" + android:drawablePadding="10dp"/> \ No newline at end of file diff --git a/catroid/src/main/res/values/colors.xml b/catroid/src/main/res/values/colors.xml index 76aeee9ddbc..668c9c243f7 100644 --- a/catroid/src/main/res/values/colors.xml +++ b/catroid/src/main/res/values/colors.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <!-- ~ Catroid: An on-device visual programming system for Android devices - ~ Copyright (C) 2010-2023 The Catrobat Team + ~ Copyright (C) 2010-2024 The Catrobat Team ~ (<http://developer.catrobat.org/credits>) ~ ~ This program is free software: you can redistribute it and/or modify @@ -42,6 +42,7 @@ <color name="advertising_button_background">#00ACC1</color> <color name="button_bottom_bar">#00475E</color> <color name="button_border_top">#4D7F8F</color> + <color name="backpack_background">#424242</color> <!-- Accent Colors --> <color name="accent">#A8DFF4</color>