diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditSkillFragment.java b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditSkillFragment.java new file mode 100644 index 0000000..1eb08dc --- /dev/null +++ b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditSkillFragment.java @@ -0,0 +1,96 @@ +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.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.models.Skill; +import com.majinnaibu.monstercards.ui.components.AbilityScorePicker; +import com.majinnaibu.monstercards.ui.components.AdvantagePicker; +import com.majinnaibu.monstercards.ui.components.ProficiencyPicker; +import com.majinnaibu.monstercards.utils.Logger; +import com.majinnaibu.monstercards.utils.TextChangedListener; + +public class EditSkillFragment extends Fragment { + private EditMonsterViewModel mEditMonsterViewModel; + private EditSkillViewModel mViewModel; + private ViewHolder mHolder; + private Skill mOldSkill; + + @Override + public void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + mViewModel = new ViewModelProvider(this).get(EditSkillViewModel.class); + if (getArguments() != null) { + EditSkillFragmentArgs args = EditSkillFragmentArgs.fromBundle(getArguments()); + mViewModel.copyFromSkill(args.getName(), args.getAbilityScore(), args.getProficiency(), args.getAdvantage()); + mOldSkill = new Skill(args.getName(), args.getAbilityScore(), args.getAdvantage(), args.getProficiency()); + } else { + Logger.logWTF("This should never happen. EditSkillFragment needs arguments."); + mOldSkill = 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); + + // Inflate the layout for this fragment + View root = inflater.inflate(R.layout.fragment_edit_skill, container, false); + + mHolder = new ViewHolder(root); + + mHolder.abilityScore.setValue(mViewModel.getAbilityScore().getValue()); + mHolder.abilityScore.setOnValueChangedListener(value -> mViewModel.setAbilityScore(value)); + + mHolder.advantage.setValue(mViewModel.getAdvantage().getValue()); + mHolder.advantage.setOnValueChangedListener(value -> mViewModel.setAdvantage(value)); + + mHolder.proficiency.setValue(mViewModel.getProficiency().getValue()); + mHolder.proficiency.setOnValueChangedListener(value -> mViewModel.setProficiency(value)); + + mHolder.name.setText(mViewModel.getName().getValue()); + mHolder.name.addTextChangedListener(new TextChangedListener((TextChangedListener.OnTextChangedCallback) (s, start, before, count) -> mViewModel.setName(s.toString()))); + + requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + if (mViewModel.hasChanges()) { + mEditMonsterViewModel.replaceSkill(mViewModel.getSkill().getValue(), mOldSkill); + } + Navigation.findNavController(requireView()).navigateUp(); + } + }); + + return root; + } + + private static class ViewHolder { + AbilityScorePicker abilityScore; + AdvantagePicker advantage; + ProficiencyPicker proficiency; + EditText name; + + ViewHolder(View root) { + abilityScore = root.findViewById(R.id.abilityScore); + advantage = root.findViewById(R.id.advantage); + proficiency = root.findViewById(R.id.proficiency); + name = root.findViewById(R.id.name); + } + } +} diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditSkillViewModel.java b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditSkillViewModel.java new file mode 100644 index 0000000..1d33390 --- /dev/null +++ b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditSkillViewModel.java @@ -0,0 +1,108 @@ +package com.majinnaibu.monstercards.ui.editmonster; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +import com.majinnaibu.monstercards.data.enums.AbilityScore; +import com.majinnaibu.monstercards.data.enums.AdvantageType; +import com.majinnaibu.monstercards.data.enums.ProficiencyType; +import com.majinnaibu.monstercards.models.Skill; +import com.majinnaibu.monstercards.utils.ChangeTrackedLiveData; + +public class EditSkillViewModel extends ViewModel { + private final ChangeTrackedLiveData mAbilityScore; + private final ChangeTrackedLiveData mAdvantageType; + private final MutableLiveData mHasChanges; + private final ChangeTrackedLiveData mProficiencyType; + private final ChangeTrackedLiveData mName; + private final ChangeTrackedLiveData mSkill; + + public EditSkillViewModel() { + mHasChanges = new MutableLiveData<>(false); + ChangeTrackedLiveData.OnValueDirtiedCallback onDirtied = () -> mHasChanges.setValue(true); + + mAbilityScore = new ChangeTrackedLiveData<>(AbilityScore.STRENGTH, onDirtied); + mAdvantageType = new ChangeTrackedLiveData<>(AdvantageType.NONE, onDirtied); + mProficiencyType = new ChangeTrackedLiveData<>(ProficiencyType.NONE, onDirtied); + mName = new ChangeTrackedLiveData<>("Unknown Skill", onDirtied); + mSkill = new ChangeTrackedLiveData<>(makeSkill(), onDirtied); + } + + public EditSkillViewModel(Skill skill) { + mHasChanges = new MutableLiveData<>(false); + ChangeTrackedLiveData.OnValueDirtiedCallback onDirtied = () -> mHasChanges.setValue(true); + + mAbilityScore = new ChangeTrackedLiveData<>(skill.abilityScore, onDirtied); + mAdvantageType = new ChangeTrackedLiveData<>(skill.advantageType, onDirtied); + mProficiencyType = new ChangeTrackedLiveData<>(skill.proficiencyType, onDirtied); + mName = new ChangeTrackedLiveData<>(skill.name, onDirtied); + mSkill = new ChangeTrackedLiveData<>(makeSkill(), onDirtied); + } + + public void copyFromSkill(Skill skill) { + mAbilityScore.resetValue(skill.abilityScore); + mAdvantageType.resetValue(skill.advantageType); + mProficiencyType.resetValue(skill.proficiencyType); + mName.resetValue(skill.name); + } + + public void copyFromSkill(String name, AbilityScore abilityScore, ProficiencyType proficiency, AdvantageType advantage) { + mAbilityScore.resetValue(abilityScore); + mAdvantageType.resetValue(advantage); + mProficiencyType.resetValue(proficiency); + mName.resetValue(name); + } + + public LiveData getSkill() { + return mSkill; + } + + public LiveData getAbilityScore() { + return mAbilityScore; + } + + public void setAbilityScore(AbilityScore value) { + mAbilityScore.setValue(value); + mSkill.setValue(makeSkill()); + } + + public LiveData getAdvantage() { + return mAdvantageType; + } + + public void setAdvantage(AdvantageType value) { + mAdvantageType.setValue(value); + mSkill.setValue(makeSkill()); + } + + public LiveData getProficiency() { + return mProficiencyType; + } + + public void setProficiency(ProficiencyType value) { + mProficiencyType.setValue(value); + mSkill.setValue(makeSkill()); + } + + public LiveData getName() { + return mName; + } + + public void setName(String value) { + mName.setValue(value); + mSkill.setValue(makeSkill()); + } + + public LiveData getHasChanges() { + return mHasChanges; + } + + public boolean hasChanges() { + return mHasChanges.getValue(); + } + + private Skill makeSkill() { + return new Skill(mName.getValue(), mAbilityScore.getValue(), mAdvantageType.getValue(), mProficiencyType.getValue()); + } +} diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditSkillsFragment.java b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditSkillsFragment.java index ab8a03f..13de066 100644 --- a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditSkillsFragment.java +++ b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditSkillsFragment.java @@ -11,6 +11,7 @@ import androidx.fragment.app.Fragment; 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; @@ -32,7 +33,10 @@ public class EditSkillsFragment extends Fragment { private ViewHolder mHolder; private void navigateToEditSkill(Skill skill) { - Logger.logUnimplementedFeature("Navigate to the edit skill fragment."); + NavDirections action = EditSkillsFragmentDirections.actionEditSkillsFragmentToEditSkillFragment(skill.name, skill.abilityScore, skill.proficiencyType, skill.advantageType); + View view = getView(); + assert view != null; + Navigation.findNavController(view).navigate(action); } @Override diff --git a/app/src/main/res/layout/fragment_edit_skill.xml b/app/src/main/res/layout/fragment_edit_skill.xml new file mode 100644 index 0000000..1f8548d --- /dev/null +++ b/app/src/main/res/layout/fragment_edit_skill.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + \ 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 15ab555..4ddc3c9 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -127,7 +127,28 @@ android:id="@+id/editSkillsFragment" android:name="com.majinnaibu.monstercards.ui.editmonster.EditSkillsFragment" android:label="fragment_edit_skills_list" - tools:layout="@layout/fragment_edit_skills_list" /> + tools:layout="@layout/fragment_edit_skills_list"> + + + + + + + + - - \ No newline at end of file +