From 8fd313e3dfbd2057c9bbb01a63158bd287d4f2e8 Mon Sep 17 00:00:00 2001 From: Tom Hicks Date: Mon, 31 May 2021 12:58:34 -0700 Subject: [PATCH] Adds saving throws editor. --- .../ui/editmonster/EditMonsterFragment.java | 37 ++++ .../ui/editmonster/EditMonsterViewModel.java | 182 ++++++++++++++++++ .../editmonster/EditSavingThrowsFragment.java | 95 +++++++++ app/src/main/res/layout/component_stepper.xml | 2 +- .../layout/fragment_edit_saving_throws.xml | 111 +++++++++++ .../main/res/navigation/mobile_navigation.xml | 8 + app/src/main/res/values/strings.xml | 5 +- 7 files changed, 436 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditSavingThrowsFragment.java create mode 100644 app/src/main/res/layout/fragment_edit_saving_throws.xml 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 98f25f3..51bb80a 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 @@ -109,6 +109,13 @@ public class EditMonsterFragment extends MCFragment { Navigation.findNavController(view).navigate(action); }); + mHolder.savingThrows.setOnClickListener(v -> { + NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditSavingThrowsFragment(); + View view = getView(); + assert view != null; + Navigation.findNavController(view).navigate(action); + }); + requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { @@ -162,12 +169,42 @@ public class EditMonsterFragment extends MCFragment { TextView armorButton; TextView speedButton; TextView abilityScoresButton; + TextView savingThrows; + TextView skills; + TextView conditionImmunities; + TextView damageImmunities; + TextView damageResistances; + TextView damageVulnerabilities; + TextView senses; + TextView languages; + TextView challengeRating; + TextView abilities; + TextView actions; + TextView reactions; + TextView legendaryActions; + TextView lairActions; + TextView regionalActions; ViewHolder(View root) { basicInfoButton = root.findViewById(R.id.basicInfo); armorButton = root.findViewById(R.id.armor); speedButton = root.findViewById(R.id.speed); abilityScoresButton = root.findViewById(R.id.abilityScores); + savingThrows = root.findViewById(R.id.savingThrows); + skills = root.findViewById(R.id.skills); + conditionImmunities = root.findViewById(R.id.conditionImmunities); + damageImmunities = root.findViewById(R.id.damageImmunities); + damageResistances = root.findViewById(R.id.damageResistances); + damageVulnerabilities = root.findViewById(R.id.damageVulnerabilities); + senses = root.findViewById(R.id.senses); + languages = root.findViewById(R.id.languages); + challengeRating = root.findViewById(R.id.challengeRating); + abilities = root.findViewById(R.id.abilities); + actions = root.findViewById(R.id.actions); + reactions = root.findViewById(R.id.reactions); + legendaryActions = root.findViewById(R.id.legendaryActions); + lairActions = root.findViewById(R.id.lairActions); + regionalActions = root.findViewById(R.id.regionalActions); } } } \ No newline at end of file diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterViewModel.java b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterViewModel.java index 08d3ea3..5f9b7b2 100644 --- a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterViewModel.java +++ b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterViewModel.java @@ -5,7 +5,9 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import com.majinnaibu.monstercards.data.enums.AdvantageType; import com.majinnaibu.monstercards.data.enums.ArmorType; +import com.majinnaibu.monstercards.data.enums.ProficiencyType; import com.majinnaibu.monstercards.helpers.StringHelper; import com.majinnaibu.monstercards.models.Monster; import com.majinnaibu.monstercards.utils.Logger; @@ -24,6 +26,18 @@ public class EditMonsterViewModel extends ViewModel { private final MutableLiveData mCanHover; private final MutableLiveData mHasCustomSpeed; private final MutableLiveData mArmorType; + private final MutableLiveData mStrengthProficiency; + private final MutableLiveData mStrengthAdvantage; + private final MutableLiveData mDexterityProficiency; + private final MutableLiveData mDexterityAdvantage; + private final MutableLiveData mConstitutionProficiency; + private final MutableLiveData mConstitutionAdvantage; + private final MutableLiveData mIntelligenceProficiency; + private final MutableLiveData mIntelligenceAdvantage; + private final MutableLiveData mWisdomProficiency; + private final MutableLiveData mWisdomAdvantage; + private final MutableLiveData mCharismaProficiency; + private final MutableLiveData mCharismaAdvantage; private final MutableLiveData mHitDice; private final MutableLiveData mNaturalArmorBonus; private final MutableLiveData mShieldBonus; @@ -81,6 +95,18 @@ public class EditMonsterViewModel extends ViewModel { mIntelligence = new MutableLiveData<>(10); mWisdom = new MutableLiveData<>(10); mCharisma = new MutableLiveData<>(10); + mStrengthProficiency = new MutableLiveData<>(ProficiencyType.NONE); + mStrengthAdvantage = new MutableLiveData<>(AdvantageType.NONE); + mDexterityProficiency = new MutableLiveData<>(ProficiencyType.NONE); + mDexterityAdvantage = new MutableLiveData<>(AdvantageType.NONE); + mConstitutionProficiency = new MutableLiveData<>(ProficiencyType.NONE); + mConstitutionAdvantage = new MutableLiveData<>(AdvantageType.NONE); + mIntelligenceProficiency = new MutableLiveData<>(ProficiencyType.NONE); + mIntelligenceAdvantage = new MutableLiveData<>(AdvantageType.NONE); + mWisdomProficiency = new MutableLiveData<>(ProficiencyType.NONE); + mWisdomAdvantage = new MutableLiveData<>(AdvantageType.NONE); + mCharismaProficiency = new MutableLiveData<>(ProficiencyType.NONE); + mCharismaAdvantage = new MutableLiveData<>(AdvantageType.NONE); // TODO: consider initializing this to true so all new monsters need saving mHasChanges = new MutableLiveData<>(false); @@ -116,6 +142,18 @@ public class EditMonsterViewModel extends ViewModel { mIntelligence.setValue(monster.intelligenceScore); mWisdom.setValue(monster.wisdomScore); mCharisma.setValue(monster.charismaScore); + mStrengthProficiency.setValue(monster.strengthSavingThrowProficiency); + mStrengthAdvantage.setValue(monster.strengthSavingThrowAdvantage); + mDexterityProficiency.setValue(monster.dexteritySavingThrowProficiency); + mDexterityAdvantage.setValue(monster.dexteritySavingThrowAdvantage); + mConstitutionProficiency.setValue(monster.constitutionSavingThrowProficiency); + mConstitutionAdvantage.setValue(monster.constitutionSavingThrowAdvantage); + mIntelligenceProficiency.setValue(monster.intelligenceSavingThrowProficiency); + mIntelligenceAdvantage.setValue(monster.intelligenceSavingThrowAdvantage); + mWisdomProficiency.setValue(monster.wisdomSavingThrowProficiency); + mWisdomAdvantage.setValue(monster.wisdomSavingThrowAdvantage); + mCharismaProficiency.setValue(monster.charismaSavingThrowProficiency); + mCharismaAdvantage.setValue(monster.charismaSavingThrowAdvantage); mHasChanges.setValue(false); } @@ -589,6 +627,138 @@ public class EditMonsterViewModel extends ViewModel { setCharisma(mCharisma.getValue() - 1); } + public LiveData getStrengthProficiency() { + return mStrengthProficiency; + } + + public void setStrengthProficiency(ProficiencyType proficiency) { + if (!Objects.equals(mStrengthProficiency.getValue(), proficiency)) { + mStrengthProficiency.setValue(proficiency); + mHasChanges.setValue(true); + } + } + + public LiveData getStrengthAdvantage() { + return mStrengthAdvantage; + } + + public void setStrengthAdvantage(AdvantageType advantage) { + if (!Objects.equals(mStrengthAdvantage.getValue(), advantage)) { + mStrengthAdvantage.setValue(advantage); + mHasChanges.setValue(true); + } + } + + public LiveData getDexterityProficiency() { + return mDexterityProficiency; + } + + public void setDexterityProficiency(ProficiencyType proficiency) { + if (!Objects.equals(mDexterityProficiency.getValue(), proficiency)) { + mDexterityProficiency.setValue(proficiency); + mHasChanges.setValue(true); + } + } + + public LiveData getDexterityAdvantage() { + return mDexterityAdvantage; + } + + public void setDexterityAdvantage(AdvantageType advantage) { + if (!Objects.equals(mDexterityAdvantage.getValue(), advantage)) { + mDexterityAdvantage.setValue(advantage); + mHasChanges.setValue(true); + } + } + + public LiveData getConstitutionProficiency() { + return mConstitutionProficiency; + } + + public void setConstitutionProficiency(ProficiencyType proficiency) { + if (!Objects.equals(mConstitutionProficiency.getValue(), proficiency)) { + mConstitutionProficiency.setValue(proficiency); + mHasChanges.setValue(true); + } + } + + public LiveData getConstitutionAdvantage() { + return mConstitutionAdvantage; + } + + public void setConstitutionAdvantage(AdvantageType advantage) { + if (!Objects.equals(mConstitutionAdvantage.getValue(), advantage)) { + mConstitutionAdvantage.setValue(advantage); + mHasChanges.setValue(true); + } + } + + public LiveData getIntelligenceProficiency() { + return mIntelligenceProficiency; + } + + public void setIntelligenceProficiency(ProficiencyType proficiency) { + if (!Objects.equals(mIntelligenceProficiency.getValue(), proficiency)) { + mIntelligenceProficiency.setValue(proficiency); + mHasChanges.setValue(true); + } + } + + public LiveData getIntelligenceAdvantage() { + return mIntelligenceAdvantage; + } + + public void setIntelligenceAdvantage(AdvantageType advantage) { + if (!Objects.equals(mIntelligenceAdvantage.getValue(), advantage)) { + mIntelligenceAdvantage.setValue(advantage); + mHasChanges.setValue(true); + } + } + + public LiveData getWisdomProficiency() { + return mWisdomProficiency; + } + + public void setWisdomProficiency(ProficiencyType proficiency) { + if (!Objects.equals(mWisdomProficiency.getValue(), proficiency)) { + mWisdomProficiency.setValue(proficiency); + mHasChanges.setValue(true); + } + } + + public LiveData getWisdomAdvantage() { + return mWisdomAdvantage; + } + + public void setWisdomAdvantage(AdvantageType advantage) { + if (!Objects.equals(mWisdomAdvantage.getValue(), advantage)) { + mWisdomAdvantage.setValue(advantage); + mHasChanges.setValue(true); + } + } + + public LiveData getCharismaProficiency() { + return mCharismaProficiency; + } + + public void setCharismaProficiency(ProficiencyType proficiency) { + if (!Objects.equals(mCharismaProficiency.getValue(), proficiency)) { + mCharismaProficiency.setValue(proficiency); + mHasChanges.setValue(true); + } + } + + public LiveData getCharismaAdvantage() { + return mCharismaAdvantage; + } + + public void setCharismaAdvantage(AdvantageType advantage) { + if (!Objects.equals(mCharismaAdvantage.getValue(), advantage)) { + mCharismaAdvantage.setValue(advantage); + mHasChanges.setValue(true); + } + } + public Monster buildMonster() { Monster monster = new Monster(); @@ -619,6 +789,18 @@ public class EditMonsterViewModel extends ViewModel { monster.intelligenceScore = mIntelligence.getValue(); monster.wisdomScore = mWisdom.getValue(); monster.charismaScore = mCharisma.getValue(); + monster.strengthSavingThrowAdvantage = mStrengthAdvantage.getValue(); + monster.strengthSavingThrowProficiency = mStrengthProficiency.getValue(); + monster.dexteritySavingThrowAdvantage = mDexterityAdvantage.getValue(); + monster.dexteritySavingThrowProficiency = mDexterityProficiency.getValue(); + monster.constitutionSavingThrowAdvantage = mConstitutionAdvantage.getValue(); + monster.constitutionSavingThrowProficiency = mConstitutionProficiency.getValue(); + monster.intelligenceSavingThrowAdvantage = mIntelligenceAdvantage.getValue(); + monster.intelligenceSavingThrowProficiency = mIntelligenceProficiency.getValue(); + monster.wisdomSavingThrowAdvantage = mWisdomAdvantage.getValue(); + monster.wisdomSavingThrowProficiency = mWisdomProficiency.getValue(); + monster.charismaSavingThrowAdvantage = mCharismaAdvantage.getValue(); + monster.charismaSavingThrowProficiency = mCharismaProficiency.getValue(); return monster; } diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditSavingThrowsFragment.java b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditSavingThrowsFragment.java new file mode 100644 index 0000000..c1a0f76 --- /dev/null +++ b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditSavingThrowsFragment.java @@ -0,0 +1,95 @@ +package com.majinnaibu.monstercards.ui.editmonster; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.fragment.app.Fragment; +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.components.AdvantagePicker; +import com.majinnaibu.monstercards.ui.components.ProficiencyPicker; + +public class EditSavingThrowsFragment extends Fragment { + private EditMonsterViewModel mViewModel; + private ViewHolder mViewHolder; + + @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); + + // Inflate the layout for this fragment + View root = inflater.inflate(R.layout.fragment_edit_saving_throws, container, false); + + mViewHolder = new ViewHolder(root); + mViewHolder.strengthProficiency.setValue(mViewModel.getStrengthProficiency().getValue()); + mViewHolder.strengthProficiency.setOnValueChangedListener(value -> mViewModel.setStrengthProficiency(value)); + mViewHolder.strengthAdvantage.setValue(mViewModel.getStrengthAdvantage().getValue()); + mViewHolder.strengthAdvantage.setOnValueChangedListener(value -> mViewModel.setStrengthAdvantage(value)); + + mViewHolder.dexterityProficiency.setValue(mViewModel.getDexterityProficiency().getValue()); + mViewHolder.dexterityProficiency.setOnValueChangedListener(value -> mViewModel.setDexterityProficiency(value)); + mViewHolder.dexterityAdvantage.setValue(mViewModel.getDexterityAdvantage().getValue()); + mViewHolder.dexterityAdvantage.setOnValueChangedListener(value -> mViewModel.setDexterityAdvantage(value)); + + mViewHolder.constitutionProficiency.setValue(mViewModel.getConstitutionProficiency().getValue()); + mViewHolder.constitutionProficiency.setOnValueChangedListener(value -> mViewModel.setConstitutionProficiency(value)); + mViewHolder.constitutionAdvantage.setValue(mViewModel.getConstitutionAdvantage().getValue()); + mViewHolder.constitutionAdvantage.setOnValueChangedListener(value -> mViewModel.setConstitutionAdvantage(value)); + + mViewHolder.intelligenceProficiency.setValue(mViewModel.getIntelligenceProficiency().getValue()); + mViewHolder.intelligenceProficiency.setOnValueChangedListener(value -> mViewModel.setIntelligenceProficiency(value)); + mViewHolder.intelligenceAdvantage.setValue(mViewModel.getIntelligenceAdvantage().getValue()); + mViewHolder.intelligenceAdvantage.setOnValueChangedListener(value -> mViewModel.setIntelligenceAdvantage(value)); + + mViewHolder.wisdomProficiency.setValue(mViewModel.getWisdomProficiency().getValue()); + mViewHolder.wisdomProficiency.setOnValueChangedListener(value -> mViewModel.setWisdomProficiency(value)); + mViewHolder.wisdomAdvantage.setValue(mViewModel.getWisdomAdvantage().getValue()); + mViewHolder.wisdomAdvantage.setOnValueChangedListener(value -> mViewModel.setWisdomAdvantage(value)); + + mViewHolder.charismaProficiency.setValue(mViewModel.getCharismaProficiency().getValue()); + mViewHolder.charismaProficiency.setOnValueChangedListener(value -> mViewModel.setCharismaProficiency(value)); + mViewHolder.charismaAdvantage.setValue(mViewModel.getCharismaAdvantage().getValue()); + mViewHolder.charismaAdvantage.setOnValueChangedListener(value -> mViewModel.setCharismaAdvantage(value)); + + return root; + } + + private static class ViewHolder { + AdvantagePicker strengthAdvantage; + ProficiencyPicker strengthProficiency; + AdvantagePicker dexterityAdvantage; + ProficiencyPicker dexterityProficiency; + AdvantagePicker constitutionAdvantage; + ProficiencyPicker constitutionProficiency; + AdvantagePicker intelligenceAdvantage; + ProficiencyPicker intelligenceProficiency; + AdvantagePicker wisdomAdvantage; + ProficiencyPicker wisdomProficiency; + AdvantagePicker charismaAdvantage; + ProficiencyPicker charismaProficiency; + + ViewHolder(View root) { + strengthAdvantage = root.findViewById(R.id.strengthAdvantage); + strengthProficiency = root.findViewById(R.id.strengthProficiency); + dexterityAdvantage = root.findViewById(R.id.dexterityAdvantage); + dexterityProficiency = root.findViewById(R.id.dexterityProficiency); + constitutionAdvantage = root.findViewById(R.id.constitutionAdvantage); + constitutionProficiency = root.findViewById(R.id.constitutionProficiency); + intelligenceAdvantage = root.findViewById(R.id.intelligenceAdvantage); + intelligenceProficiency = root.findViewById(R.id.intelligenceProficiency); + wisdomAdvantage = root.findViewById(R.id.wisdomAdvantage); + wisdomProficiency = root.findViewById(R.id.wisdomProficiency); + charismaAdvantage = root.findViewById(R.id.charismaAdvantage); + charismaProficiency = root.findViewById(R.id.charismaProficiency); + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/component_stepper.xml b/app/src/main/res/layout/component_stepper.xml index a330941..d8535c7 100644 --- a/app/src/main/res/layout/component_stepper.xml +++ b/app/src/main/res/layout/component_stepper.xml @@ -3,7 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_height="wrap_content" android:layout_margin="@dimen/text_margin" tools:context=".ui.components.Stepper"> diff --git a/app/src/main/res/layout/fragment_edit_saving_throws.xml b/app/src/main/res/layout/fragment_edit_saving_throws.xml new file mode 100644 index 0000000..61b2c03 --- /dev/null +++ b/app/src/main/res/layout/fragment_edit_saving_throws.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index e302b30..fe6f878 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -84,6 +84,9 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 52485b3..9934f06 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -35,6 +35,7 @@ Damage Vulnerabilities - Dexterity + Fly Speed Has Custom HP Has Custom Speed Has a Shield @@ -61,6 +62,7 @@ Speed Strength Subtype + Swim Speed Type Wisdom section divider @@ -73,7 +75,4 @@ Library Search WIS - Fly Speed - Swim Speed - \ No newline at end of file