diff --git a/app/build.gradle b/app/build.gradle index dae90a3..c5547c7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,7 @@ plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' + id 'org.jetbrains.kotlin.plugin.serialization' version '1.9.22' id 'com.mikepenz.aboutlibraries.plugin' version '10.10.0' } @@ -39,12 +40,13 @@ android { dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'com.google.android.material:material:1.11.0' + implementation 'androidx.core:core-ktx:1.12.0' + implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7' implementation 'androidx.navigation:navigation-ui-ktx:2.7.7' - implementation 'androidx.core:core-ktx:1.12.0' - implementation 'androidx.preference:preference-ktx:1.2.1' + implementation 'com.google.android.material:material:1.11.0' + implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' diff --git a/app/src/main/java/net/helcel/beendroid/activity/MainActivity.kt b/app/src/main/java/net/helcel/beendroid/activity/MainActivity.kt index 5362760..d00b676 100644 --- a/app/src/main/java/net/helcel/beendroid/activity/MainActivity.kt +++ b/app/src/main/java/net/helcel/beendroid/activity/MainActivity.kt @@ -17,7 +17,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import net.helcel.beendroid.R import net.helcel.beendroid.activity.fragment.SettingsFragment -import net.helcel.beendroid.helper.Visited import net.helcel.beendroid.svg.CSSWrapper import net.helcel.beendroid.svg.PSVGWrapper @@ -76,14 +75,6 @@ class MainActivity : AppCompatActivity() { }) - // Restore visited countries - visited = Visited(this).load() - groups = Groups(this).load() - - // Wrap lists of countries - psvg = PSVGWrapper(this) - css = CSSWrapper(this,visited!!) - // Populate map from list of countries setContentView(R.layout.activity_main) @@ -91,6 +82,11 @@ class MainActivity : AppCompatActivity() { photoView.minimumScale = 1f photoView.maximumScale = 30f + loadData(this, Int.MIN_VALUE) + + psvg = PSVGWrapper(this) + css = CSSWrapper(this) + refreshMap() } diff --git a/app/src/main/java/net/helcel/beendroid/activity/StatActivity.kt b/app/src/main/java/net/helcel/beendroid/activity/StatActivity.kt index 52e4574..6edebb2 100644 --- a/app/src/main/java/net/helcel/beendroid/activity/StatActivity.kt +++ b/app/src/main/java/net/helcel/beendroid/activity/StatActivity.kt @@ -1,6 +1,7 @@ package net.helcel.beendroid.activity import android.graphics.Color +import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.util.Log import android.view.MenuItem @@ -10,13 +11,13 @@ import com.github.mikephil.charting.data.PieData import com.github.mikephil.charting.data.PieDataSet import com.github.mikephil.charting.data.PieEntry import com.github.mikephil.charting.formatter.PercentFormatter -import com.github.mikephil.charting.utils.ColorTemplate import com.github.mikephil.charting.utils.MPPointF import net.helcel.beendroid.R import net.helcel.beendroid.countries.World import net.helcel.beendroid.helper.colorWrapper import net.helcel.beendroid.helper.createActionBar -import net.helcel.beendroid.helper.visited +import net.helcel.beendroid.helper.groups +import net.helcel.beendroid.helper.visits class StatActivity : AppCompatActivity() { @@ -62,13 +63,13 @@ class StatActivity : AppCompatActivity() { private fun bind() { val entries = ArrayList() - val VIS_continents = World.WWW.children.groupBy { visited!!.getVisited(it) }.map { Pair(it.key,it.value.map { c-> c.area }.fold(0){acc,i-> acc+i}) } - val VIS_country = World.WWW.children.map { it.children }.flatten().groupBy { visited!!.getVisited(it) }.map { Pair(it.key,it.value.map { c-> c.area }.fold(0){acc,i-> acc+i}) } + val VIS_continents = World.WWW.children.groupBy { visits?.getVisited(it)?:0 }.map { Pair(it.key,it.value.map { c-> c.area }.fold(0){ acc, i-> acc+i}) } + val VIS_country = World.WWW.children.map { it.children }.flatten().groupBy { visits!!.getVisited(it) }.map { Pair(it.key,it.value.map { c-> c.area }.fold(0){ acc, i-> acc+i}) } val vis = VIS_country Log.d("VIS",vis.toString()) - val max = vis.fold(0) {acc, i -> acc+i.second} + val max = vis.map{it.second}.fold(0) {acc, i -> acc+i} vis.forEach { - entries.add(PieEntry(it.second.toFloat().div(max.toFloat()),it.first.toString())) + entries.add(PieEntry(it.second.toFloat().div(max.toFloat()),groups!!.getGroupFromKey(it.first)?.name?:"None")) } val dataSet = PieDataSet(entries, "GG1") @@ -77,22 +78,9 @@ class StatActivity : AppCompatActivity() { dataSet.iconsOffset = MPPointF(0f, 40f) dataSet.selectionShift = 5f - // add a lot of colors - val colors = ArrayList() - for (c in ColorTemplate.VORDIPLOM_COLORS) colors.add(c) - - for (c in ColorTemplate.JOYFUL_COLORS) colors.add(c) - - for (c in ColorTemplate.COLORFUL_COLORS) colors.add(c) - - for (c in ColorTemplate.LIBERTY_COLORS) colors.add(c) - - for (c in ColorTemplate.PASTEL_COLORS) colors.add(c) - - colors.add(ColorTemplate.getHoloBlue()) - - dataSet.colors = colors + dataSet.setDrawIcons(true) + dataSet.colors = vis.map{ (groups!!.getGroupFromKey(it.first)?.color?:ColorDrawable(Color.WHITE)).color }.toList() val data = PieData(dataSet) data.setDrawValues(false) diff --git a/app/src/main/java/net/helcel/beendroid/activity/adapter/GeolocListAdapter.kt b/app/src/main/java/net/helcel/beendroid/activity/adapter/GeolocListAdapter.kt index 18f1fec..56fd8a7 100644 --- a/app/src/main/java/net/helcel/beendroid/activity/adapter/GeolocListAdapter.kt +++ b/app/src/main/java/net/helcel/beendroid/activity/adapter/GeolocListAdapter.kt @@ -1,25 +1,29 @@ package net.helcel.beendroid.activity.adapter -import android.content.Context +import android.content.res.ColorStateList +import android.graphics.Color import android.graphics.Typeface import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView +import androidx.fragment.app.FragmentActivity import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.checkbox.MaterialCheckBox import net.helcel.beendroid.R +import net.helcel.beendroid.activity.fragment.EditPlaceColorFragment import net.helcel.beendroid.countries.GeoLoc import net.helcel.beendroid.helper.colorWrapper -import net.helcel.beendroid.helper.visited -import java.util.* - - +import net.helcel.beendroid.helper.groups +import net.helcel.beendroid.helper.saveData +import net.helcel.beendroid.helper.selected_geoloc +import net.helcel.beendroid.helper.selected_group +import net.helcel.beendroid.helper.visits class GeolocListAdapter( - private val ctx: Context, l: List) : RecyclerView.Adapter() { + private val ctx: FragmentActivity, l: List) : RecyclerView.Adapter() { - private val cg : MutableMap = l.sortedBy { it.fullName }.fold(LinkedHashMap()) { acc, e -> + private val cg : MutableMap = l.sortedBy { it.fullName }.fold(LinkedHashMap()) { acc, e -> acc[e] = false acc } @@ -35,22 +39,20 @@ class GeolocListAdapter( val el = cg.toList()[position] holder.bind(el) - holder.addListeners( { + holder.addListeners(el) { if (!el.first.isEnd) { cg[el.first] = !el.second notifyItemChanged(position) } !el.first.isEnd - }, { - visited!!.setVisited(el.first, it) - }) + } } override fun getItemCount(): Int { return cg.size } - class FoldingListViewHolder(private val ctx: Context, itemView: View) : RecyclerView.ViewHolder(itemView) { + class FoldingListViewHolder(private val ctx: FragmentActivity, itemView: View) : RecyclerView.ViewHolder(itemView) { private val textView: TextView = itemView.findViewById(R.id.textView) private val progressView: TextView = itemView.findViewById(R.id.name) private val checkBox: MaterialCheckBox = itemView.findViewById(R.id.checkBox) @@ -72,7 +74,7 @@ class GeolocListAdapter( textView.isActivated = false }else { textView.setTypeface(null, Typeface.BOLD) - progressView.text = ctx.getString(R.string.rate,(el.first.children.map { visited!!.getVisited(it)>0 }.count { it }),el.first.children.size) + progressView.text = ctx.getString(R.string.rate,(el.first.children.map { visits!!.getVisited(it)>0 }.count { it }),el.first.children.size) textView.background = colorWrapper(ctx, android.R.attr.panelColorBackground) textView.background.alpha = 128 @@ -80,18 +82,44 @@ class GeolocListAdapter( list.adapter = GeolocListAdapter(ctx, el.first.children) textView.parent.parent.requestChildFocus(textView, textView) } - checkBox.checkedState = - if (visited!!.getVisited(el.first)>0) MaterialCheckBox.STATE_CHECKED - else if (el.first.children.any { visited!!.getVisited(it)>0 }) MaterialCheckBox.STATE_INDETERMINATE - else MaterialCheckBox.STATE_UNCHECKED + refreshCheck(el.first) } - fun addListeners(expandLambda: ()->Boolean, visitedLambda: (Int)->Unit) { + fun addListeners(el: Pair, expandLambda: () -> Boolean) { textView.setOnClickListener { expandLambda() } - checkBox.addOnCheckedStateChangedListener { _, e -> - visitedLambda( if(e == MaterialCheckBox.STATE_CHECKED) 1 else 0) + checkBox.setOnClickListener { + val dialogFragment = EditPlaceColorFragment(this) + selected_geoloc = el.first + selected_group = null + dialogFragment.show(ctx.supportFragmentManager, "AddColorDialogFragment") } } + fun onColorDialogDismiss(clear: Boolean) { + if(clear){ + visits!!.setVisited(selected_geoloc!!,0) + saveData() + } + if(selected_group!=null && selected_geoloc!=null) { + visits!!.setVisited(selected_geoloc!!, selected_group!!.key) + saveData() + } + selected_geoloc?.let { refreshCheck(it) } + selected_geoloc = null + selected_group = null + } + + private fun refreshCheck(geoLoc: GeoLoc){ + val col = groups!!.getGroupFromKey(visits!!.getVisited(geoLoc))?.color?.color?:Color.WHITE + checkBox.checkedState = + if (visits!!.getVisited(geoLoc)!=0) MaterialCheckBox.STATE_CHECKED + else if (geoLoc.children.any { visits!!.getVisited(it)!=0 }) MaterialCheckBox.STATE_INDETERMINATE + else MaterialCheckBox.STATE_UNCHECKED + + checkBox.buttonTintList = ColorStateList(arrayOf( + intArrayOf(-android.R.attr.state_checked), intArrayOf(android.R.attr.state_checked)), + intArrayOf(col, col)) + } + } } diff --git a/app/src/main/java/net/helcel/beendroid/activity/adapter/GroupListAdapter.kt b/app/src/main/java/net/helcel/beendroid/activity/adapter/GroupListAdapter.kt index 6038a59..2d22de0 100644 --- a/app/src/main/java/net/helcel/beendroid/activity/adapter/GroupListAdapter.kt +++ b/app/src/main/java/net/helcel/beendroid/activity/adapter/GroupListAdapter.kt @@ -1,22 +1,24 @@ package net.helcel.beendroid.activity.adapter -import android.graphics.drawable.ColorDrawable import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button +import androidx.fragment.app.DialogFragment import androidx.fragment.app.FragmentActivity import androidx.recyclerview.widget.RecyclerView import net.helcel.beendroid.R import net.helcel.beendroid.activity.fragment.EditGroupAddFragment +import net.helcel.beendroid.helper.Groups import net.helcel.beendroid.helper.getContrastColor import net.helcel.beendroid.helper.groups +import net.helcel.beendroid.helper.selected_group -class GroupListAdapter(val activity: FragmentActivity) : RecyclerView.Adapter() { +class GroupListAdapter(private val activity: FragmentActivity, private val selectDialog: DialogFragment?) : RecyclerView.Adapter() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) : GroupViewHolder { val view : View = LayoutInflater.from(parent.context).inflate(R.layout.item_list_group, parent, false) - return GroupViewHolder(view, activity) + return GroupViewHolder(view, activity, selectDialog) } override fun onBindViewHolder(holder: GroupViewHolder, pos: Int) { @@ -27,21 +29,29 @@ class GroupListAdapter(val activity: FragmentActivity) : RecyclerView.Adapter>) { - color.text = entry.second.first - color.setBackgroundColor(entry.second.second.color) - color.setTextColor(getContrastColor(entry.second.second.color)) + fun bind(entry: Pair) { + color.text = entry.second.name + color.setBackgroundColor(entry.second.color.color) + color.setTextColor(getContrastColor(entry.second.color.color)) color.setOnClickListener { - val dialogFragment = EditGroupAddFragment(entry.first) { - val newEntry = groups!!.getGroupFromKey(entry.first)!! - color.text = newEntry.first - color.setBackgroundColor(newEntry.second.color) - color.setTextColor(getContrastColor(newEntry.second.color)) + if(selectDialog==null) { + val dialogFragment = EditGroupAddFragment(entry.first) { + val newEntry = groups!!.getGroupFromKey(entry.first)!! + color.text = newEntry.name + color.setBackgroundColor(newEntry.color.color) + color.setTextColor(getContrastColor(newEntry.color.color)) + } + dialogFragment.show( + activity.supportFragmentManager, + "AddColorDialogFragment" + ) + }else{ + selected_group = entry.second + selectDialog.dismiss() } - dialogFragment.show(activity.supportFragmentManager, "AddColorDialogFragment") } } } diff --git a/app/src/main/java/net/helcel/beendroid/activity/fragment/EditGroupAddFragment.kt b/app/src/main/java/net/helcel/beendroid/activity/fragment/EditGroupAddFragment.kt index b8764e4..1132d83 100644 --- a/app/src/main/java/net/helcel/beendroid/activity/fragment/EditGroupAddFragment.kt +++ b/app/src/main/java/net/helcel/beendroid/activity/fragment/EditGroupAddFragment.kt @@ -5,18 +5,34 @@ import android.content.DialogInterface import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher import android.view.View -import android.widget.EditText import androidx.appcompat.app.AlertDialog +import androidx.core.graphics.blue +import androidx.core.graphics.green +import androidx.core.graphics.red import androidx.fragment.app.DialogFragment +import com.google.android.material.slider.Slider +import com.google.android.material.textfield.TextInputEditText import net.helcel.beendroid.R +import net.helcel.beendroid.helper.Groups import net.helcel.beendroid.helper.colorToHex6 import net.helcel.beendroid.helper.groups +import net.helcel.beendroid.helper.saveData +import java.lang.Exception class EditGroupAddFragment(private val key: Int =0, val onAddCb : (Int)->Unit) : DialogFragment() { - private var colorNameEditText: EditText? = null - private var colorEditText: EditText? = null + private lateinit var colorNameEditText: TextInputEditText + private lateinit var colorEditText: TextInputEditText + + private lateinit var colorView : View + + private lateinit var colorEditR : Slider + private lateinit var colorEditG : Slider + private lateinit var colorEditB : Slider + private val grp = groups!!.getGroupFromKey(key) override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val builder = AlertDialog.Builder( @@ -27,18 +43,28 @@ class EditGroupAddFragment(private val key: Int =0, val onAddCb : (Int)->Unit) : colorNameEditText = view.findViewById(R.id.group_name) colorEditText = view.findViewById(R.id.group_color) + colorView = view.findViewById(R.id.colorView) + colorEditR = view.findViewById(R.id.colorR) + colorEditG = view.findViewById(R.id.colorG) + colorEditB = view.findViewById(R.id.colorB) - if(grp!=null){ - view.findViewById(R.id.group_name).setText(grp.first) - view.findViewById(R.id.group_color).setText(colorToHex6(grp.second)) - } + setupSlider(colorEditR,(grp?.color?.color?.red ?: 0)/ 255F) + setupSlider(colorEditG,(grp?.color?.color?.green ?: 0)/ 255F) + setupSlider(colorEditB,(grp?.color?.color?.blue ?: 0)/ 255F) + + setupText(colorEditText,grp) + + colorView.background = ColorDrawable(grp?.color?.color ?: 0) + + + colorNameEditText.setText(grp?.name ?: "") builder.setView(view) - .setTitle("Add Color") - .setPositiveButton("Add") { _: DialogInterface?, _: Int -> - val name = colorNameEditText!!.text.toString() - val color = colorEditText!!.text.toString() + .setPositiveButton("Ok") { _: DialogInterface?, _: Int -> + val name = colorNameEditText.text.toString() + val color = colorEditText.text.toString() val key = (if (key!=0) key else groups!!.genKey()) - groups!!.setGroup(key,name, ColorDrawable(Color.parseColor(color))) + groups!!.setGroup(key,name, ColorDrawable(Color.parseColor("#$color"))) + saveData() onAddCb(key) } .setNegativeButton( @@ -46,4 +72,65 @@ class EditGroupAddFragment(private val key: Int =0, val onAddCb : (Int)->Unit) : ) { dialog: DialogInterface, _: Int -> dialog.cancel() } return builder.create() } -} \ No newline at end of file + + private fun setupText(s: TextInputEditText, grp: Groups.Group?) { + s.setText( colorToHex6(ColorDrawable(grp?.color?.color ?: 0)).substring(1)) + s.addTextChangedListener(EditTextListener(colorEditR, colorEditG, colorEditB, colorEditText, colorView)) + } + + private fun setupSlider(s: Slider, v: Float){ + s.valueFrom = 0F + s.valueTo = 1F + s.value = v + s.addOnChangeListener(SliderOnChangeListener( colorEditR, colorEditG, colorEditB,colorEditText, colorView)) + } + +} + + + +private class EditTextListener( + private val colorEditR: Slider, + private val colorEditG: Slider, + private val colorEditB: Slider, + private val colorEditText: TextInputEditText, + private val colorView: View +): TextWatcher { + + + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + } + + override fun afterTextChanged(s: Editable?) { + val col : Color + try{ + col = Color.valueOf(Color.parseColor("#${colorEditText.text}")) + }catch (e:Exception){ + return + } + + colorEditR.value = col.red() + colorEditG.value = col.green() + colorEditB.value = col.blue() + colorView.background = ColorDrawable(col.toArgb()) + } + +} + +private class SliderOnChangeListener( + private val colorEditR: Slider, + private val colorEditG: Slider, + private val colorEditB: Slider, + private val colorEditText: TextInputEditText, + private val colorView: View +): Slider.OnChangeListener { + override fun onValueChange(slider: Slider, value: Float, fromUser: Boolean) { + val rgb = ColorDrawable(Color.argb(1F,colorEditR.value, colorEditG.value, colorEditB.value)) + colorEditText.setText(colorToHex6(rgb).substring(1)) + colorView.background = rgb + } + +} diff --git a/app/src/main/java/net/helcel/beendroid/activity/fragment/EditGroupFragment.kt b/app/src/main/java/net/helcel/beendroid/activity/fragment/EditGroupFragment.kt index 8861cb6..8ae5341 100644 --- a/app/src/main/java/net/helcel/beendroid/activity/fragment/EditGroupFragment.kt +++ b/app/src/main/java/net/helcel/beendroid/activity/fragment/EditGroupFragment.kt @@ -23,13 +23,12 @@ class EditGroupFragment : Fragment() { ): View { _binding = FragmentEditGroupsBinding.inflate(inflater, container, false) - listadapt = GroupListAdapter(requireActivity()) + listadapt = GroupListAdapter(requireActivity(),null) binding.addGroup.setOnClickListener { val dialogFragment = EditGroupAddFragment { listadapt.notifyItemInserted(groups!!.findGroupPos(it)) } dialogFragment.show(requireActivity().supportFragmentManager, "AddColorDialogFragment") - } binding.list.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) diff --git a/app/src/main/java/net/helcel/beendroid/activity/fragment/EditPlaceColorFragment.kt b/app/src/main/java/net/helcel/beendroid/activity/fragment/EditPlaceColorFragment.kt new file mode 100644 index 0000000..852f745 --- /dev/null +++ b/app/src/main/java/net/helcel/beendroid/activity/fragment/EditPlaceColorFragment.kt @@ -0,0 +1,42 @@ +package net.helcel.beendroid.activity.fragment + +import android.app.Dialog +import android.content.DialogInterface +import android.os.Bundle +import android.view.View +import androidx.appcompat.app.AlertDialog +import androidx.fragment.app.DialogFragment +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import net.helcel.beendroid.R +import net.helcel.beendroid.activity.adapter.GeolocListAdapter +import net.helcel.beendroid.activity.adapter.GroupListAdapter + + +class EditPlaceColorFragment(private val parent: GeolocListAdapter.FoldingListViewHolder) : DialogFragment() { + private lateinit var listAdapt : GroupListAdapter + private lateinit var list : RecyclerView + private var clear : Boolean = false + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val builder = AlertDialog.Builder( + requireActivity() + ) + val inflater = requireActivity().layoutInflater + val view: View = inflater.inflate(R.layout.fragment_edit_places_colors, null) + + val dialog = builder.setView(view).setNegativeButton("Clear") { dialogInterface: DialogInterface, i: Int -> clear = true } + .create() + listAdapt = GroupListAdapter(requireActivity(),this) + list = view.findViewById(R.id.groups_color)!! + list.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) + list.adapter = listAdapt + + return dialog + } + + override fun onDismiss(dialog: DialogInterface) { + super.onDismiss(dialog) + parent.onColorDialogDismiss(clear) + } +} diff --git a/app/src/main/java/net/helcel/beendroid/activity/fragment/EditPlaceFragment.kt b/app/src/main/java/net/helcel/beendroid/activity/fragment/EditPlaceFragment.kt index e6a3eb7..b10aa34 100644 --- a/app/src/main/java/net/helcel/beendroid/activity/fragment/EditPlaceFragment.kt +++ b/app/src/main/java/net/helcel/beendroid/activity/fragment/EditPlaceFragment.kt @@ -23,7 +23,7 @@ class EditPlaceFragment : Fragment() { _binding = FragmentEditPlacesBinding.inflate(inflater, container, false) binding.list.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) - binding.list.adapter = GeolocListAdapter(requireContext(), World.WWW.children) + binding.list.adapter = GeolocListAdapter(requireActivity(), World.WWW.children) return binding.root } diff --git a/app/src/main/java/net/helcel/beendroid/countries/GeoLoc.kt b/app/src/main/java/net/helcel/beendroid/countries/GeoLoc.kt index 22f115a..fc40ccc 100644 --- a/app/src/main/java/net/helcel/beendroid/countries/GeoLoc.kt +++ b/app/src/main/java/net/helcel/beendroid/countries/GeoLoc.kt @@ -3,6 +3,7 @@ package net.helcel.beendroid.countries enum class LocType { WORLD, GROUP, CUSTOM_GROUP, COUNTRY, STATE; } + interface GeoLoc { val code : String val fullName : String diff --git a/app/src/main/java/net/helcel/beendroid/helper/Data.kt b/app/src/main/java/net/helcel/beendroid/helper/Data.kt index 9c184cb..58b3e24 100644 --- a/app/src/main/java/net/helcel/beendroid/helper/Data.kt +++ b/app/src/main/java/net/helcel/beendroid/helper/Data.kt @@ -1,5 +1,36 @@ package net.helcel.beendroid.helper +import android.content.Context +import android.content.SharedPreferences +import androidx.preference.PreferenceManager +import net.helcel.beendroid.countries.GeoLoc -var visited : Visited? = null +var visits : Visits? = null var groups : Groups? = null + +var selected_group : Groups.Group? = null +var selected_geoloc: GeoLoc? = null + +val groupsSerial = Groups.GroupsSerializer() +val visitsSerial = Visits.VisitsSerializer() + +private var sharedPreferences: SharedPreferences? = null + +fun loadData(ctx: Context, id:Int) { + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ctx) + + val groupsString = sharedPreferences!!.getString("groups_$id",null) + val visitsString = sharedPreferences!!.getString("visits_$id",null) + + groups = if(!groupsString.isNullOrEmpty()) groupsSerial.readFrom(groupsString.byteInputStream()) else groupsSerial.defaultValue + visits = if(!visitsString.isNullOrEmpty()) visitsSerial.readFrom(visitsString.byteInputStream()) else visitsSerial.defaultValue +} + +fun saveData() { + if(groups!!.id != visits!!.id) return + val id = groups!!.id + val editor = sharedPreferences!!.edit() + editor.putString("groups_$id", groupsSerial.writeTo(groups!!)) + editor.putString("visits_$id", visitsSerial.writeTo(visits!!)) + editor.apply() +} \ No newline at end of file diff --git a/app/src/main/java/net/helcel/beendroid/helper/Groups.kt b/app/src/main/java/net/helcel/beendroid/helper/Groups.kt index 450b1be..e0d30cd 100644 --- a/app/src/main/java/net/helcel/beendroid/helper/Groups.kt +++ b/app/src/main/java/net/helcel/beendroid/helper/Groups.kt @@ -1,35 +1,24 @@ package net.helcel.beendroid.helper -import android.content.Context -import android.graphics.Color import android.graphics.drawable.ColorDrawable +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.Serializable +import kotlinx.serialization.Serializer +import kotlinx.serialization.json.Json +import java.io.InputStream import kotlin.random.Random -class Groups(ctx: Context) { - private val randSeed = 0 - private val rnd = Random(randSeed) - private var grps: MutableMap> = HashMap() - private val pref = ctx.getSharedPreferences("Groups", Context.MODE_PRIVATE) - private val editor = pref.edit() - - fun load(): Groups { - pref.all.keys.filter { !it.endsWith("_color") }.forEach { - grps[it.toInt()] = Pair(pref.getString(it, "")!!, - ColorDrawable(pref.getInt(it+"_color", Color.WHITE))) - } - editor.apply() - return this - } +private const val randSeed = 0 +private val rnd = Random(randSeed) +@Serializable +class Groups(val id: Int, private val grps: HashMap) { fun setGroup(key: Int, name: String, col: ColorDrawable) { - grps[key] = Pair(name,col) - editor.putString(key.toString(), name) - editor.putInt(key.toString()+"_color", col.color) - editor.apply() + grps[key] = Group(key,name,col) } - fun getGroupFromKey(key: Int): Pair? { + fun getGroupFromKey(key: Int): Group? { return grps.getOrDefault(key,null) } @@ -43,7 +32,7 @@ class Groups(ctx: Context) { return grps.size } - fun getGroupFromPos(pos: Int): Pair> { + fun getGroupFromPos(pos: Int): Pair { val key = grps.keys.toList()[pos] return Pair(key,getGroupFromKey(key)!!) } @@ -52,4 +41,23 @@ class Groups(ctx: Context) { return grps.keys.toList().indexOf(key) } + @Serializable + class Group(val key: Int, val name: String, @Serializable(with = ColorDrawableSerializer::class) val color: ColorDrawable) + + @OptIn(ExperimentalSerializationApi::class) + @Serializer(Groups::class) + class GroupsSerializer{ + val defaultValue: Groups + get() = Groups(Int.MIN_VALUE,hashMapOf()) + + fun readFrom(input: InputStream): Groups { + return Json.decodeFromString(serializer(),input.readBytes().decodeToString()) + } + + fun writeTo(t: Groups): String { + return Json.encodeToString(serializer(),t).encodeToByteArray().decodeToString() + } + + } + } \ No newline at end of file diff --git a/app/src/main/java/net/helcel/beendroid/helper/Various.kt b/app/src/main/java/net/helcel/beendroid/helper/Various.kt new file mode 100644 index 0000000..bb72011 --- /dev/null +++ b/app/src/main/java/net/helcel/beendroid/helper/Various.kt @@ -0,0 +1,20 @@ +package net.helcel.beendroid.helper + +import android.graphics.drawable.ColorDrawable +import kotlinx.serialization.KSerializer +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder + +object ColorDrawableSerializer : KSerializer { + override val descriptor = PrimitiveSerialDescriptor("ColorDrawable", PrimitiveKind.INT) + + override fun deserialize(decoder: Decoder): ColorDrawable { + return ColorDrawable(decoder.decodeInt()) + } + + override fun serialize(encoder: Encoder, value: ColorDrawable) { + encoder.encodeInt(value.color) + } +} \ No newline at end of file diff --git a/app/src/main/java/net/helcel/beendroid/helper/Visited.kt b/app/src/main/java/net/helcel/beendroid/helper/Visited.kt deleted file mode 100644 index d1c62df..0000000 --- a/app/src/main/java/net/helcel/beendroid/helper/Visited.kt +++ /dev/null @@ -1,52 +0,0 @@ -package net.helcel.beendroid.helper - -import android.content.Context -import net.helcel.beendroid.countries.Country -import net.helcel.beendroid.countries.GeoLoc -import net.helcel.beendroid.countries.Group -import net.helcel.beendroid.countries.State -import java.lang.ClassCastException - - -class Visited(ctx: Context) { - private var locs: MutableMap = HashMap() - private val pref = ctx.getSharedPreferences("Visited", Context.MODE_PRIVATE) - private val editor = pref.edit() - - fun load(): Visited { - Group.entries.forEach { - try { - locs[it] = pref.getInt(it.code, 0) - }catch (e:ClassCastException){ - locs[it] = if (pref.getBoolean(it.code, false)) 1 else 0 - } - } - Country.entries.forEach { - try { - locs[it] = pref.getInt(it.code, 0) - }catch (e:ClassCastException){ - locs[it] = if (pref.getBoolean(it.code, false)) 1 else 0 - } - } - State.entries.forEach { - try { - locs[it] = pref.getInt(it.code, 0) - }catch (e:ClassCastException){ - locs[it] = if (pref.getBoolean(it.code, false)) 1 else 0 - } - } - editor.apply() - return this - } - - fun setVisited(key: GeoLoc, b: Int) { - locs[key] = b - editor.putInt(key.code, b) - editor.apply() - } - - fun getVisited(key: GeoLoc): Int { - return locs.getOrDefault(key,0) - } - -} \ No newline at end of file diff --git a/app/src/main/java/net/helcel/beendroid/helper/Visits.kt b/app/src/main/java/net/helcel/beendroid/helper/Visits.kt new file mode 100644 index 0000000..a5be13a --- /dev/null +++ b/app/src/main/java/net/helcel/beendroid/helper/Visits.kt @@ -0,0 +1,38 @@ +package net.helcel.beendroid.helper + +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.Serializable +import kotlinx.serialization.Serializer +import kotlinx.serialization.json.Json +import net.helcel.beendroid.countries.GeoLoc +import java.io.InputStream + + +@Serializable +class Visits(val id: Int, private val locs: HashMap) { + + fun setVisited(key: GeoLoc, b: Int) { + locs[key.code] = b + } + + fun getVisited(key: GeoLoc): Int { + return locs.getOrDefault(key.code,0) + } + + @OptIn(ExperimentalSerializationApi::class) + @Serializer(Visits::class) + class VisitsSerializer { + val defaultValue: Visits + get() = Visits(Int.MIN_VALUE,hashMapOf()) + + fun readFrom(input: InputStream): Visits { + return Json.decodeFromString(serializer(),input.readBytes().decodeToString()) + } + + fun writeTo(t: Visits): String { + return Json.encodeToString(serializer(),t).encodeToByteArray().decodeToString() + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/net/helcel/beendroid/svg/CSSWrapper.kt b/app/src/main/java/net/helcel/beendroid/svg/CSSWrapper.kt index b64cf9f..4e754b3 100644 --- a/app/src/main/java/net/helcel/beendroid/svg/CSSWrapper.kt +++ b/app/src/main/java/net/helcel/beendroid/svg/CSSWrapper.kt @@ -1,26 +1,25 @@ package net.helcel.beendroid.svg import android.content.Context -import net.helcel.beendroid.helper.Visited import net.helcel.beendroid.countries.World import net.helcel.beendroid.helper.colorToHex6 import net.helcel.beendroid.helper.colorWrapper +import net.helcel.beendroid.helper.groups +import net.helcel.beendroid.helper.visits -class CSSWrapper(ctx: Context, private val visited: Visited) { +class CSSWrapper(ctx: Context) { - private val visitedColor = colorToHex6(colorWrapper(ctx,android.R.attr.colorPrimary)) - fun get() : String { return listOf(World.WWW.children - .filter { visited.getVisited(it)>0} - .map { ".${it.code}{fill:$visitedColor;}"} + .filter { visits!!.getVisited(it)!=0} + .map { ".${it.code}{fill:${colorToHex6(groups!!.getGroupFromKey(visits!!.getVisited(it))!!.color)};}"} .fold(""){acc, s-> acc + s}, World.WWW.children - .filter { visited.getVisited(it)==0 } + .filter { visits!!.getVisited(it)==0 } .map { cg -> cg.children - .filter { visited.getVisited(it)>0 } - .map { ".${it.code}{fill:$visitedColor;}"} + .filter { visits!!.getVisited(it)!=0 } + .map { ".${it.code}{fill:${colorToHex6(groups!!.getGroupFromKey(visits!!.getVisited(it))!!.color)};}"} .fold(""){acc, s-> acc + s} }.fold(""){acc,s->acc+s}, ).fold(""){acc,s-> acc+s} diff --git a/app/src/main/java/net/helcel/beendroid/svg/PSVGWrapper.kt b/app/src/main/java/net/helcel/beendroid/svg/PSVGWrapper.kt index be614c5..88f794d 100644 --- a/app/src/main/java/net/helcel/beendroid/svg/PSVGWrapper.kt +++ b/app/src/main/java/net/helcel/beendroid/svg/PSVGWrapper.kt @@ -23,10 +23,6 @@ class PSVGWrapper(ctx: Context) { build() } - fun level(el: Country, level: Level){ - cm[el]?.changeLevel(level) - } - private fun build(){ fm = World.WWW.children.map { gr -> gr.children.map {c -> diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml similarity index 95% rename from app/src/main/res/drawable-v24/ic_launcher_foreground.xml rename to app/src/main/res/drawable/ic_launcher_foreground.xml index d3144e3..3c49f59 100644 --- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -5,7 +5,7 @@ android:viewportHeight="1600"> - + android:inputType="text" + android:autofillHints="" /> - + android:layout_height="match_parent"> + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_edit_places_colors.xml b/app/src/main/res/layout/fragment_edit_places_colors.xml new file mode 100644 index 0000000..6e3ae40 --- /dev/null +++ b/app/src/main/res/layout/fragment_edit_places_colors.xml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v28/ic_launcher.xml similarity index 93% rename from app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml rename to app/src/main/res/mipmap-anydpi-v28/ic_launcher.xml index 6f3b755..50ec886 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v28/ic_launcher.xml @@ -1,6 +1,6 @@ - - - + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v28/ic_launcher_round.xml similarity index 75% rename from app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to app/src/main/res/mipmap-anydpi-v28/ic_launcher_round.xml index eca70cf..50ec886 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app/src/main/res/mipmap-anydpi-v28/ic_launcher_round.xml @@ -1,5 +1,6 @@ - - + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v33/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v33/ic_launcher.xml deleted file mode 100644 index 6f3b755..0000000 --- a/app/src/main/res/mipmap-anydpi-v33/ic_launcher.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp deleted file mode 100644 index c209e78..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp deleted file mode 100644 index b2dfe3d..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp deleted file mode 100644 index 4f0f1d6..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp deleted file mode 100644 index 62b611d..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp deleted file mode 100644 index 948a307..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp deleted file mode 100644 index 1b9a695..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp deleted file mode 100644 index 28d4b77..0000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp deleted file mode 100644 index 9287f50..0000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp deleted file mode 100644 index aa7d642..0000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp deleted file mode 100644 index 9126ae3..0000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index aa4a009..bfb470c 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,6 +3,16 @@ #FF000000 #FF0C1D2E #FF93A9BE - #FF3193F5 #FFFFFFFF + + #F59331 + #F5F531 + #93F531 + #31F593 + #3193F5 + #9331F5 + #F53193 + #F53131 + + diff --git a/app/src/main/res/values/en.xml b/app/src/main/res/values/en.xml index 4c13a0b..7e742f2 100644 --- a/app/src/main/res/values/en.xml +++ b/app/src/main/res/values/en.xml @@ -21,5 +21,5 @@ Logo Name %1$d/%2$d - Color (#RRGGBB) + RRGGBB \ 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 55344e5..ec731f6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,4 @@ + # \ No newline at end of file