[m] Cleanup & Intermediate select

This commit is contained in:
choelzl 2023-04-07 12:30:51 +02:00
parent 77e7893c5f
commit 72a0b73b3f
Signed by: sora
GPG Key ID: A362EA0491E2EEA0
9 changed files with 106 additions and 109 deletions

View File

@ -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() }
} }
} }

View File

@ -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) { }
} }
} }

View File

@ -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
} }

View File

@ -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(

View 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
}
}

View File

@ -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
} }
} }

View File

@ -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"

View File

@ -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>-->
<!-- &lt;!&ndash; Secondary brand color. &ndash;&gt;-->
<!-- <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>

View File

@ -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>-->
<!-- &lt;!&ndash; Secondary brand color. &ndash;&gt;-->
<!-- <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">