[m] Cleanup & Intermediate select
This commit is contained in:
parent
77e7893c5f
commit
72a0b73b3f
@ -4,21 +4,23 @@ import android.content.Context
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.CheckBox
|
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.checkbox.MaterialCheckBox
|
||||||
import net.helcel.beendroid.R
|
import net.helcel.beendroid.R
|
||||||
import net.helcel.beendroid.countries.GeoLoc
|
import net.helcel.beendroid.countries.GeoLoc
|
||||||
import net.helcel.beendroid.countries.LocType
|
|
||||||
import net.helcel.beendroid.countries.Visited
|
import net.helcel.beendroid.countries.Visited
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
class FoldingListAdapter(private val ctx: Context, l: List<GeoLoc>, private val visited: Visited) :
|
class FoldingListAdapter(
|
||||||
RecyclerView.Adapter<FoldingListAdapter.FoldingListViewHolder>() {
|
private val ctx: Context, l: List<GeoLoc>,
|
||||||
|
private val visited: Visited,
|
||||||
|
private val parentLambda: () -> Unit,
|
||||||
|
) : RecyclerView.Adapter<FoldingListAdapter.FoldingListViewHolder>() {
|
||||||
|
|
||||||
private var cg : MutableMap<GeoLoc,Boolean> = l.sortedBy { it.fullName }.fold(LinkedHashMap<GeoLoc,Boolean>()) { acc, e ->
|
private var cg : MutableMap<GeoLoc,Boolean> = l.sortedBy { it.fullName }.fold(LinkedHashMap<GeoLoc,Boolean>()) { acc, e ->
|
||||||
acc[e] = false
|
acc[e] = false
|
||||||
@ -34,39 +36,34 @@ class FoldingListAdapter(private val ctx: Context, l: List<GeoLoc>, private val
|
|||||||
|
|
||||||
override fun onBindViewHolder(holder: FoldingListViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: FoldingListViewHolder, position: Int) {
|
||||||
val el = cg.toList()[position]
|
val el = cg.toList()[position]
|
||||||
holder.bind(el)
|
holder.bind(el) {
|
||||||
|
|
||||||
val expandLambda = { _:View ->
|
|
||||||
if (el.first.children.isEmpty() || el.first.type == LocType.STATE) {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
cg[el.first] = !el.second
|
|
||||||
if (!el.second)
|
|
||||||
cg.filter { (it.key != el.first) && (cg[it.key] == true) }.keys.forEach {
|
|
||||||
cg[it] = false
|
|
||||||
notifyItemChanged(cg.toList().map { e -> e.first }.indexOf(it))
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyItemChanged(position)
|
notifyItemChanged(position)
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
holder.addListeners( {
|
||||||
|
if (!el.first.isEnd) {
|
||||||
|
cg[el.first] = !el.second
|
||||||
|
notifyItemChanged(position)
|
||||||
}
|
}
|
||||||
|
!el.first.isEnd
|
||||||
|
}, {
|
||||||
|
visited.setVisited(el.first, it)
|
||||||
|
parentLambda()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
holder.textView.setOnClickListener { holder.checkBox.toggle() }
|
|
||||||
holder.checkBox.setOnCheckedChangeListener{_,e->visited.setVisited(el.first,e)}
|
|
||||||
holder.textView.setOnLongClickListener{ expandLambda(it) }
|
|
||||||
holder.expand.setOnClickListener { expandLambda(it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return cg.size
|
return cg.size
|
||||||
}
|
}
|
||||||
|
|
||||||
class FoldingListViewHolder(private val ctx: Context, itemView: View, private val visited: Visited) : RecyclerView.ViewHolder(itemView) {
|
class FoldingListViewHolder(private val ctx: Context, itemView: View,
|
||||||
val textView: TextView
|
private val visited: Visited,
|
||||||
val expand: ImageView
|
) : RecyclerView.ViewHolder(itemView) {
|
||||||
val checkBox: CheckBox
|
private val textView: TextView
|
||||||
|
private val expand: ImageView
|
||||||
|
private val checkBox: MaterialCheckBox
|
||||||
private val subItemView: View
|
private val subItemView: View
|
||||||
private val list: RecyclerView
|
private val list: RecyclerView
|
||||||
|
|
||||||
@ -78,22 +75,32 @@ class FoldingListAdapter(private val ctx: Context, l: List<GeoLoc>, private val
|
|||||||
subItemView = itemView.findViewById(R.id.sub_item)
|
subItemView = itemView.findViewById(R.id.sub_item)
|
||||||
list = itemView.findViewById(R.id.list_list)
|
list = itemView.findViewById(R.id.list_list)
|
||||||
list.layoutManager = LinearLayoutManager(ctx, RecyclerView.VERTICAL, false)
|
list.layoutManager = LinearLayoutManager(ctx, RecyclerView.VERTICAL, false)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bind(el: Pair<GeoLoc, Boolean>) {
|
fun bind(el: Pair<GeoLoc, Boolean>, parentLambda: () -> Unit) {
|
||||||
expand.rotation = if(el.second) 90f else 0f
|
expand.rotation = if(el.second) 90f else 0f
|
||||||
subItemView.visibility = if (el.second) View.VISIBLE else View.GONE
|
subItemView.visibility = if (el.second) View.VISIBLE else View.GONE
|
||||||
|
expand.visibility = if(!el.first.isEnd) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
textView.text = el.first.fullName
|
textView.text = el.first.fullName
|
||||||
checkBox.isChecked = visited.visited(el.first)
|
checkBox.checkedState =
|
||||||
if(el.first.type == LocType.STATE || el.first.children.isEmpty()){
|
if(visited.visited(el.first)) MaterialCheckBox.STATE_CHECKED
|
||||||
expand.visibility = View.GONE
|
else if (el.first.children.any { visited.visited(it) }) MaterialCheckBox.STATE_INDETERMINATE
|
||||||
return
|
else MaterialCheckBox.STATE_UNCHECKED
|
||||||
}
|
|
||||||
textView.parent.parent.requestChildFocus(textView,textView)
|
textView.parent.parent.requestChildFocus(textView,textView)
|
||||||
list.adapter = FoldingListAdapter(ctx, el.first.children,visited)
|
list.adapter = FoldingListAdapter(ctx, el.first.children,visited, parentLambda)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addListeners(expandLambda: ()->Boolean, visitedLambda: (Boolean)->Unit) {
|
||||||
|
|
||||||
|
textView.setOnClickListener { checkBox.toggle() }
|
||||||
|
checkBox.addOnCheckedStateChangedListener { _, e ->
|
||||||
|
visitedLambda(e == MaterialCheckBox.STATE_CHECKED)
|
||||||
|
}
|
||||||
|
|
||||||
|
textView.setOnLongClickListener{ expandLambda() }
|
||||||
|
expand.setOnClickListener { expandLambda() }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,10 @@ import android.os.Bundle
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.caverock.androidsvg.SVG
|
|
||||||
import com.caverock.androidsvg.SVGImageView
|
import com.caverock.androidsvg.SVGImageView
|
||||||
import net.helcel.beendroid.R
|
import net.helcel.beendroid.R
|
||||||
import net.helcel.beendroid.countries.Country
|
|
||||||
import net.helcel.beendroid.countries.Visited
|
import net.helcel.beendroid.countries.Visited
|
||||||
import net.helcel.beendroid.countries.WORLD
|
|
||||||
import net.helcel.beendroid.countries.World
|
import net.helcel.beendroid.countries.World
|
||||||
import net.helcel.beendroid.svg.Level
|
|
||||||
import net.helcel.beendroid.svg.PSVGWrapper
|
import net.helcel.beendroid.svg.PSVGWrapper
|
||||||
|
|
||||||
|
|
||||||
@ -23,6 +19,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
private lateinit var list : RecyclerView
|
private lateinit var list : RecyclerView
|
||||||
|
|
||||||
private lateinit var visited : Visited
|
private lateinit var visited : Visited
|
||||||
|
private lateinit var psvg : PSVGWrapper
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -30,27 +27,20 @@ class MainActivity : AppCompatActivity() {
|
|||||||
visited = Visited(this)
|
visited = Visited(this)
|
||||||
visited.load()
|
visited.load()
|
||||||
|
|
||||||
|
psvg = PSVGWrapper(this)
|
||||||
|
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
map = findViewById(R.id.map)
|
map = findViewById(R.id.map)
|
||||||
|
|
||||||
|
|
||||||
val cm = HashMap<Country, PSVGWrapper>()
|
|
||||||
Country.values().forEach { c->
|
|
||||||
cm[c] = PSVGWrapper(applicationContext,c, Level.ZERO).load()
|
|
||||||
}
|
|
||||||
|
|
||||||
val fm = cm.values.fold("") { acc, e -> acc + e.data }
|
|
||||||
val svg = SVG.getFromString("<svg id=\"map\" xmlns=\"http://www.w3.org/2000/svg\" width=\"1200\" height=\"1200\" x=\"0\" y=\"0\" >$fm</svg>")
|
|
||||||
|
|
||||||
val bitmap = Bitmap.createBitmap(1200,900, Bitmap.Config.ARGB_8888)
|
val bitmap = Bitmap.createBitmap(1200,900, Bitmap.Config.ARGB_8888)
|
||||||
val canvas = Canvas(bitmap)
|
val canvas = Canvas(bitmap)
|
||||||
canvas.drawRGB(255, 255, 255)
|
canvas.drawRGB(255, 255, 255)
|
||||||
|
|
||||||
svg.renderToCanvas(canvas)
|
psvg.get().renderToCanvas(canvas)
|
||||||
map.setImageBitmap(bitmap)
|
map.setImageBitmap(bitmap)
|
||||||
|
|
||||||
list = findViewById(R.id.list)
|
list = findViewById(R.id.list)
|
||||||
list.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
|
list.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
|
||||||
list.adapter = FoldingListAdapter(this, World.WWW.children, visited)
|
list.adapter = FoldingListAdapter(this, World.WWW.children, visited) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,7 +3,6 @@ package net.helcel.beendroid.countries
|
|||||||
enum class LocType {
|
enum class LocType {
|
||||||
WORLD, GROUP, CUSTOM_GROUP, COUNTRY, STATE;
|
WORLD, GROUP, CUSTOM_GROUP, COUNTRY, STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GeoLoc {
|
interface GeoLoc {
|
||||||
val code : String
|
val code : String
|
||||||
val fullName : String
|
val fullName : String
|
||||||
@ -12,4 +11,6 @@ interface GeoLoc {
|
|||||||
val type : LocType
|
val type : LocType
|
||||||
val children : List<GeoLoc>
|
val children : List<GeoLoc>
|
||||||
|
|
||||||
|
val isEnd: Boolean
|
||||||
|
get() = children.isEmpty() || type == LocType.STATE
|
||||||
}
|
}
|
@ -1,17 +1,6 @@
|
|||||||
package net.helcel.beendroid.countries
|
package net.helcel.beendroid.countries
|
||||||
|
|
||||||
import net.helcel.beendroid.countries.Country.*
|
import net.helcel.beendroid.countries.Country.*
|
||||||
|
|
||||||
val WORLD = listOf(
|
|
||||||
Group.EEE,
|
|
||||||
Group.ABB,
|
|
||||||
Group.FFF,
|
|
||||||
Group.NNN,
|
|
||||||
Group.SRR,
|
|
||||||
Group.UUU,
|
|
||||||
Group.XXX
|
|
||||||
)
|
|
||||||
|
|
||||||
enum class Group(override val fullName: String, override val children: List<Country>) : GeoLoc {
|
enum class Group(override val fullName: String, override val children: List<Country>) : GeoLoc {
|
||||||
|
|
||||||
EEE("Europe",listOf(
|
EEE("Europe",listOf(
|
||||||
|
28
app/src/main/java/net/helcel/beendroid/svg/PSVGLoader.kt
Normal file
28
app/src/main/java/net/helcel/beendroid/svg/PSVGLoader.kt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package net.helcel.beendroid.svg
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import net.helcel.beendroid.countries.Country
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
|
|
||||||
|
class PSVGLoader(private val c: Context, private val country: Country, private var level: Level) {
|
||||||
|
var data = ""
|
||||||
|
|
||||||
|
fun load(): PSVGLoader {
|
||||||
|
data = try {
|
||||||
|
String(
|
||||||
|
c.assets.open("${country.code}_${level.id}.psvg").readBytes(),
|
||||||
|
StandardCharsets.UTF_8
|
||||||
|
)
|
||||||
|
}catch(e: Exception){
|
||||||
|
""
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun changeLevel(level: Level): PSVGLoader {
|
||||||
|
this.level = level
|
||||||
|
this.load()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
@ -1,28 +1,31 @@
|
|||||||
package net.helcel.beendroid.svg
|
package net.helcel.beendroid.svg
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import com.caverock.androidsvg.SVG
|
||||||
import net.helcel.beendroid.countries.Country
|
import net.helcel.beendroid.countries.Country
|
||||||
import java.nio.charset.StandardCharsets
|
|
||||||
|
class PSVGWrapper(ctx: Context) {
|
||||||
|
|
||||||
|
|
||||||
class PSVGWrapper(private val c: Context, private val country: Country, private var level: Level) {
|
|
||||||
var data = ""
|
|
||||||
|
|
||||||
fun load(): PSVGWrapper {
|
private val cm = HashMap<Country, PSVGLoader>()
|
||||||
data = try {
|
|
||||||
String(
|
init {
|
||||||
c.assets.open("${country.code}_${level.id}.psvg").readBytes(),
|
Country.values().forEach {
|
||||||
StandardCharsets.UTF_8
|
cm[it] = PSVGLoader(ctx, it, Level.ZERO).load()
|
||||||
)
|
|
||||||
}catch(e: Exception){
|
|
||||||
""
|
|
||||||
}
|
}
|
||||||
return this
|
}
|
||||||
|
fun level(el: Country, level: Level){
|
||||||
|
cm[el]?.changeLevel(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun changeLevel(level: Level): PSVGWrapper {
|
fun get(): SVG {
|
||||||
this.level = level
|
val fm = cm.values.fold("") { acc, e -> acc + e.data }
|
||||||
this.load()
|
return SVG.getFromString("<svg id=\"map\" xmlns=\"http://www.w3.org/2000/svg\" width=\"1200\" height=\"1200\" x=\"0\" y=\"0\" >$fm</svg>")
|
||||||
return this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -26,12 +26,13 @@
|
|||||||
android:id="@+id/checkBox"
|
android:id="@+id/checkBox"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
app:checkedState="indeterminate"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/textView"
|
app:layout_constraintBottom_toBottomOf="@+id/textView"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintHorizontal_bias="0.844"
|
app:layout_constraintHorizontal_bias="1"
|
||||||
app:layout_constraintStart_toEndOf="@+id/textView"
|
app:layout_constraintStart_toEndOf="@+id/textView"
|
||||||
app:layout_constraintTop_toTopOf="@+id/textView"
|
app:layout_constraintTop_toTopOf="@+id/textView"
|
||||||
app:layout_constraintVertical_bias="0.0" />
|
app:layout_constraintVertical_bias="0.5" />
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
android:id="@+id/textView"
|
android:id="@+id/textView"
|
||||||
|
@ -1,16 +1,5 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<!-- Base application theme. -->
|
<style name="Theme.Beendroid" parent="Theme.Material3.DayNight.NoActionBar">
|
||||||
<style name="Theme.Beendroid" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
<item name="android:statusBarColor">?attr/colorPrimary</item>
|
||||||
<!-- Primary brand color. -->
|
|
||||||
<!-- <item name="colorPrimary">@color/purple_200</item>-->
|
|
||||||
<!-- <item name="colorPrimaryVariant">@color/purple_700</item>-->
|
|
||||||
<!-- <item name="colorOnPrimary">@color/black</item>-->
|
|
||||||
<!-- <!– Secondary brand color. –>-->
|
|
||||||
<!-- <item name="colorSecondary">@color/teal_200</item>-->
|
|
||||||
<!-- <item name="colorSecondaryVariant">@color/teal_200</item>-->
|
|
||||||
<!-- <item name="colorOnSecondary">@color/black</item>-->
|
|
||||||
<!-- Status bar color. -->
|
|
||||||
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
|
|
||||||
<!-- Customize your theme here. -->
|
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
@ -1,17 +1,6 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<!-- Base application theme. -->
|
<style name="Theme.Beendroid" parent="Theme.Material3.DayNight.NoActionBar">
|
||||||
<style name="Theme.Beendroid" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
<item name="android:statusBarColor">?attr/colorPrimary</item>
|
||||||
<!-- Primary brand color. -->
|
|
||||||
<!-- <item name="colorPrimary">@color/purple_500</item>-->
|
|
||||||
<!-- <item name="colorPrimaryVariant">@color/purple_700</item>-->
|
|
||||||
<!-- <item name="colorOnPrimary">@color/white</item>-->
|
|
||||||
<!-- <!– Secondary brand color. –>-->
|
|
||||||
<!-- <item name="colorSecondary">@color/teal_200</item>-->
|
|
||||||
<!-- <item name="colorSecondaryVariant">@color/teal_700</item>-->
|
|
||||||
<!-- <item name="colorOnSecondary">@color/black</item>-->
|
|
||||||
<!-- Status bar color. -->
|
|
||||||
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
|
|
||||||
<!-- Customize your theme here. -->
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Theme.Beendroid.NoActionBar">
|
<style name="Theme.Beendroid.NoActionBar">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user