Cleanup and Colors
@@ -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'
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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<PieEntry>()
 | 
			
		||||
        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<Int>()
 | 
			
		||||
 | 
			
		||||
        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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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<GeoLoc>) : RecyclerView.Adapter<GeolocListAdapter.FoldingListViewHolder>()  {
 | 
			
		||||
    private val ctx: FragmentActivity, l: List<GeoLoc>) : RecyclerView.Adapter<GeolocListAdapter.FoldingListViewHolder>()  {
 | 
			
		||||
 | 
			
		||||
    private val cg : MutableMap<GeoLoc,Boolean> = l.sortedBy { it.fullName }.fold(LinkedHashMap<GeoLoc,Boolean>()) { acc, e ->
 | 
			
		||||
    private val cg : MutableMap<GeoLoc,Boolean> = 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<GeoLoc, Boolean>, 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))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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<GroupListAdapter.GroupViewHolder>()  {
 | 
			
		||||
class GroupListAdapter(private val activity: FragmentActivity, private val selectDialog: DialogFragment?) : RecyclerView.Adapter<GroupListAdapter.GroupViewHolder>()  {
 | 
			
		||||
 | 
			
		||||
    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<Gr
 | 
			
		||||
        return groups!!.size()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class GroupViewHolder(itemView: View, val activity: FragmentActivity) : RecyclerView.ViewHolder(itemView) {
 | 
			
		||||
    class GroupViewHolder(itemView: View, private val activity: FragmentActivity, private val selectDialog: DialogFragment?) : RecyclerView.ViewHolder(itemView) {
 | 
			
		||||
        private val color: Button = itemView.findViewById(R.id.group_color)
 | 
			
		||||
 | 
			
		||||
        fun bind(entry: Pair<Int, Pair<String, ColorDrawable>>) {
 | 
			
		||||
            color.text = entry.second.first
 | 
			
		||||
            color.setBackgroundColor(entry.second.second.color)
 | 
			
		||||
            color.setTextColor(getContrastColor(entry.second.second.color))
 | 
			
		||||
        fun bind(entry: Pair<Int, Groups.Group>) {
 | 
			
		||||
            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")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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<EditText>(R.id.group_name).setText(grp.first)
 | 
			
		||||
            view.findViewById<EditText>(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()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
}
 | 
			
		||||
@@ -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<Int,Pair<String, ColorDrawable>> = 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<Int,Group>) {
 | 
			
		||||
 | 
			
		||||
    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<String,ColorDrawable>? {
 | 
			
		||||
    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<Int,Pair<String,ColorDrawable>> {
 | 
			
		||||
    fun getGroupFromPos(pos: Int): Pair<Int,Group> {
 | 
			
		||||
        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()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								app/src/main/java/net/helcel/beendroid/helper/Various.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -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<ColorDrawable> {
 | 
			
		||||
    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)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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<GeoLoc, Int> = 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)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								app/src/main/java/net/helcel/beendroid/helper/Visits.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -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<String,Int>) {
 | 
			
		||||
 | 
			
		||||
    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()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -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}
 | 
			
		||||
 
 | 
			
		||||
@@ -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 ->
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
    android:viewportHeight="1600">
 | 
			
		||||
 | 
			
		||||
    <path
 | 
			
		||||
        android:fillColor="?attr/colorPrimary"
 | 
			
		||||
        android:fillColor="@color/blue"
 | 
			
		||||
        android:fillType="nonZero"
 | 
			
		||||
        android:pathData="m800,1200q-83,0 -156,-31.5Q571,1137 517,1083 463,1029 431.5,956 400,883 400,800 400,717 431.5,644 463,571 517,517 571,463 644,431.5 717,400 800,400q83,0 156,31.5 73,31.5 127,85.5 54,54 85.5,127 31.5,73 31.5,156 0,83 -31.5,156 -31.5,73 -85.5,127 -54,54 -127,85.5 -73,31.5 -156,31.5zM800,1120q134,0 227,-93 93,-93 93,-227 0,-7 -0.5,-14.5 -0.5,-7.5 -0.5,-12.5 -5,29 -27,48 -22,19 -52,19L960,840Q927,840 903.5,816.5 880,793 880,760L880,720L720,720v-80q0,-33 23.5,-56.5Q767,560 800,560h40v0q0,-23 12.5,-40.5Q865,502 883,491q-20,-5 -40.5,-8 -20.5,-3 -42.5,-3 -134,0 -227,93 -93,93 -93,227 0,0 0,0 0,0 0,0h200q66,0 113,47 47,47 47,113v40L720,1000v110q20,5 39.5,7.5 19.5,2.5 40.5,2.5z"
 | 
			
		||||
        android:strokeWidth="1"
 | 
			
		||||
@@ -1,22 +1,87 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="wrap_content"
 | 
			
		||||
    android:orientation="vertical"
 | 
			
		||||
    android:padding="16dp">
 | 
			
		||||
 | 
			
		||||
    <EditText
 | 
			
		||||
    <com.google.android.material.textfield.TextInputEditText
 | 
			
		||||
        android:id="@+id/group_name"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:hint="@string/name"
 | 
			
		||||
        android:inputType="text" />
 | 
			
		||||
        android:inputType="text"
 | 
			
		||||
        android:autofillHints="" />
 | 
			
		||||
 | 
			
		||||
    <EditText
 | 
			
		||||
        android:id="@+id/group_color"
 | 
			
		||||
    <androidx.constraintlayout.widget.ConstraintLayout
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:hint="@string/color_rrggbb"
 | 
			
		||||
        android:inputType="text" />
 | 
			
		||||
        android:layout_height="match_parent">
 | 
			
		||||
 | 
			
		||||
        <View
 | 
			
		||||
            android:id="@+id/colorView"
 | 
			
		||||
            android:layout_width="0dp"
 | 
			
		||||
            android:layout_height="0dp"
 | 
			
		||||
            app:layout_constraintBottom_toBottomOf="parent"
 | 
			
		||||
            app:layout_constraintEnd_toStartOf="@+id/colorR"
 | 
			
		||||
            app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
            app:layout_constraintTop_toTopOf="parent"
 | 
			
		||||
            android:background="?attr/background"/>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        <com.google.android.material.slider.Slider
 | 
			
		||||
            android:id="@+id/colorR"
 | 
			
		||||
            android:layout_width="0dp"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            app:layout_constraintBottom_toTopOf="@id/colorG"
 | 
			
		||||
            app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
            app:layout_constraintStart_toEndOf="@id/colorView"
 | 
			
		||||
            app:layout_constraintTop_toTopOf="parent"
 | 
			
		||||
            app:thumbColor="@color/red"
 | 
			
		||||
            app:trackColorActive="@color/red" />
 | 
			
		||||
 | 
			
		||||
        <com.google.android.material.slider.Slider
 | 
			
		||||
            android:id="@+id/colorG"
 | 
			
		||||
            android:layout_width="0dp"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:foregroundTint="#FF0000"
 | 
			
		||||
            app:layout_constraintBottom_toTopOf="@id/colorB"
 | 
			
		||||
            app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
            app:layout_constraintStart_toEndOf="@id/colorView"
 | 
			
		||||
            app:layout_constraintTop_toBottomOf="@id/colorR"
 | 
			
		||||
            app:thumbColor="@color/green"
 | 
			
		||||
            app:trackColorActive="@color/green" />
 | 
			
		||||
 | 
			
		||||
        <com.google.android.material.slider.Slider
 | 
			
		||||
            android:id="@+id/colorB"
 | 
			
		||||
            android:layout_width="0dp"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            app:layout_constraintBottom_toBottomOf="parent"
 | 
			
		||||
            app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
            app:layout_constraintStart_toEndOf="@id/colorView"
 | 
			
		||||
            app:layout_constraintTop_toBottomOf="@id/colorG"
 | 
			
		||||
            app:thumbColor="@color/blue"
 | 
			
		||||
            app:trackColorActive="@color/blue" />
 | 
			
		||||
 | 
			
		||||
    </androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="match_parent">
 | 
			
		||||
        <com.google.android.material.textview.MaterialTextView
 | 
			
		||||
            android:id="@+id/textView"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:labelFor="@id/group_color"
 | 
			
		||||
            android:text="@string/hashtag"/>
 | 
			
		||||
 | 
			
		||||
        <com.google.android.material.textfield.TextInputEditText
 | 
			
		||||
            android:id="@+id/group_color"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:autofillHints=""
 | 
			
		||||
            android:hint="@string/color_rrggbb"
 | 
			
		||||
            android:inputType="text"
 | 
			
		||||
            android:maxLength="6" />
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
</LinearLayout>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								app/src/main/res/layout/fragment_edit_places_colors.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,17 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<ScrollView
 | 
			
		||||
    xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent" >
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:orientation="vertical"
 | 
			
		||||
        android:padding="16dp">
 | 
			
		||||
        <androidx.recyclerview.widget.RecyclerView
 | 
			
		||||
            android:id="@+id/groups_color"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"/>
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
</ScrollView>
 | 
			
		||||
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
 | 
			
		||||
    <background android:drawable="@drawable/ic_launcher_background" />
 | 
			
		||||
    <foreground android:drawable="@drawable/ic_launcher_foreground" />
 | 
			
		||||
    <monochrome android:drawable="@drawable/ic_launcher_foreground" />
 | 
			
		||||
    <background android:drawable="@drawable/ic_launcher_background"/>
 | 
			
		||||
    <foreground android:drawable="@drawable/ic_launcher_foreground"/>
 | 
			
		||||
    <monochrome android:drawable="@drawable/ic_launcher_foreground"/>
 | 
			
		||||
</adaptive-icon>
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
 | 
			
		||||
    <background android:drawable="@drawable/ic_launcher_background" />
 | 
			
		||||
    <foreground android:drawable="@drawable/ic_launcher_foreground" />
 | 
			
		||||
    <background android:drawable="@drawable/ic_launcher_background"/>
 | 
			
		||||
    <foreground android:drawable="@drawable/ic_launcher_foreground"/>
 | 
			
		||||
    <monochrome android:drawable="@drawable/ic_launcher_foreground"/>
 | 
			
		||||
</adaptive-icon>
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
 | 
			
		||||
    <background android:drawable="@drawable/ic_launcher_background" />
 | 
			
		||||
    <foreground android:drawable="@drawable/ic_launcher_foreground" />
 | 
			
		||||
    <monochrome android:drawable="@drawable/ic_launcher_foreground" />
 | 
			
		||||
</adaptive-icon>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 1.4 KiB  | 
| 
		 Before Width: | Height: | Size: 2.8 KiB  | 
| 
		 Before Width: | Height: | Size: 982 B  | 
| 
		 Before Width: | Height: | Size: 1.7 KiB  | 
| 
		 Before Width: | Height: | Size: 1.9 KiB  | 
| 
		 Before Width: | Height: | Size: 3.8 KiB  | 
| 
		 Before Width: | Height: | Size: 2.8 KiB  | 
| 
		 Before Width: | Height: | Size: 5.8 KiB  | 
| 
		 Before Width: | Height: | Size: 3.8 KiB  | 
| 
		 Before Width: | Height: | Size: 7.6 KiB  | 
@@ -3,6 +3,16 @@
 | 
			
		||||
    <color name="black">#FF000000</color>
 | 
			
		||||
    <color name="darkgray">#FF0C1D2E</color>
 | 
			
		||||
    <color name="lightgray">#FF93A9BE</color>
 | 
			
		||||
    <color name="blue">#FF3193F5</color>
 | 
			
		||||
    <color name="white">#FFFFFFFF</color>
 | 
			
		||||
 | 
			
		||||
    <color name="orange">#F59331</color>
 | 
			
		||||
    <color name="yellow">#F5F531</color>
 | 
			
		||||
    <color name="green">#93F531</color>
 | 
			
		||||
    <color name="turquoise">#31F593</color>
 | 
			
		||||
    <color name="blue">#3193F5</color>
 | 
			
		||||
    <color name="purple">#9331F5</color>
 | 
			
		||||
    <color name="pink">#F53193</color>
 | 
			
		||||
    <color name="red">#F53131</color>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -21,5 +21,5 @@
 | 
			
		||||
    <string name="logo">Logo</string>
 | 
			
		||||
    <string name="name">Name</string>
 | 
			
		||||
    <string name="rate">%1$d/%2$d</string>
 | 
			
		||||
    <string name="color_rrggbb">Color (#RRGGBB)</string>
 | 
			
		||||
    <string name="color_rrggbb">RRGGBB</string>
 | 
			
		||||
</resources>
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="hashtag">#</string>
 | 
			
		||||
</resources>
 | 
			
		||||