Makes monster editor smoother and fixes colors.
This commit is contained in:
@@ -58,20 +58,11 @@ public class MainActivity extends AppCompatActivity {
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
|
||||
WindowCompat.setDecorFitsSystemWindows(getWindow(), true);
|
||||
super.onCreate(savedInstanceState);
|
||||
AppCenterInitializer.init(getApplication());
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
View container = findViewById(R.id.container);
|
||||
if (container != null) {
|
||||
ViewCompat.setOnApplyWindowInsetsListener(container, (v, windowInsets) -> {
|
||||
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||
v.setPadding(insets.left, insets.top, insets.right, 0);
|
||||
return windowInsets;
|
||||
});
|
||||
}
|
||||
|
||||
BottomNavigationView navView = findViewById(R.id.nav_view);
|
||||
// Passing each menu ID as a set of Ids because each
|
||||
// menu should be considered as top level destinations.
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.majinnaibu.monstercards.ui.editmonster;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
@@ -14,7 +16,7 @@ import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.NavBackStackEntry;
|
||||
import androidx.navigation.NavController;
|
||||
import androidx.navigation.NavDirections;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.majinnaibu.monstercards.R;
|
||||
@@ -22,10 +24,11 @@ import com.majinnaibu.monstercards.data.MonsterRepository;
|
||||
import com.majinnaibu.monstercards.data.enums.StringType;
|
||||
import com.majinnaibu.monstercards.data.enums.TraitType;
|
||||
import com.majinnaibu.monstercards.models.Monster;
|
||||
import com.majinnaibu.monstercards.ui.monster.MonsterDetailFragmentArgs;
|
||||
import com.majinnaibu.monstercards.ui.shared.MCFragment;
|
||||
import com.majinnaibu.monstercards.utils.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -43,21 +46,34 @@ public class EditMonsterFragment extends MCFragment {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
|
||||
MonsterRepository repository = getMonsterRepository();
|
||||
Bundle arguments = getArguments();
|
||||
assert arguments != null;
|
||||
UUID monsterId = UUID.fromString(MonsterDetailFragmentArgs.fromBundle(arguments).getMonsterId());
|
||||
|
||||
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_monster, container, false);
|
||||
mHolder = new ViewHolder(root);
|
||||
|
||||
MonsterRepository repository = getMonsterRepository();
|
||||
Bundle arguments = getArguments();
|
||||
if (arguments == null) {
|
||||
Logger.logError("Arguments bundle is null in EditMonsterFragment");
|
||||
return root;
|
||||
}
|
||||
|
||||
String monsterIdStr = EditMonsterFragmentArgs.fromBundle(arguments).getMonsterId();
|
||||
if (monsterIdStr == null || monsterIdStr.isEmpty()) {
|
||||
Logger.logError("monsterId is null or empty in EditMonsterFragment");
|
||||
return root;
|
||||
}
|
||||
|
||||
UUID monsterId = UUID.fromString(monsterIdStr);
|
||||
|
||||
try {
|
||||
NavController navController = NavHostFragment.findNavController(this);
|
||||
NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.edit_monster_navigation);
|
||||
mViewModel = new ViewModelProvider(backStackEntry).get(EditMonsterViewModel.class);
|
||||
} catch (Exception e) {
|
||||
mViewModel = new ViewModelProvider(this).get(EditMonsterViewModel.class);
|
||||
}
|
||||
|
||||
setTitle(getString(R.string.title_editMonster_fmt, getString(R.string.default_monster_name)));
|
||||
|
||||
// TODO: Show a loading spinner until we have the monster loaded.
|
||||
if (mViewModel.hasError() || !mViewModel.hasLoaded() || !Objects.equals(mViewModel.getMonsterId().getValue(), monsterId)) {
|
||||
repository.getMonster(monsterId).toObservable()
|
||||
.firstOrError()
|
||||
@@ -73,7 +89,6 @@ public class EditMonsterFragment extends MCFragment {
|
||||
|
||||
@Override
|
||||
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
|
||||
// TODO: Show an error state.
|
||||
Logger.logError(e);
|
||||
mViewModel.setHasError(true);
|
||||
mViewModel.setErrorMessage(e.toString());
|
||||
@@ -82,101 +97,9 @@ public class EditMonsterFragment extends MCFragment {
|
||||
});
|
||||
}
|
||||
|
||||
mHolder.basicInfoButton.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditBasicInfoFragment();
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.armorButton.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditArmorFragment();
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.speedButton.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditSpeedFragment();
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.abilityScoresButton.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditAbilityScoresFragment();
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.savingThrows.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditSavingThrowsFragment();
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.challengeRating.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditChallengeRatingFragment();
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.skills.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditSkillsFragment();
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.senses.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.SENSE);
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.conditionImmunities.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.CONDITION_IMMUNITY);
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.damageImmunities.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.DAMAGE_IMMUNITY);
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.damageResistances.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.DAMAGE_RESISTANCE);
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.damageVulnerabilities.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.DAMAGE_VULNERABILITY);
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.languages.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditLanguagesFragment();
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.abilities.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.ABILITY);
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.actions.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.ACTION);
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.lairActions.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.LAIR_ACTION);
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.legendaryActions.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.LEGENDARY_ACTION);
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.reactions.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.REACTIONS);
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
mHolder.regionalActions.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.REGIONAL_ACTION);
|
||||
Navigation.findNavController(requireView()).navigate(action);
|
||||
});
|
||||
|
||||
setupAccordions();
|
||||
setupSummaries();
|
||||
setupSubClickListeners();
|
||||
|
||||
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) {
|
||||
@Override
|
||||
@@ -187,7 +110,6 @@ public class EditMonsterFragment extends MCFragment {
|
||||
alertDialog.setTitle("Unsaved Changes");
|
||||
alertDialog.setMessage("Do you want to save your changes?");
|
||||
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Save", (dialog, id) -> {
|
||||
// Save the monster. Navigate up if the save is successful. Show a SnackBar if there was an error.
|
||||
getMonsterRepository().saveMonster(mViewModel.buildMonster())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@@ -195,29 +117,23 @@ public class EditMonsterFragment extends MCFragment {
|
||||
new DisposableCompletableObserver() {
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Navigation.findNavController(requireView()).navigateUp();
|
||||
NavHostFragment.findNavController(EditMonsterFragment.this).navigateUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
|
||||
Logger.logError("Error creating monster", e);
|
||||
Logger.logError("Error saving monster", e);
|
||||
assert view != null;
|
||||
Snackbar.make(view, getString(R.string.snackbar_failed_to_create_monster), Snackbar.LENGTH_LONG)
|
||||
.setAction("Action", null).show();
|
||||
}
|
||||
});
|
||||
});
|
||||
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Discard", (dialog, id) -> {
|
||||
// Navigate up ignoring unsaved changes.
|
||||
Navigation.findNavController(requireView()).navigateUp();
|
||||
});
|
||||
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "Cancel", (dialog, id) -> {
|
||||
// Do nothing.
|
||||
});
|
||||
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Discard", (dialog, id) -> NavHostFragment.findNavController(EditMonsterFragment.this).navigateUp());
|
||||
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "Cancel", (dialog, id) -> {});
|
||||
alertDialog.show();
|
||||
} else {
|
||||
// No changes so we can safely leave.
|
||||
Navigation.findNavController(requireView()).navigateUp();
|
||||
NavHostFragment.findNavController(EditMonsterFragment.this).navigateUp();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -225,42 +141,344 @@ public class EditMonsterFragment extends MCFragment {
|
||||
return root;
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
private void setupAccordions() {
|
||||
if (mHolder.headerBasicInfo != null && mHolder.bodyBasicInfo != null && mHolder.chevronBasicInfo != null) {
|
||||
setupAccordion(mHolder.headerBasicInfo, mHolder.bodyBasicInfo, mHolder.chevronBasicInfo);
|
||||
}
|
||||
if (mHolder.headerCombatAbilities != null && mHolder.bodyCombatAbilities != null && mHolder.chevronCombatAbilities != null) {
|
||||
setupAccordion(mHolder.headerCombatAbilities, mHolder.bodyCombatAbilities, mHolder.chevronCombatAbilities);
|
||||
}
|
||||
if (mHolder.headerSavesSkillsLanguages != null && mHolder.bodySavesSkillsLanguages != null && mHolder.chevronSavesSkillsLanguages != null) {
|
||||
setupAccordion(mHolder.headerSavesSkillsLanguages, mHolder.bodySavesSkillsLanguages, mHolder.chevronSavesSkillsLanguages);
|
||||
}
|
||||
if (mHolder.headerDefenses != null && mHolder.bodyDefenses != null && mHolder.chevronDefenses != null) {
|
||||
setupAccordion(mHolder.headerDefenses, mHolder.bodyDefenses, mHolder.chevronDefenses);
|
||||
}
|
||||
if (mHolder.headerTraitsActions != null && mHolder.bodyTraitsActions != null && mHolder.chevronTraitsActions != null) {
|
||||
setupAccordion(mHolder.headerTraitsActions, mHolder.bodyTraitsActions, mHolder.chevronTraitsActions);
|
||||
}
|
||||
}
|
||||
|
||||
TextView basicInfoButton;
|
||||
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;
|
||||
private void setupAccordion(View header, View body, ImageView chevron) {
|
||||
header.setOnClickListener(v -> {
|
||||
boolean isExpanded = body.getVisibility() == View.VISIBLE;
|
||||
body.setVisibility(isExpanded ? View.GONE : View.VISIBLE);
|
||||
chevron.setImageResource(isExpanded ? R.drawable.ic_expand_more_24 : R.drawable.ic_expand_less_24);
|
||||
});
|
||||
}
|
||||
|
||||
private void setupSummaries() {
|
||||
mViewModel.getName().observe(getViewLifecycleOwner(), v -> updateBasicInfoSummary());
|
||||
mViewModel.getSize().observe(getViewLifecycleOwner(), v -> updateBasicInfoSummary());
|
||||
mViewModel.getType().observe(getViewLifecycleOwner(), v -> updateBasicInfoSummary());
|
||||
mViewModel.getChallengeRating().observe(getViewLifecycleOwner(), v -> updateBasicInfoSummary());
|
||||
|
||||
mViewModel.getStrength().observe(getViewLifecycleOwner(), v -> updateCombatAbilitiesSummary());
|
||||
mViewModel.getDexterity().observe(getViewLifecycleOwner(), v -> updateCombatAbilitiesSummary());
|
||||
mViewModel.getConstitution().observe(getViewLifecycleOwner(), v -> updateCombatAbilitiesSummary());
|
||||
mViewModel.getIntelligence().observe(getViewLifecycleOwner(), v -> updateCombatAbilitiesSummary());
|
||||
mViewModel.getWisdom().observe(getViewLifecycleOwner(), v -> updateCombatAbilitiesSummary());
|
||||
mViewModel.getCharisma().observe(getViewLifecycleOwner(), v -> updateCombatAbilitiesSummary());
|
||||
|
||||
mViewModel.getSkills().observe(getViewLifecycleOwner(), v -> updateSavesSkillsSummary());
|
||||
mViewModel.getLanguages().observe(getViewLifecycleOwner(), v -> updateSavesSkillsSummary());
|
||||
|
||||
mViewModel.getConditionImmunities().observe(getViewLifecycleOwner(), v -> updateDefensesSummary());
|
||||
mViewModel.getDamageImmunities().observe(getViewLifecycleOwner(), v -> updateDefensesSummary());
|
||||
mViewModel.getDamageResistances().observe(getViewLifecycleOwner(), v -> updateDefensesSummary());
|
||||
mViewModel.getDamageVulnerabilities().observe(getViewLifecycleOwner(), v -> updateDefensesSummary());
|
||||
|
||||
mViewModel.getAbilities().observe(getViewLifecycleOwner(), v -> updateTraitsActionsSummary());
|
||||
mViewModel.getActions().observe(getViewLifecycleOwner(), v -> updateTraitsActionsSummary());
|
||||
mViewModel.getReactions().observe(getViewLifecycleOwner(), v -> updateTraitsActionsSummary());
|
||||
}
|
||||
|
||||
private void updateBasicInfoSummary() {
|
||||
if (mHolder.summaryBasicInfo == null) return;
|
||||
String name = mViewModel.getName().getValue();
|
||||
String size = mViewModel.getSize().getValue();
|
||||
String type = mViewModel.getType().getValue();
|
||||
|
||||
List<String> parts = new ArrayList<>();
|
||||
if (!TextUtils.isEmpty(name)) parts.add(name);
|
||||
if (!TextUtils.isEmpty(size)) parts.add(size);
|
||||
if (!TextUtils.isEmpty(type)) parts.add(type);
|
||||
|
||||
mHolder.summaryBasicInfo.setText(parts.isEmpty() ? "Tap to edit basic info" : TextUtils.join(", ", parts));
|
||||
}
|
||||
|
||||
private void updateCombatAbilitiesSummary() {
|
||||
if (mHolder.summaryCombatAbilities == null) return;
|
||||
Integer str = mViewModel.getStrength().getValue();
|
||||
Integer dex = mViewModel.getDexterity().getValue();
|
||||
Integer con = mViewModel.getConstitution().getValue();
|
||||
Integer intel = mViewModel.getIntelligence().getValue();
|
||||
Integer wis = mViewModel.getWisdom().getValue();
|
||||
Integer cha = mViewModel.getCharisma().getValue();
|
||||
|
||||
String summary = String.format("STR %d | DEX %d | CON %d | INT %d | WIS %d | CHA %d",
|
||||
str != null ? str : 10,
|
||||
dex != null ? dex : 10,
|
||||
con != null ? con : 10,
|
||||
intel != null ? intel : 10,
|
||||
wis != null ? wis : 10,
|
||||
cha != null ? cha : 10);
|
||||
mHolder.summaryCombatAbilities.setText(summary);
|
||||
}
|
||||
|
||||
private void updateSavesSkillsSummary() {
|
||||
if (mHolder.summarySavesSkillsLanguages == null) return;
|
||||
int skillsCount = mViewModel.getSkills().getValue() != null ? mViewModel.getSkills().getValue().size() : 0;
|
||||
int languagesCount = mViewModel.getLanguages().getValue() != null ? mViewModel.getLanguages().getValue().size() : 0;
|
||||
|
||||
mHolder.summarySavesSkillsLanguages.setText(String.format("%d Skills, %d Languages", skillsCount, languagesCount));
|
||||
}
|
||||
|
||||
private void updateDefensesSummary() {
|
||||
if (mHolder.summaryDefenses == null) return;
|
||||
List<String> defenses = new ArrayList<>();
|
||||
if (mViewModel.getConditionImmunities().getValue() != null && !mViewModel.getConditionImmunities().getValue().isEmpty()) {
|
||||
defenses.add(mViewModel.getConditionImmunities().getValue().size() + " Condition Immunities");
|
||||
}
|
||||
if (mViewModel.getDamageImmunities().getValue() != null && !mViewModel.getDamageImmunities().getValue().isEmpty()) {
|
||||
defenses.add(mViewModel.getDamageImmunities().getValue().size() + " Damage Immunities");
|
||||
}
|
||||
if (mViewModel.getDamageResistances().getValue() != null && !mViewModel.getDamageResistances().getValue().isEmpty()) {
|
||||
defenses.add(mViewModel.getDamageResistances().getValue().size() + " Resistances");
|
||||
}
|
||||
|
||||
mHolder.summaryDefenses.setText(defenses.isEmpty() ? "None" : TextUtils.join(", ", defenses));
|
||||
}
|
||||
|
||||
private void updateTraitsActionsSummary() {
|
||||
if (mHolder.summaryTraitsActions == null) return;
|
||||
int abilitiesCount = mViewModel.getAbilities().getValue() != null ? mViewModel.getAbilities().getValue().size() : 0;
|
||||
int actionsCount = mViewModel.getActions().getValue() != null ? mViewModel.getActions().getValue().size() : 0;
|
||||
int reactionsCount = mViewModel.getReactions().getValue() != null ? mViewModel.getReactions().getValue().size() : 0;
|
||||
|
||||
mHolder.summaryTraitsActions.setText(String.format("%d Abilities, %d Actions, %d Reactions", abilitiesCount, actionsCount, reactionsCount));
|
||||
}
|
||||
|
||||
private void setupSubClickListeners() {
|
||||
if (mHolder.basicInfoButton != null) {
|
||||
mHolder.basicInfoButton.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditBasicInfoFragment();
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.challengeRating != null) {
|
||||
mHolder.challengeRating.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditChallengeRatingFragment();
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.armorButton != null) {
|
||||
mHolder.armorButton.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditArmorFragment();
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.speedButton != null) {
|
||||
mHolder.speedButton.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditSpeedFragment();
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.abilityScoresButton != null) {
|
||||
mHolder.abilityScoresButton.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditAbilityScoresFragment();
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.savingThrows != null) {
|
||||
mHolder.savingThrows.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditSavingThrowsFragment();
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.skills != null) {
|
||||
mHolder.skills.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditSkillsFragment();
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.senses != null) {
|
||||
mHolder.senses.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.SENSE);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.languages != null) {
|
||||
mHolder.languages.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditLanguagesFragment();
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.conditionImmunities != null) {
|
||||
mHolder.conditionImmunities.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.CONDITION_IMMUNITY);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.damageImmunities != null) {
|
||||
mHolder.damageImmunities.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.DAMAGE_IMMUNITY);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.damageResistances != null) {
|
||||
mHolder.damageResistances.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.DAMAGE_RESISTANCE);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.damageVulnerabilities != null) {
|
||||
mHolder.damageVulnerabilities.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditStringsFragment(StringType.DAMAGE_VULNERABILITY);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.abilities != null) {
|
||||
mHolder.abilities.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.ABILITY);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.actions != null) {
|
||||
mHolder.actions.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.ACTION);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.reactions != null) {
|
||||
mHolder.reactions.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.REACTIONS);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.legendaryActions != null) {
|
||||
mHolder.legendaryActions.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.LEGENDARY_ACTION);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.lairActions != null) {
|
||||
mHolder.lairActions.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.LAIR_ACTION);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
|
||||
if (mHolder.regionalActions != null) {
|
||||
mHolder.regionalActions.setOnClickListener(v -> {
|
||||
NavDirections action = EditMonsterFragmentDirections.actionEditMonsterFragmentToEditTraitListFragment(TraitType.REGIONAL_ACTION);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
final View headerBasicInfo;
|
||||
final View bodyBasicInfo;
|
||||
final ImageView chevronBasicInfo;
|
||||
final TextView summaryBasicInfo;
|
||||
|
||||
final View headerCombatAbilities;
|
||||
final View bodyCombatAbilities;
|
||||
final ImageView chevronCombatAbilities;
|
||||
final TextView summaryCombatAbilities;
|
||||
|
||||
final View headerSavesSkillsLanguages;
|
||||
final View bodySavesSkillsLanguages;
|
||||
final ImageView chevronSavesSkillsLanguages;
|
||||
final TextView summarySavesSkillsLanguages;
|
||||
|
||||
final View headerDefenses;
|
||||
final View bodyDefenses;
|
||||
final ImageView chevronDefenses;
|
||||
final TextView summaryDefenses;
|
||||
|
||||
final View headerTraitsActions;
|
||||
final View bodyTraitsActions;
|
||||
final ImageView chevronTraitsActions;
|
||||
final TextView summaryTraitsActions;
|
||||
|
||||
final TextView basicInfoButton;
|
||||
final TextView challengeRating;
|
||||
final TextView armorButton;
|
||||
final TextView speedButton;
|
||||
final TextView abilityScoresButton;
|
||||
final TextView savingThrows;
|
||||
final TextView skills;
|
||||
final TextView senses;
|
||||
final TextView languages;
|
||||
final TextView conditionImmunities;
|
||||
final TextView damageImmunities;
|
||||
final TextView damageResistances;
|
||||
final TextView damageVulnerabilities;
|
||||
final TextView abilities;
|
||||
final TextView actions;
|
||||
final TextView reactions;
|
||||
final TextView legendaryActions;
|
||||
final TextView lairActions;
|
||||
final TextView regionalActions;
|
||||
|
||||
ViewHolder(@NonNull View root) {
|
||||
headerBasicInfo = root.findViewById(R.id.headerBasicInfo);
|
||||
bodyBasicInfo = root.findViewById(R.id.bodyBasicInfo);
|
||||
chevronBasicInfo = root.findViewById(R.id.chevronBasicInfo);
|
||||
summaryBasicInfo = root.findViewById(R.id.summaryBasicInfo);
|
||||
|
||||
headerCombatAbilities = root.findViewById(R.id.headerCombatAbilities);
|
||||
bodyCombatAbilities = root.findViewById(R.id.bodyCombatAbilities);
|
||||
chevronCombatAbilities = root.findViewById(R.id.chevronCombatAbilities);
|
||||
summaryCombatAbilities = root.findViewById(R.id.summaryCombatAbilities);
|
||||
|
||||
headerSavesSkillsLanguages = root.findViewById(R.id.headerSavesSkillsLanguages);
|
||||
bodySavesSkillsLanguages = root.findViewById(R.id.bodySavesSkillsLanguages);
|
||||
chevronSavesSkillsLanguages = root.findViewById(R.id.chevronSavesSkillsLanguages);
|
||||
summarySavesSkillsLanguages = root.findViewById(R.id.summarySavesSkillsLanguages);
|
||||
|
||||
headerDefenses = root.findViewById(R.id.headerDefenses);
|
||||
bodyDefenses = root.findViewById(R.id.bodyDefenses);
|
||||
chevronDefenses = root.findViewById(R.id.chevronDefenses);
|
||||
summaryDefenses = root.findViewById(R.id.summaryDefenses);
|
||||
|
||||
headerTraitsActions = root.findViewById(R.id.headerTraitsActions);
|
||||
bodyTraitsActions = root.findViewById(R.id.bodyTraitsActions);
|
||||
chevronTraitsActions = root.findViewById(R.id.chevronTraitsActions);
|
||||
summaryTraitsActions = root.findViewById(R.id.summaryTraitsActions);
|
||||
|
||||
basicInfoButton = root.findViewById(R.id.basicInfo);
|
||||
challengeRating = root.findViewById(R.id.challengeRating);
|
||||
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);
|
||||
senses = root.findViewById(R.id.senses);
|
||||
languages = root.findViewById(R.id.languages);
|
||||
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);
|
||||
|
||||
@@ -702,6 +702,38 @@ public class EditMonsterViewModel extends ChangeTrackedViewModel {
|
||||
return mDamageResistances;
|
||||
}
|
||||
|
||||
public LiveData<List<String>> getDamageVulnerabilities() {
|
||||
return mDamageVulnerabilities;
|
||||
}
|
||||
|
||||
public LiveData<List<String>> getConditionImmunities() {
|
||||
return mConditionImmunities;
|
||||
}
|
||||
|
||||
public LiveData<List<Trait>> getAbilities() {
|
||||
return mAbilities;
|
||||
}
|
||||
|
||||
public LiveData<List<Trait>> getActions() {
|
||||
return mActions;
|
||||
}
|
||||
|
||||
public LiveData<List<Trait>> getReactions() {
|
||||
return mReactions;
|
||||
}
|
||||
|
||||
public LiveData<List<Trait>> getLairActions() {
|
||||
return mLairActions;
|
||||
}
|
||||
|
||||
public LiveData<List<Trait>> getLegendaryActions() {
|
||||
return mLegendaryActions;
|
||||
}
|
||||
|
||||
public LiveData<List<Trait>> getRegionalActions() {
|
||||
return mRegionalActions;
|
||||
}
|
||||
|
||||
public LiveData<List<Language>> getLanguages() {
|
||||
return mLanguages;
|
||||
}
|
||||
|
||||
10
Android/app/src/main/res/drawable/ic_expand_less_24.xml
Normal file
10
Android/app/src/main/res/drawable/ic_expand_less_24.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,8l-6,6 1.41,1.41L12,10.83l4.59,4.58L18,14z"/>
|
||||
</vector>
|
||||
10
Android/app/src/main/res/drawable/ic_expand_more_24.xml
Normal file
10
Android/app/src/main/res/drawable/ic_expand_more_24.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/>
|
||||
</vector>
|
||||
@@ -59,6 +59,7 @@
|
||||
android:id="@+id/decrement"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:paddingVertical="8dp"
|
||||
android:text="@string/label_decrement_field"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.editmonster.EditBasicInfoFragment">
|
||||
android:clipToPadding="false"
|
||||
android:padding="16dp"
|
||||
tools:context=".ui.editmonster.EditAbilityScoresFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.editmonster.EditBasicInfoFragment">
|
||||
android:clipToPadding="false"
|
||||
android:padding="16dp"
|
||||
tools:context=".ui.editmonster.EditArmorFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:padding="16dp"
|
||||
tools:context=".ui.editmonster.EditBasicInfoFragment">
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:padding="16dp"
|
||||
tools:context=".ui.editmonster.EditChallengeRatingFragment">
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -3,187 +3,545 @@
|
||||
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="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:padding="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:context=".ui.editmonster.EditMonsterFragment">
|
||||
|
||||
<!-- Card 1: Basic Info & Challenge Rating -->
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cardBasicInfo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/headerBasicInfo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleBasicInfo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:text="Basic Info & Challenge Rating"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/summaryBasicInfo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/titleBasicInfo"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_toStartOf="@+id/chevronBasicInfo"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="14sp"
|
||||
tools:text="Goblin — Small humanoid, CR 1/4" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/chevronBasicInfo"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="Expand/Collapse"
|
||||
android:src="@drawable/ic_expand_more_24" />
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bodyBasicInfo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:divider="?android:attr/dividerVertical"
|
||||
android:dividerPadding="@dimen/text_margin"
|
||||
android:dividerPadding="8dp"
|
||||
android:orientation="vertical"
|
||||
android:showDividers="middle"
|
||||
tools:context=".ui.editmonster.EditMonsterFragment">
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/basicInfo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_basic_info"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/armor"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:text="@string/label_armor"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/speed"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:text="@string/label_speed"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/abilityScores"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:text="@string/label_ability_scores"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/savingThrows"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:text="@string/label_saving_throws"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/skills"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:text="@string/label_skills"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/conditionImmunities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:text="@string/label_condition_immunities"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/damageImmunities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:text="@string/label_damage_immunities"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/damageResistances"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:text="@string/label_damage_resistances"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/damageVulnerabilities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:text="@string/label_damage_vulnerabilities"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/senses"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:text="@string/label_senses"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/languages"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:text="@string/label_languages"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/challengeRating"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_challenge_rating"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<!-- Card 2: Armor, Speed & Ability Scores -->
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cardCombatAbilities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/headerCombatAbilities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleCombatAbilities"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:text="Armor, Speed & Ability Scores"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/summaryCombatAbilities"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/titleCombatAbilities"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_toStartOf="@+id/chevronCombatAbilities"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="14sp"
|
||||
tools:text="STR 8 | DEX 14 | CON 10 | INT 10 | WIS 14 | CHA 15" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/chevronCombatAbilities"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="Expand/Collapse"
|
||||
android:src="@drawable/ic_expand_more_24" />
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bodyCombatAbilities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:divider="?android:attr/dividerVertical"
|
||||
android:dividerPadding="8dp"
|
||||
android:orientation="vertical"
|
||||
android:showDividers="middle"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/armor"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_armor"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/speed"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_speed"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/abilityScores"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_ability_scores"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<!-- Card 3: Saves, Skills & Languages -->
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cardSavesSkillsLanguages"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/headerSavesSkillsLanguages"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleSavesSkillsLanguages"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:text="Saves, Skills & Languages"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/summarySavesSkillsLanguages"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/titleSavesSkillsLanguages"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_toStartOf="@+id/chevronSavesSkillsLanguages"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="14sp"
|
||||
tools:text="3 Saves, 2 Skills, Common & Goblin" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/chevronSavesSkillsLanguages"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="Expand/Collapse"
|
||||
android:src="@drawable/ic_expand_more_24" />
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bodySavesSkillsLanguages"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:divider="?android:attr/dividerVertical"
|
||||
android:dividerPadding="8dp"
|
||||
android:orientation="vertical"
|
||||
android:showDividers="middle"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/savingThrows"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_saving_throws"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/skills"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_skills"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/senses"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_senses"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/languages"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_languages"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<!-- Card 4: Defenses & Immunities -->
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cardDefenses"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/headerDefenses"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleDefenses"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:text="Defenses & Immunities"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/summaryDefenses"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/titleDefenses"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_toStartOf="@+id/chevronDefenses"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="14sp"
|
||||
tools:text="Poison Immunity, Fire Resistance" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/chevronDefenses"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="Expand/Collapse"
|
||||
android:src="@drawable/ic_expand_more_24" />
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bodyDefenses"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:divider="?android:attr/dividerVertical"
|
||||
android:dividerPadding="8dp"
|
||||
android:orientation="vertical"
|
||||
android:showDividers="middle"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/conditionImmunities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_condition_immunities"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/damageImmunities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_damage_immunities"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/damageResistances"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_damage_resistances"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/damageVulnerabilities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_damage_vulnerabilities"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<!-- Card 5: Abilities, Actions & Traits -->
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cardTraitsActions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/headerTraitsActions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleTraitsActions"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:text="Abilities, Actions & Traits"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/summaryTraitsActions"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/titleTraitsActions"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_toStartOf="@+id/chevronTraitsActions"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="14sp"
|
||||
tools:text="2 Abilities, 2 Actions, 1 Reaction" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/chevronTraitsActions"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="Expand/Collapse"
|
||||
android:src="@drawable/ic_expand_more_24" />
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bodyTraitsActions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:divider="?android:attr/dividerVertical"
|
||||
android:dividerPadding="8dp"
|
||||
android:orientation="vertical"
|
||||
android:showDividers="middle"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/abilities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_abilities"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/actions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_actions"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/reactions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_reactions"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/legendaryActions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_legendary_actions"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/lairActions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_lair_actions"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/regionalActions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:text="@string/label_regional_effects"
|
||||
android:textSize="@dimen/text_h4_size"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right_24" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
android:clipToPadding="false"
|
||||
android:padding="16dp"
|
||||
tools:context=".ui.editmonster.EditSavingThrowsFragment">
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.editmonster.EditBasicInfoFragment">
|
||||
android:clipToPadding="false"
|
||||
android:padding="16dp"
|
||||
tools:context=".ui.editmonster.EditSpeedFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
<resources>
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorSecondary">@color/colorSecondary</item>
|
||||
<item name="colorSecondaryVariant">@color/colorSecondaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="colorOnPrimary">#ffffff</item>
|
||||
<item name="colorOnSecondary">#000000</item>
|
||||
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user