diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageImmunitiesFragment.java b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageImmunitiesFragment.java new file mode 100644 index 0000000..58bf169 --- /dev/null +++ b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageImmunitiesFragment.java @@ -0,0 +1,92 @@ +package com.majinnaibu.monstercards.ui.editmonster; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.lifecycle.ViewModelProvider; +import androidx.navigation.NavBackStackEntry; +import androidx.navigation.NavController; +import androidx.navigation.NavDirections; +import androidx.navigation.Navigation; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.majinnaibu.monstercards.R; +import com.majinnaibu.monstercards.ui.shared.MCFragment; +import com.majinnaibu.monstercards.ui.shared.SwipeToDeleteCallback; +import com.majinnaibu.monstercards.utils.Logger; + +/** + * A fragment representing a list of Items. + */ +public class EditDamageImmunitiesFragment extends MCFragment { + private EditMonsterViewModel mViewModel; + private ViewHolder mHolder; + + private void navigateToEditDamageImmunity(String damageImmunity) { + NavDirections action = EditDamageImmunitiesFragmentDirections.actionEditDamageImmunitiesFragmentToEditDamageImmunityFragment(damageImmunity); + View view = getView(); + assert view != null; + Navigation.findNavController(view).navigate(action); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment); + NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation); + mViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class); + View root = inflater.inflate(R.layout.fragment_edit_damage_immunities_list, container, false); + mHolder = new ViewHolder(root); + setupRecyclerView(mHolder.list); + setupAddDamageImmunityButton(mHolder.addDamageImmunity); + return root; + } + + private void setupRecyclerView(@NonNull RecyclerView recyclerView) { + Context context = requireContext(); + LinearLayoutManager layoutManager = new LinearLayoutManager(context); + recyclerView.setLayoutManager(layoutManager); + + mViewModel.getDamageImmunities().observe(getViewLifecycleOwner(), damageImmunities -> { + EditDamageImmunitiesRecyclerViewAdapter adapter = new EditDamageImmunitiesRecyclerViewAdapter(mViewModel.getDamageImmunitiesArray(), damageImmunity -> { + if (damageImmunity != null) { + navigateToEditDamageImmunity(damageImmunity); + } else { + Logger.logError("Can't navigate to EditDamageImmunity with a null damageImmunity"); + } + }); + recyclerView.setAdapter(adapter); + }); + + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context, layoutManager.getOrientation()); + recyclerView.addItemDecoration(dividerItemDecoration); + + ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SwipeToDeleteCallback(context, mViewModel::removeDamageImmunity)); + itemTouchHelper.attachToRecyclerView(recyclerView); + } + + private void setupAddDamageImmunityButton(@NonNull FloatingActionButton fab) { + fab.setOnClickListener(view -> { + String newDamageImmunity = mViewModel.addNewDamageImmunity(); + navigateToEditDamageImmunity(newDamageImmunity); + }); + } + + private static class ViewHolder { + RecyclerView list; + FloatingActionButton addDamageImmunity; + + ViewHolder(View root) { + list = root.findViewById(R.id.list); + addDamageImmunity = root.findViewById(R.id.add_damage_type); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageImmunitiesRecyclerViewAdapter.java b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageImmunitiesRecyclerViewAdapter.java new file mode 100644 index 0000000..f70a6b8 --- /dev/null +++ b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageImmunitiesRecyclerViewAdapter.java @@ -0,0 +1,69 @@ +package com.majinnaibu.monstercards.ui.editmonster; + +import android.view.LayoutInflater; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.recyclerview.widget.RecyclerView; + +import com.majinnaibu.monstercards.databinding.FragmentEditDamageImmunitiesListItemBinding; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * x + * {@link RecyclerView.Adapter} that can display a {@link String}. + */ +public class EditDamageImmunitiesRecyclerViewAdapter extends RecyclerView.Adapter { + private final List mValues; + private final ItemCallback mOnClick; + + public EditDamageImmunitiesRecyclerViewAdapter(List items, ItemCallback onClick) { + mValues = items; + mOnClick = onClick; + } + + @NotNull + @Override + public ViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) { + return new ViewHolder(FragmentEditDamageImmunitiesListItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(final ViewHolder holder, int position) { + holder.mItem = mValues.get(position); + holder.mContentView.setText(mValues.get(position)); + holder.itemView.setOnClickListener(v -> { + if (mOnClick != null) { + mOnClick.onItemCallback(holder.mItem); + } + }); + } + + @Override + public int getItemCount() { + return mValues.size(); + } + + public interface ItemCallback { + void onItemCallback(String sense); + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + public final TextView mContentView; + public String mItem; + + public ViewHolder(FragmentEditDamageImmunitiesListItemBinding binding) { + super(binding.getRoot()); + mContentView = binding.content; + } + + @NotNull + @Override + public String toString() { + return super.toString() + " '" + mContentView.getText() + "'"; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageImmunityFragment.java b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageImmunityFragment.java new file mode 100644 index 0000000..e10a2b8 --- /dev/null +++ b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageImmunityFragment.java @@ -0,0 +1,76 @@ +package com.majinnaibu.monstercards.ui.editmonster; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; + +import androidx.activity.OnBackPressedCallback; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.ViewModelProvider; +import androidx.navigation.NavBackStackEntry; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; + +import com.majinnaibu.monstercards.R; +import com.majinnaibu.monstercards.ui.shared.MCFragment; +import com.majinnaibu.monstercards.utils.Logger; +import com.majinnaibu.monstercards.utils.TextChangedListener; + +public class EditDamageImmunityFragment extends MCFragment { + private EditMonsterViewModel mEditMonsterViewModel; + private EditStringViewModel mViewModel; + private EditDamageImmunityFragment.ViewHolder mHolder; + private String mOldDamageImmunity; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + mViewModel = new ViewModelProvider(this).get(EditStringViewModel.class); + if (getArguments() != null) { + EditDamageImmunityFragmentArgs args = EditDamageImmunityFragmentArgs.fromBundle(getArguments()); + mOldDamageImmunity = args.getDamageType(); + mViewModel.resetValue(mOldDamageImmunity); + } else { + Logger.logWTF("EditDamageImmunityFragment needs arguments"); + mOldDamageImmunity = null; + } + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment); + NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation); + mEditMonsterViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class); + + View root = inflater.inflate(R.layout.fragment_edit_damage_immunity, container, false); + + mHolder = new EditDamageImmunityFragment.ViewHolder(root); + + mHolder.value.setText(mViewModel.getValueAsString()); + mHolder.value.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setValue(s.toString()))); + + requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + if (mViewModel.hasChanges()) { + mEditMonsterViewModel.replaceDamageImmunity(mOldDamageImmunity, mViewModel.getValueAsString()); + } + Navigation.findNavController(requireView()).navigateUp(); + } + }); + + return root; + } + + private static class ViewHolder { + EditText value; + + ViewHolder(View root) { + value = root.findViewById(R.id.value); + } + } +} diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageVulnerabilitiesFragment.java b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageVulnerabilitiesFragment.java new file mode 100644 index 0000000..9ea643b --- /dev/null +++ b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageVulnerabilitiesFragment.java @@ -0,0 +1,92 @@ +package com.majinnaibu.monstercards.ui.editmonster; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.lifecycle.ViewModelProvider; +import androidx.navigation.NavBackStackEntry; +import androidx.navigation.NavController; +import androidx.navigation.NavDirections; +import androidx.navigation.Navigation; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.majinnaibu.monstercards.R; +import com.majinnaibu.monstercards.ui.shared.MCFragment; +import com.majinnaibu.monstercards.ui.shared.SwipeToDeleteCallback; +import com.majinnaibu.monstercards.utils.Logger; + +/** + * A fragment representing a list of Items. + */ +public class EditDamageVulnerabilitiesFragment extends MCFragment { + private EditMonsterViewModel mViewModel; + private ViewHolder mHolder; + + private void navigateToEditDamageVulnerability(String damageVulnerability) { + NavDirections action = EditDamageVulnerabilitiesFragmentDirections.actionEditDamageVulnerabilitiesFragmentToEditDamageVulnerabilityFragment(damageVulnerability); + View view = getView(); + assert view != null; + Navigation.findNavController(view).navigate(action); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment); + NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation); + mViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class); + View root = inflater.inflate(R.layout.fragment_edit_damage_vulnerabilities_list, container, false); + mHolder = new ViewHolder(root); + setupRecyclerView(mHolder.list); + setupAddDamageVulnerabilityButton(mHolder.addDamageVulnerability); + return root; + } + + private void setupRecyclerView(@NonNull RecyclerView recyclerView) { + Context context = requireContext(); + LinearLayoutManager layoutManager = new LinearLayoutManager(context); + recyclerView.setLayoutManager(layoutManager); + + mViewModel.getDamageVulnerabilities().observe(getViewLifecycleOwner(), damageVulnerabilities -> { + EditDamageVulnerabilitiesRecyclerViewAdapter adapter = new EditDamageVulnerabilitiesRecyclerViewAdapter(mViewModel.getDamageVulnerabilitiesArray(), damageVulnerability -> { + if (damageVulnerability != null) { + navigateToEditDamageVulnerability(damageVulnerability); + } else { + Logger.logError("Can't navigate to EditDamageVulnerability with a null damageVulnerability"); + } + }); + recyclerView.setAdapter(adapter); + }); + + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context, layoutManager.getOrientation()); + recyclerView.addItemDecoration(dividerItemDecoration); + + ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SwipeToDeleteCallback(context, mViewModel::removeDamageVulnerability)); + itemTouchHelper.attachToRecyclerView(recyclerView); + } + + private void setupAddDamageVulnerabilityButton(@NonNull FloatingActionButton fab) { + fab.setOnClickListener(view -> { + String newDamageVulnerability = mViewModel.addNewDamageVulnerability(); + navigateToEditDamageVulnerability(newDamageVulnerability); + }); + } + + private static class ViewHolder { + RecyclerView list; + FloatingActionButton addDamageVulnerability; + + ViewHolder(View root) { + list = root.findViewById(R.id.list); + addDamageVulnerability = root.findViewById(R.id.add_damage_type); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageVulnerabilitiesRecyclerViewAdapter.java b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageVulnerabilitiesRecyclerViewAdapter.java new file mode 100644 index 0000000..c59d2d7 --- /dev/null +++ b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageVulnerabilitiesRecyclerViewAdapter.java @@ -0,0 +1,69 @@ +package com.majinnaibu.monstercards.ui.editmonster; + +import android.view.LayoutInflater; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.recyclerview.widget.RecyclerView; + +import com.majinnaibu.monstercards.databinding.FragmentEditDamageVulnerabilitiesListItemBinding; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * x + * {@link RecyclerView.Adapter} that can display a {@link String}. + */ +public class EditDamageVulnerabilitiesRecyclerViewAdapter extends RecyclerView.Adapter { + private final List mValues; + private final ItemCallback mOnClick; + + public EditDamageVulnerabilitiesRecyclerViewAdapter(List items, ItemCallback onClick) { + mValues = items; + mOnClick = onClick; + } + + @NotNull + @Override + public ViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) { + return new ViewHolder(FragmentEditDamageVulnerabilitiesListItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(final ViewHolder holder, int position) { + holder.mItem = mValues.get(position); + holder.mContentView.setText(mValues.get(position)); + holder.itemView.setOnClickListener(v -> { + if (mOnClick != null) { + mOnClick.onItemCallback(holder.mItem); + } + }); + } + + @Override + public int getItemCount() { + return mValues.size(); + } + + public interface ItemCallback { + void onItemCallback(String sense); + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + public final TextView mContentView; + public String mItem; + + public ViewHolder(FragmentEditDamageVulnerabilitiesListItemBinding binding) { + super(binding.getRoot()); + mContentView = binding.content; + } + + @NotNull + @Override + public String toString() { + return super.toString() + " '" + mContentView.getText() + "'"; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageVulnerabilityFragment.java b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageVulnerabilityFragment.java new file mode 100644 index 0000000..4ce8238 --- /dev/null +++ b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditDamageVulnerabilityFragment.java @@ -0,0 +1,76 @@ +package com.majinnaibu.monstercards.ui.editmonster; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; + +import androidx.activity.OnBackPressedCallback; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.ViewModelProvider; +import androidx.navigation.NavBackStackEntry; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; + +import com.majinnaibu.monstercards.R; +import com.majinnaibu.monstercards.ui.shared.MCFragment; +import com.majinnaibu.monstercards.utils.Logger; +import com.majinnaibu.monstercards.utils.TextChangedListener; + +public class EditDamageVulnerabilityFragment extends MCFragment { + private EditMonsterViewModel mEditMonsterViewModel; + private EditStringViewModel mViewModel; + private EditDamageVulnerabilityFragment.ViewHolder mHolder; + private String mOldDamageVulnerability; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + mViewModel = new ViewModelProvider(this).get(EditStringViewModel.class); + if (getArguments() != null) { + EditDamageVulnerabilityFragmentArgs args = EditDamageVulnerabilityFragmentArgs.fromBundle(getArguments()); + mOldDamageVulnerability = args.getDamageType(); + mViewModel.resetValue(mOldDamageVulnerability); + } else { + Logger.logWTF("EditDamageVulnerabilityFragment needs arguments"); + mOldDamageVulnerability = null; + } + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment); + NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation); + mEditMonsterViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class); + + View root = inflater.inflate(R.layout.fragment_edit_damage_vulnerability, container, false); + + mHolder = new EditDamageVulnerabilityFragment.ViewHolder(root); + + mHolder.value.setText(mViewModel.getValueAsString()); + mHolder.value.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setValue(s.toString()))); + + requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + if (mViewModel.hasChanges()) { + mEditMonsterViewModel.replaceDamageVulnerability(mOldDamageVulnerability, mViewModel.getValueAsString()); + } + Navigation.findNavController(requireView()).navigateUp(); + } + }); + + return root; + } + + private static class ViewHolder { + EditText value; + + ViewHolder(View root) { + value = root.findViewById(R.id.value); + } + } +} diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterFragment.java b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterFragment.java index 83d50b5..81d7db7 100644 --- a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterFragment.java +++ b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterFragment.java @@ -125,11 +125,21 @@ public class EditMonsterFragment extends MCFragment { Navigation.findNavController(requireView()).navigate(action); }); + mHolder.damageImmunities.setOnClickListener(v -> { + NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditDamageImmunitiesFragment(); + Navigation.findNavController(requireView()).navigate(action); + }); + mHolder.damageResistances.setOnClickListener(v -> { NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditDamageResistancesFragment(); Navigation.findNavController(requireView()).navigate(action); }); + mHolder.damageVulnerabilities.setOnClickListener(v -> { + NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditDamageVulnerabilitiesFragment(); + Navigation.findNavController(requireView()).navigate(action); + }); + requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { diff --git a/app/src/main/res/layout/fragment_edit_damage_immunities_list.xml b/app/src/main/res/layout/fragment_edit_damage_immunities_list.xml new file mode 100644 index 0000000..26b1fbd --- /dev/null +++ b/app/src/main/res/layout/fragment_edit_damage_immunities_list.xml @@ -0,0 +1,33 @@ + + + + + + + diff --git a/app/src/main/res/layout/fragment_edit_damage_immunities_list_item.xml b/app/src/main/res/layout/fragment_edit_damage_immunities_list_item.xml new file mode 100644 index 0000000..6e9049a --- /dev/null +++ b/app/src/main/res/layout/fragment_edit_damage_immunities_list_item.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_edit_damage_immunity.xml b/app/src/main/res/layout/fragment_edit_damage_immunity.xml new file mode 100644 index 0000000..a1456f2 --- /dev/null +++ b/app/src/main/res/layout/fragment_edit_damage_immunity.xml @@ -0,0 +1,17 @@ + + + + + diff --git a/app/src/main/res/layout/fragment_edit_damage_vulnerabilities_list.xml b/app/src/main/res/layout/fragment_edit_damage_vulnerabilities_list.xml new file mode 100644 index 0000000..26b1fbd --- /dev/null +++ b/app/src/main/res/layout/fragment_edit_damage_vulnerabilities_list.xml @@ -0,0 +1,33 @@ + + + + + + + diff --git a/app/src/main/res/layout/fragment_edit_damage_vulnerabilities_list_item.xml b/app/src/main/res/layout/fragment_edit_damage_vulnerabilities_list_item.xml new file mode 100644 index 0000000..6e9049a --- /dev/null +++ b/app/src/main/res/layout/fragment_edit_damage_vulnerabilities_list_item.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_edit_damage_vulnerability.xml b/app/src/main/res/layout/fragment_edit_damage_vulnerability.xml new file mode 100644 index 0000000..a1456f2 --- /dev/null +++ b/app/src/main/res/layout/fragment_edit_damage_vulnerability.xml @@ -0,0 +1,17 @@ + + + + + diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index 3873941..cfb1c4c 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -102,6 +102,12 @@ + + + + + + + + + + + + + +