diff --git a/app/src/main/java/net/helcel/beans/activity/adapter/GeolocListAdapter.kt b/app/src/main/java/net/helcel/beans/activity/adapter/GeolocListAdapter.kt index 47144e5..2eae116 100644 --- a/app/src/main/java/net/helcel/beans/activity/adapter/GeolocListAdapter.kt +++ b/app/src/main/java/net/helcel/beans/activity/adapter/GeolocListAdapter.kt @@ -13,12 +13,15 @@ import net.helcel.beans.activity.fragment.EditPlaceColorFragment import net.helcel.beans.activity.fragment.EditPlaceFragment import net.helcel.beans.countries.GeoLoc import net.helcel.beans.databinding.ItemListGeolocBinding +import net.helcel.beans.helper.AUTO_GROUP import net.helcel.beans.helper.Data +import net.helcel.beans.helper.NO_GROUP import net.helcel.beans.helper.Settings import net.helcel.beans.helper.Theme.colorWrapper class GeolocListAdapter( - private val ctx: EditPlaceFragment, private val l: GeoLoc, private val pager: ViewPagerAdapter + private val ctx: EditPlaceFragment, private val l: GeoLoc, private val pager: ViewPagerAdapter, + private val parentHolder: FoldingListViewHolder? ) : RecyclerView.Adapter() { override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): FoldingListViewHolder { @@ -27,7 +30,7 @@ class GeolocListAdapter( viewGroup, false ) - return FoldingListViewHolder(ctx.requireActivity(), binding) + return FoldingListViewHolder(ctx.requireActivity(), binding, parentHolder, l) } override fun onBindViewHolder(holder: FoldingListViewHolder, position: Int) { @@ -35,7 +38,7 @@ class GeolocListAdapter( holder.bind(el) holder.addListeners(el) { if (el.children.isNotEmpty()) - pager.addFragment(ctx, EditPlaceFragment(el, pager)) + pager.addFragment(ctx, EditPlaceFragment(el, pager, holder)) true } } @@ -46,21 +49,13 @@ class GeolocListAdapter( class FoldingListViewHolder( private val ctx: FragmentActivity, - private val _binding: ItemListGeolocBinding + private val _binding: ItemListGeolocBinding, + private val _parentHolder: FoldingListViewHolder? = null, + private val _parentGeoLoc: GeoLoc, ) : RecyclerView.ViewHolder(_binding.root) { private fun bindGroup(el: GeoLoc) { - val numerator = el.children.map { Data.visits.getVisited(it) != 0 }.count { it } - val denominator = el.children.size - - _binding.count.text = when (Settings.getStatPref(ctx)) { - ctx.getString(R.string.percentages) -> ctx.getString( - R.string.percentage, - (100 * (numerator.toFloat() / denominator.toFloat())).toInt() - ) - - else -> ctx.getString(R.string.rate, numerator, denominator) - } + refreshCount(el) _binding.textView.setTypeface(null, Typeface.BOLD) _binding.textView.backgroundTintList = ColorStateList.valueOf( colorWrapper( @@ -104,6 +99,7 @@ class GeolocListAdapter( "AddColorDialogFragment" ) } + _parentHolder?.refresh(_parentGeoLoc) } } @@ -122,6 +118,24 @@ class GeolocListAdapter( } private fun refreshCheck(geoLoc: GeoLoc) { + _binding.checkBox.checkedState = + if (Data.visits.getVisited(geoLoc) !in listOf(NO_GROUP, AUTO_GROUP)) { + MaterialCheckBox.STATE_CHECKED + } + else if (geoLoc.children.isNotEmpty() && geoLoc.children.all { Data.visits.getVisited(it) != NO_GROUP }) { + Data.visits.setVisited(geoLoc, AUTO_GROUP) + MaterialCheckBox.STATE_CHECKED + } + else if (geoLoc.children.any { Data.visits.getVisited(it) != NO_GROUP }) { + Data.visits.setVisited(geoLoc, AUTO_GROUP) + MaterialCheckBox.STATE_INDETERMINATE + } + else { + Data.visits.setVisited(geoLoc, NO_GROUP) + MaterialCheckBox.STATE_UNCHECKED + } + Data.saveData() + var col = Data.groups.getGroupFromKey(Data.visits.getVisited(geoLoc)).color if (col.color == Color.TRANSPARENT) { col = colorWrapper( @@ -130,13 +144,29 @@ class GeolocListAdapter( ) col.alpha = 64 } - _binding.checkBox.checkedState = - if (Data.visits.getVisited(geoLoc) != 0) MaterialCheckBox.STATE_CHECKED - else if (geoLoc.children.any { Data.visits.getVisited(it) != 0 }) MaterialCheckBox.STATE_INDETERMINATE - else MaterialCheckBox.STATE_UNCHECKED - _binding.checkBox.buttonTintList = ColorStateList.valueOf(col.color) } + private fun refreshCount(geoLoc: GeoLoc) { + val numerator = geoLoc.children.map { Data.visits.getVisited(it) != 0 }.count { it } + val denominator = geoLoc.children.size + _binding.count.text = when (Settings.getStatPref(ctx)) { + ctx.getString(R.string.percentages) -> ctx.getString( + R.string.percentage, + (100 * (numerator.toFloat() / denominator.toFloat())).toInt() + ) + else -> ctx.getString(R.string.rate, numerator, denominator) + } + } + + private fun refresh(geoLoc: GeoLoc) { + // Refresh + refreshCheck(geoLoc) + refreshCount(geoLoc) + + // Recursively refresh parent + _parentHolder?.refresh(_parentGeoLoc) + } + } } diff --git a/app/src/main/java/net/helcel/beans/activity/fragment/EditPlaceFragment.kt b/app/src/main/java/net/helcel/beans/activity/fragment/EditPlaceFragment.kt index 2c14f7d..ddccaac 100644 --- a/app/src/main/java/net/helcel/beans/activity/fragment/EditPlaceFragment.kt +++ b/app/src/main/java/net/helcel/beans/activity/fragment/EditPlaceFragment.kt @@ -8,11 +8,12 @@ import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import net.helcel.beans.activity.adapter.GeolocListAdapter +import net.helcel.beans.activity.adapter.GeolocListAdapter.FoldingListViewHolder import net.helcel.beans.activity.adapter.ViewPagerAdapter import net.helcel.beans.countries.GeoLoc import net.helcel.beans.databinding.FragmentEditPlacesBinding -class EditPlaceFragment(val loc: GeoLoc, private val pager: ViewPagerAdapter) : Fragment() { +class EditPlaceFragment(val loc: GeoLoc, private val pager: ViewPagerAdapter, private val holder: FoldingListViewHolder? = null) : Fragment() { private lateinit var _binding: FragmentEditPlacesBinding override fun onCreateView( @@ -26,7 +27,7 @@ class EditPlaceFragment(val loc: GeoLoc, private val pager: ViewPagerAdapter) : _binding.list.setHasFixedSize(true) _binding.list.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) - _binding.list.adapter = GeolocListAdapter(this, loc, pager) + _binding.list.adapter = GeolocListAdapter(this, loc, pager, holder) return _binding.root } } \ No newline at end of file diff --git a/app/src/main/java/net/helcel/beans/helper/Data.kt b/app/src/main/java/net/helcel/beans/helper/Data.kt index 5c1c72a..f426e83 100644 --- a/app/src/main/java/net/helcel/beans/helper/Data.kt +++ b/app/src/main/java/net/helcel/beans/helper/Data.kt @@ -34,7 +34,7 @@ fun loadData(ctx: Context, id:Int) { // Add default group "Visited" with app's color if there is no group already if (groups.size() == 0) { - groups.setGroup(1, "Visited", ColorDrawable(ContextCompat.getColor(ctx, R.color.blue))) + groups.setGroup(DEFAULT_GROUP, "Visited", ColorDrawable(ContextCompat.getColor(ctx, R.color.blue))) saveData() } diff --git a/app/src/main/java/net/helcel/beans/helper/Groups.kt b/app/src/main/java/net/helcel/beans/helper/Groups.kt index 7f396bf..2e2cc1d 100644 --- a/app/src/main/java/net/helcel/beans/helper/Groups.kt +++ b/app/src/main/java/net/helcel/beans/helper/Groups.kt @@ -13,6 +13,10 @@ import kotlin.random.Random private const val randSeed = 0 private val rnd = Random(randSeed) +const val NO_GROUP = 0 +const val DEFAULT_GROUP = 1 +const val AUTO_GROUP = -1 + @Serializable class Groups(val id: Int, private val grps: HashMap) { @@ -30,7 +34,7 @@ class Groups(val id: Int, private val grps: HashMap) { fun genKey(): Int { val key = rnd.nextInt() - if (grps.containsKey(key) || key == 0) return genKey() + if (grps.containsKey(key) || key in listOf(NO_GROUP, AUTO_GROUP)) return genKey() return key } diff --git a/app/src/main/java/net/helcel/beans/helper/Visits.kt b/app/src/main/java/net/helcel/beans/helper/Visits.kt index 10eb23d..3d93554 100644 --- a/app/src/main/java/net/helcel/beans/helper/Visits.kt +++ b/app/src/main/java/net/helcel/beans/helper/Visits.kt @@ -27,7 +27,7 @@ class Visits(val id: Int, private val locs: HashMap) { } fun getVisited(key: GeoLoc): Int { - return locs.getOrDefault(key.code, 0) + return getVisited(key.code) } private fun getVisited(key: String): Int {