Compare commits
	
		
			2 Commits
		
	
	
		
			0.1a-rc2
			...
			6e5e5c944f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 6e5e5c944f | ||
|  | 44b0cccbd9 | 
| @@ -5,12 +5,12 @@ plugins { | |||||||
|  |  | ||||||
| android { | android { | ||||||
|     namespace 'net.helcel.beendroid' |     namespace 'net.helcel.beendroid' | ||||||
|     compileSdk 33 |     compileSdk 34 | ||||||
|  |  | ||||||
|     defaultConfig { |     defaultConfig { | ||||||
|         applicationId 'net.helcel.beendroid' |         applicationId 'net.helcel.beendroid' | ||||||
|         minSdk 28 |         minSdk 28 | ||||||
|         targetSdk 33 |         targetSdk 34 | ||||||
|         versionCode 1 |         versionCode 1 | ||||||
|         versionName "1.0" |         versionName "1.0" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,14 +16,21 @@ | |||||||
|         > |         > | ||||||
|         <activity |         <activity | ||||||
|             android:name=".activity.MainActivity" |             android:name=".activity.MainActivity" | ||||||
|             android:exported="true" |             android:exported="true" > | ||||||
|             android:theme="@style/Theme.Beendroid.NoActionBar"> |  | ||||||
|             <intent-filter> |             <intent-filter> | ||||||
|                 <action android:name="android.intent.action.MAIN" /> |                 <action android:name="android.intent.action.MAIN" /> | ||||||
|  |  | ||||||
|                 <category android:name="android.intent.category.LAUNCHER" /> |                 <category android:name="android.intent.category.LAUNCHER" /> | ||||||
|             </intent-filter> |             </intent-filter> | ||||||
|         </activity> |         </activity> | ||||||
|  |         <activity | ||||||
|  |             android:name=".activity.SettingsActivity" | ||||||
|  |             android:exported="true" > | ||||||
|  |             <intent-filter> | ||||||
|  |                 <action android:name="android.intent.action.MAIN" /> | ||||||
|  |                 <category android:name="android.intent.category.LAUNCHER" /> | ||||||
|  |             </intent-filter> | ||||||
|  |         </activity> | ||||||
|  |  | ||||||
|     </application> |     </application> | ||||||
|  |  | ||||||
| </manifest> | </manifest> | ||||||
| @@ -1,17 +1,24 @@ | |||||||
| package net.helcel.beendroid.activity | package net.helcel.beendroid.activity | ||||||
|  |  | ||||||
| import android.content.Context | import android.content.Context | ||||||
|  | import android.graphics.Color | ||||||
|  | import android.graphics.Typeface | ||||||
|  | import android.graphics.drawable.ColorDrawable | ||||||
|  | import android.util.Log | ||||||
|  | import android.util.TypedValue | ||||||
| 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.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.getDrawable | ||||||
| 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.button.MaterialButton | ||||||
| import com.google.android.material.checkbox.MaterialCheckBox | 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.* | ||||||
|  |  | ||||||
| @@ -61,15 +68,14 @@ class FoldingListAdapter( | |||||||
|                                 private val visited: Visited, |                                 private val visited: Visited, | ||||||
|                                 ) : RecyclerView.ViewHolder(itemView) { |                                 ) : RecyclerView.ViewHolder(itemView) { | ||||||
|         private val textView: TextView |         private val textView: TextView | ||||||
|         private val expand: ImageView |         //private val expand: MaterialButton | ||||||
|         private val checkBox: MaterialCheckBox |         private val checkBox: MaterialCheckBox | ||||||
|         private val subItemView: View |         private val subItemView: View | ||||||
|         private val list: RecyclerView |         private val list: RecyclerView | ||||||
|  |  | ||||||
|         init { |         init { | ||||||
|             textView = itemView.findViewById(R.id.textView) |             textView = itemView.findViewById(R.id.textView) | ||||||
|             expand = itemView.findViewById(R.id.expand) |             //expand = itemView.findViewById(R.id.expand) | ||||||
|             expand.setImageDrawable(AppCompatResources.getDrawable(ctx,R.drawable.chevron_right_solid)) |  | ||||||
|             checkBox = itemView.findViewById(R.id.checkBox) |             checkBox = itemView.findViewById(R.id.checkBox) | ||||||
|             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) | ||||||
| @@ -77,11 +83,40 @@ class FoldingListAdapter( | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         fun bind(el: Pair<GeoLoc, Boolean>, parentLambda: () -> Unit) { |         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 |             //expand.visibility = if(!el.first.isEnd) View.VISIBLE else View.INVISIBLE | ||||||
|  |  | ||||||
|             textView.text = el.first.fullName |             textView.text = el.first.fullName | ||||||
|  |             if (el.first.type == LocType.GROUP) { | ||||||
|  |                 textView.setTypeface(null, Typeface.BOLD) | ||||||
|  |  | ||||||
|  |                 val colorGrayTyped = TypedValue() | ||||||
|  |                 ctx.theme.resolveAttribute(android.R.attr.textColorTertiary, colorGrayTyped, true) | ||||||
|  |                 val color = Color.valueOf(colorGrayTyped.data) | ||||||
|  |                 textView.setBackgroundColor(Color.valueOf(color.red(), color.green(), color.blue(), 0.5f).toArgb()) | ||||||
|  |                 checkBox.visibility = View.INVISIBLE | ||||||
|  |  | ||||||
|  |                 el.first.children.apply { | ||||||
|  |                     val nbCountries = this.size | ||||||
|  |                     val nbVisited = this.map { if (visited.visited(it)) 1 else 0 }.reduce{ a, b -> (a + b) } | ||||||
|  |                     val ratio = nbVisited.toFloat() / nbCountries.toFloat() | ||||||
|  |                     val percentage = (ratio * 100).toInt() | ||||||
|  |                     textView.text = "${textView.text as String} (${percentage}%)" | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 val colorBackgroundTyped = TypedValue() | ||||||
|  |                 ctx.theme.resolveAttribute(android.R.attr.colorBackground, colorBackgroundTyped, true) | ||||||
|  |                 textView.backgroundTintList = null | ||||||
|  |                 textView.background = ColorDrawable(colorBackgroundTyped.data) | ||||||
|  |                 textView.isActivated = false | ||||||
|  |  | ||||||
|  |                 val layoutParam = checkBox.layoutParams | ||||||
|  |                 layoutParam.width = 125 | ||||||
|  |                 checkBox.layoutParams = layoutParam | ||||||
|  |  | ||||||
|  |                 checkBox.visibility = View.VISIBLE | ||||||
|  |             } | ||||||
|             checkBox.checkedState = |             checkBox.checkedState = | ||||||
|                 if (visited.visited(el.first)) MaterialCheckBox.STATE_CHECKED |                 if (visited.visited(el.first)) MaterialCheckBox.STATE_CHECKED | ||||||
|                 else if (el.first.children.any { visited.visited(it) }) MaterialCheckBox.STATE_INDETERMINATE |                 else if (el.first.children.any { visited.visited(it) }) MaterialCheckBox.STATE_INDETERMINATE | ||||||
| @@ -93,13 +128,13 @@ class FoldingListAdapter( | |||||||
|  |  | ||||||
|         fun addListeners(expandLambda: ()->Boolean, visitedLambda: (Boolean)->Unit) { |         fun addListeners(expandLambda: ()->Boolean, visitedLambda: (Boolean)->Unit) { | ||||||
|  |  | ||||||
|             textView.setOnClickListener { checkBox.toggle() } |             textView.setOnClickListener { expandLambda() } | ||||||
|             checkBox.addOnCheckedStateChangedListener { _, e -> |             checkBox.addOnCheckedStateChangedListener { _, e -> | ||||||
|                 visitedLambda(e == MaterialCheckBox.STATE_CHECKED) |                 visitedLambda(e == MaterialCheckBox.STATE_CHECKED) | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             textView.setOnLongClickListener{ expandLambda() } |             //textView.setOnLongClickListener{ checkBox.toggle(); true } | ||||||
|             expand.setOnClickListener { expandLambda() } |             //expand.setOnClickListener { expandLambda() } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,9 +1,20 @@ | |||||||
| package net.helcel.beendroid.activity | package net.helcel.beendroid.activity | ||||||
|  |  | ||||||
|  | import android.content.Intent | ||||||
|  | import android.content.SharedPreferences | ||||||
| import android.graphics.Bitmap | import android.graphics.Bitmap | ||||||
| import android.graphics.Canvas | import android.graphics.Canvas | ||||||
|  | import android.graphics.Color | ||||||
|  | import android.graphics.drawable.ColorDrawable | ||||||
| import android.os.Bundle | import android.os.Bundle | ||||||
|  | import android.util.Log | ||||||
|  | import android.util.TypedValue | ||||||
|  | import android.view.Menu | ||||||
|  | import android.view.MenuInflater | ||||||
|  | import android.view.MenuItem | ||||||
| import androidx.appcompat.app.AppCompatActivity | import androidx.appcompat.app.AppCompatActivity | ||||||
|  | import androidx.core.view.MenuProvider | ||||||
|  | import androidx.preference.PreferenceManager | ||||||
| import androidx.recyclerview.widget.LinearLayoutManager | import androidx.recyclerview.widget.LinearLayoutManager | ||||||
| import androidx.recyclerview.widget.RecyclerView | import androidx.recyclerview.widget.RecyclerView | ||||||
| import com.caverock.androidsvg.RenderOptions | import com.caverock.androidsvg.RenderOptions | ||||||
| @@ -17,6 +28,8 @@ import net.helcel.beendroid.svg.PSVGWrapper | |||||||
|  |  | ||||||
| class MainActivity : AppCompatActivity() { | class MainActivity : AppCompatActivity() { | ||||||
|  |  | ||||||
|  |     private lateinit var sharedPreferences: SharedPreferences | ||||||
|  |  | ||||||
|     private lateinit var map : SVGImageView |     private lateinit var map : SVGImageView | ||||||
|     private lateinit var list : RecyclerView |     private lateinit var list : RecyclerView | ||||||
|  |  | ||||||
| @@ -30,26 +43,70 @@ class MainActivity : AppCompatActivity() { | |||||||
|     override fun onCreate(savedInstanceState: Bundle?) { |     override fun onCreate(savedInstanceState: Bundle?) { | ||||||
|         super.onCreate(savedInstanceState) |         super.onCreate(savedInstanceState) | ||||||
|  |  | ||||||
|         canvas.drawRGB(255, 255, 255) |         // Create action bar | ||||||
|  |         val colorPrimaryTyped = TypedValue() | ||||||
|  |         theme.resolveAttribute(android.R.attr.colorPrimary, colorPrimaryTyped, true) | ||||||
|  |         supportActionBar?.setBackgroundDrawable(ColorDrawable(colorPrimaryTyped.data)) | ||||||
|  |  | ||||||
|  |         // Fetch shared preferences to restore app theme upon startup | ||||||
|  |         sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this) | ||||||
|  |         SettingsFragment.setTheme(this, sharedPreferences.getString(getString(R.string.key_theme), getString(R.string.system))) | ||||||
|  |  | ||||||
|  |         // Create menu in action bar | ||||||
|  |         addMenuProvider(object : MenuProvider { | ||||||
|  |             override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { | ||||||
|  |                 menuInflater.inflate(R.menu.menu_main, menu) | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             override fun onMenuItemSelected(menuItem: MenuItem): Boolean { | ||||||
|  |                 return when (menuItem.itemId) { | ||||||
|  |                     R.id.action_edit -> { | ||||||
|  |                         // TODO: Enable editing selected countries | ||||||
|  |                         true | ||||||
|  |                     } | ||||||
|  |                     R.id.action_settings -> { | ||||||
|  |                         // Open settings | ||||||
|  |                         startActivity(Intent(this@MainActivity, SettingsActivity::class.java)) | ||||||
|  |                         true | ||||||
|  |                     } | ||||||
|  |                     else -> { | ||||||
|  |                         false | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |         }) | ||||||
|  |  | ||||||
|  |         // Restore visited countries | ||||||
|         visited = Visited(this) |         visited = Visited(this) | ||||||
|         visited.load() |         visited.load() | ||||||
|  |  | ||||||
|  |         // Wrap lists of countries | ||||||
|         psvg = PSVGWrapper(this) |         psvg = PSVGWrapper(this) | ||||||
|         css = CSSWrapper(visited) |         css = CSSWrapper(visited) | ||||||
|  |  | ||||||
|  |         // Populate map from list of countries | ||||||
|         setContentView(R.layout.activity_main) |         setContentView(R.layout.activity_main) | ||||||
|         map = findViewById(R.id.map) |         map = findViewById(R.id.map) | ||||||
|         map.setImageBitmap(bitmap) |         map.setImageBitmap(bitmap) | ||||||
|  |  | ||||||
|         refreshMap() |         refreshMap() | ||||||
|  |  | ||||||
|  |         // Populate list below the map | ||||||
|         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) { refreshMap() } |         list.adapter = FoldingListAdapter(this, World.WWW.children, visited) { refreshMap() } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun refreshMap(){ |     private fun refreshMap(){ | ||||||
|         psvg.get().renderToCanvas(canvas,RenderOptions.create().css(css.get())) |         // Set or reset background (replaces canvas.drawColor(0, 0, 0)) | ||||||
|  |         val colorBackgroundTyped = TypedValue() | ||||||
|  |         theme.resolveAttribute(android.R.attr.colorBackground, colorBackgroundTyped, true) | ||||||
|  |         canvas.drawColor(colorBackgroundTyped.data) | ||||||
|  |  | ||||||
|  |         // Render all countries and visited ones | ||||||
|  |         psvg.getFill().renderToCanvas(canvas, RenderOptions.create().css(css.get())) | ||||||
|  |  | ||||||
|  |         // Render all contours in the same color as the background to make them much clearer | ||||||
|  |         psvg.getDraw().renderToCanvas(canvas) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -0,0 +1,39 @@ | |||||||
|  | package net.helcel.beendroid.activity | ||||||
|  |  | ||||||
|  | import android.graphics.drawable.ColorDrawable | ||||||
|  | import android.content.Intent | ||||||
|  | import android.os.Bundle | ||||||
|  | import android.os.PersistableBundle | ||||||
|  | import android.util.TypedValue | ||||||
|  | import android.view.MenuItem | ||||||
|  | import androidx.activity.addCallback | ||||||
|  | import androidx.appcompat.app.AppCompatActivity | ||||||
|  | import net.helcel.beendroid.R | ||||||
|  |  | ||||||
|  | class  SettingsActivity: AppCompatActivity() { | ||||||
|  |  | ||||||
|  |     override fun onCreate(savedInstanceState: Bundle?) { | ||||||
|  |         super.onCreate(savedInstanceState) | ||||||
|  |  | ||||||
|  |         // Bind activity to XML layout with fragment view | ||||||
|  |         setContentView(R.layout.activity_settings) | ||||||
|  |  | ||||||
|  |         // Create action bar | ||||||
|  |         val colorPrimaryTyped = TypedValue() | ||||||
|  |         theme.resolveAttribute(android.R.attr.colorPrimary, colorPrimaryTyped, true) | ||||||
|  |         supportActionBar?.setBackgroundDrawable(ColorDrawable(colorPrimaryTyped.data)) | ||||||
|  |         supportActionBar?.title = getString(R.string.action_settings) | ||||||
|  |         supportActionBar?.setDisplayHomeAsUpEnabled(true) | ||||||
|  |  | ||||||
|  |         // Populate activity with settings fragment | ||||||
|  |         supportFragmentManager.beginTransaction() | ||||||
|  |             .replace(R.id.fragment_view, SettingsFragment()) | ||||||
|  |             .commit() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     override fun onOptionsItemSelected(item: MenuItem): Boolean { | ||||||
|  |         // Configure on back pressed | ||||||
|  |         finish() | ||||||
|  |         return super.onOptionsItemSelected(item) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,54 @@ | |||||||
|  | package net.helcel.beendroid.activity | ||||||
|  |  | ||||||
|  | import android.content.Context | ||||||
|  | import android.graphics.drawable.ColorDrawable | ||||||
|  | import android.os.Bundle | ||||||
|  | import android.util.TypedValue | ||||||
|  | import androidx.appcompat.app.AppCompatDelegate | ||||||
|  | import androidx.preference.ListPreference | ||||||
|  | import androidx.preference.PreferenceFragmentCompat | ||||||
|  | import net.helcel.beendroid.R | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class SettingsFragment: PreferenceFragmentCompat() { | ||||||
|  |     private lateinit var themePreference: ListPreference | ||||||
|  |  | ||||||
|  |     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { | ||||||
|  |         setPreferencesFromResource(R.xml.fragment_settings, rootKey) | ||||||
|  |  | ||||||
|  |         // Select Light/Dark/System Mode | ||||||
|  |         themePreference = findPreference(getString(R.string.key_theme))!! | ||||||
|  |         themePreference.setOnPreferenceChangeListener { _, key -> | ||||||
|  |             setTheme(requireContext(), key as String) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     companion object { | ||||||
|  |         fun setTheme(context: Context, key: String?): Boolean { | ||||||
|  |             when (key) { | ||||||
|  |                 context.getString(R.string.system) -> { | ||||||
|  |                     // Set SYSTEM Theme | ||||||
|  |                     AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) | ||||||
|  |                     return true | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 context.getString(R.string.light) -> { | ||||||
|  |                     // Set LIGHT Theme | ||||||
|  |                     AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) | ||||||
|  |                     return true | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 context.getString(R.string.dark) -> { | ||||||
|  |                     // Set DARK Theme | ||||||
|  |                     AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) | ||||||
|  |                     return true | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 else -> { | ||||||
|  |                     return false | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -10,13 +10,13 @@ class Visited(ctx: Context) { | |||||||
|  |  | ||||||
|     fun load() { |     fun load() { | ||||||
|  |  | ||||||
|         Group.values().forEach { |         Group.entries.forEach { | ||||||
|             locs[it] = pref.getBoolean(it.code, false) |             locs[it] = pref.getBoolean(it.code, false) | ||||||
|         } |         } | ||||||
|         Country.values().forEach { |         Country.entries.forEach { | ||||||
|             locs[it] = pref.getBoolean(it.code, false) |             locs[it] = pref.getBoolean(it.code, false) | ||||||
|         } |         } | ||||||
|         State.values().forEach { |         State.entries.forEach { | ||||||
|             locs[it] = pref.getBoolean(it.code, false) |             locs[it] = pref.getBoolean(it.code, false) | ||||||
|         } |         } | ||||||
|         editor.apply() |         editor.apply() | ||||||
|   | |||||||
| @@ -1,20 +1,23 @@ | |||||||
| package net.helcel.beendroid.svg | package net.helcel.beendroid.svg | ||||||
|  |  | ||||||
|  | import android.util.TypedValue | ||||||
| import net.helcel.beendroid.countries.Visited | import net.helcel.beendroid.countries.Visited | ||||||
| import net.helcel.beendroid.countries.World | import net.helcel.beendroid.countries.World | ||||||
|  |  | ||||||
| class CSSWrapper(private val visited: Visited) { | class CSSWrapper(private val visited: Visited) { | ||||||
|  |  | ||||||
|  |     private val colorPrimary = "#0187FF" | ||||||
|  |  | ||||||
|     fun get() : String { |     fun get() : String { | ||||||
|         return listOf(World.WWW.children |         return listOf(World.WWW.children | ||||||
|             .filter { visited.visited(it)} |             .filter { visited.visited(it)} | ||||||
|             .map { ".${it.code}{fill:blue;}"} |             .map { ".${it.code}{fill:$colorPrimary;}"} | ||||||
|             .fold(""){acc, s-> acc + s}, |             .fold(""){acc, s-> acc + s}, | ||||||
|         World.WWW.children |         World.WWW.children | ||||||
|             .filter { !visited.visited(it) } |             .filter { !visited.visited(it) } | ||||||
|             .map { cg -> cg.children |             .map { cg -> cg.children | ||||||
|                 .filter { visited.visited(it) } |                 .filter { visited.visited(it) } | ||||||
|                 .map { ".${it.code}{fill:blue;}"} |                 .map { ".${it.code}{fill:$colorPrimary;}"} | ||||||
|                 .fold(""){acc, s-> acc + s} |                 .fold(""){acc, s-> acc + s} | ||||||
|             }.fold(""){acc,s->acc+s}, |             }.fold(""){acc,s->acc+s}, | ||||||
|         ).fold(""){acc,s-> acc+s} |         ).fold(""){acc,s-> acc+s} | ||||||
|   | |||||||
| @@ -1,7 +1,12 @@ | |||||||
| package net.helcel.beendroid.svg | package net.helcel.beendroid.svg | ||||||
|  |  | ||||||
| import android.content.Context | import android.content.Context | ||||||
|  | import android.graphics.Color | ||||||
|  | import android.graphics.drawable.ColorDrawable | ||||||
|  | import android.util.Log | ||||||
|  | import android.util.TypedValue | ||||||
| import com.caverock.androidsvg.SVG | import com.caverock.androidsvg.SVG | ||||||
|  | import net.helcel.beendroid.R | ||||||
| import net.helcel.beendroid.countries.Country | import net.helcel.beendroid.countries.Country | ||||||
| import net.helcel.beendroid.countries.GeoLoc | import net.helcel.beendroid.countries.GeoLoc | ||||||
| import net.helcel.beendroid.countries.World | import net.helcel.beendroid.countries.World | ||||||
| @@ -11,8 +16,20 @@ class PSVGWrapper(ctx: Context) { | |||||||
|     private val cm = HashMap<GeoLoc, PSVGLoader>() |     private val cm = HashMap<GeoLoc, PSVGLoader>() | ||||||
|     private var fm = "" |     private var fm = "" | ||||||
|  |  | ||||||
|  |     private val colorForeground: String | ||||||
|  |     private val colorBackground: String | ||||||
|  |  | ||||||
|     init { |     init { | ||||||
|         Country.values().forEach { |         val colorSecondaryTyped = TypedValue() | ||||||
|  |         ctx.theme.resolveAttribute(android.R.attr.textColorTertiary, colorSecondaryTyped, true) | ||||||
|  |         colorForeground = "\"#${Integer.toHexString(colorSecondaryTyped.data).subSequence(2, 8)}\"" | ||||||
|  |  | ||||||
|  |         val colorBackgroundTyped = TypedValue() | ||||||
|  |         ctx.theme.resolveAttribute(android.R.attr.colorBackground, colorBackgroundTyped, true) | ||||||
|  |         colorBackground = "\"#${Integer.toHexString(colorBackgroundTyped.data).subSequence(2, 8)}\"" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         Country.entries.forEach { | ||||||
|             cm[it] = PSVGLoader(ctx, it, Level.ZERO).load() |             cm[it] = PSVGLoader(ctx, it, Level.ZERO).load() | ||||||
|         } |         } | ||||||
|         build() |         build() | ||||||
| @@ -31,12 +48,12 @@ class PSVGWrapper(ctx: Context) { | |||||||
|         }.fold("") { acc, e -> acc + e } |         }.fold("") { acc, e -> acc + e } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fun get(): SVG { |     fun getFill(): SVG { | ||||||
|         return SVG.getFromString("<svg id=\"map\" xmlns=\"http://www.w3.org/2000/svg\" width=\"1200\" height=\"1200\" x=\"0\" y=\"0\" >$fm</svg>") |         return SVG.getFromString("<svg id=\"map\" xmlns=\"http://www.w3.org/2000/svg\" width=\"1200\" height=\"1200\" x=\"0\" y=\"0\" fill=${colorForeground}>$fm</svg>") | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     fun getDraw(): SVG { | ||||||
|  |         return SVG.getFromString("<svg id=\"map\" xmlns=\"http://www.w3.org/2000/svg\" width=\"1200\" height=\"1200\" x=\"0\" y=\"0\" fill-opacity=\"0\" stroke=${colorBackground}>$fm</svg>") | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -4,6 +4,6 @@ | |||||||
|     android:viewportWidth="320" |     android:viewportWidth="320" | ||||||
|     android:viewportHeight="512"> |     android:viewportHeight="512"> | ||||||
|   <path |   <path | ||||||
|       android:fillColor="#FFFFFFFF" |       android:fillColor="?attr/colorOnBackground" | ||||||
|       android:pathData="M310.6,233.4c12.5,12.5 12.5,32.8 0,45.3l-192,192c-12.5,12.5 -32.8,12.5 -45.3,0s-12.5,-32.8 0,-45.3L242.7,256 73.4,86.6c-12.5,-12.5 -12.5,-32.8 0,-45.3s32.8,-12.5 45.3,0l192,192z"/> |       android:pathData="M310.6,233.4c12.5,12.5 12.5,32.8 0,45.3l-192,192c-12.5,12.5 -32.8,12.5 -45.3,0s-12.5,-32.8 0,-45.3L242.7,256 73.4,86.6c-12.5,-12.5 -12.5,-32.8 0,-45.3s32.8,-12.5 45.3,0l192,192z"/> | ||||||
| </vector> | </vector> | ||||||
							
								
								
									
										10
									
								
								app/src/main/res/drawable/edit.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/src/main/res/drawable/edit.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | <vector | ||||||
|  |     android:height="24dp" | ||||||
|  |     android:viewportHeight="24" | ||||||
|  |     android:viewportWidth="24" | ||||||
|  |     android:width="24dp" | ||||||
|  |     xmlns:android="http://schemas.android.com/apk/res/android"> | ||||||
|  |     <path | ||||||
|  |         android:fillColor="@color/white" | ||||||
|  |         android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/> | ||||||
|  | </vector> | ||||||
							
								
								
									
										11
									
								
								app/src/main/res/drawable/palette.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								app/src/main/res/drawable/palette.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | <vector | ||||||
|  |     android:height="24dp" | ||||||
|  |     android:viewportHeight="24" | ||||||
|  |     android:viewportWidth="24" | ||||||
|  |     android:width="24dp" | ||||||
|  |     xmlns:android="http://schemas.android.com/apk/res/android" > | ||||||
|  |  | ||||||
|  |     <path | ||||||
|  |         android:fillColor="?attr/colorPrimary" | ||||||
|  |         android:pathData="M12,2C6.49,2 2,6.49 2,12s4.49,10 10,10c1.38,0 2.5,-1.12 2.5,-2.5c0,-0.61 -0.23,-1.2 -0.64,-1.67c-0.08,-0.1 -0.13,-0.21 -0.13,-0.33c0,-0.28 0.22,-0.5 0.5,-0.5H16c3.31,0 6,-2.69 6,-6C22,6.04 17.51,2 12,2zM17.5,13c-0.83,0 -1.5,-0.67 -1.5,-1.5c0,-0.83 0.67,-1.5 1.5,-1.5s1.5,0.67 1.5,1.5C19,12.33 18.33,13 17.5,13zM14.5,9C13.67,9 13,8.33 13,7.5C13,6.67 13.67,6 14.5,6S16,6.67 16,7.5C16,8.33 15.33,9 14.5,9zM5,11.5C5,10.67 5.67,10 6.5,10S8,10.67 8,11.5C8,12.33 7.33,13 6.5,13S5,12.33 5,11.5zM11,7.5C11,8.33 10.33,9 9.5,9S8,8.33 8,7.5C8,6.67 8.67,6 9.5,6S11,6.67 11,7.5z" /> | ||||||
|  | </vector> | ||||||
| @@ -2,8 +2,9 @@ | |||||||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" |     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||||
|     android:orientation="vertical" |     android:orientation="vertical" | ||||||
|     android:layout_width="fill_parent" |     android:theme="@style/Theme.Beendroid" | ||||||
|     android:layout_height="fill_parent"> |     android:layout_width="match_parent" | ||||||
|  |     android:layout_height="match_parent"> | ||||||
|  |  | ||||||
| <com.caverock.androidsvg.SVGImageView | <com.caverock.androidsvg.SVGImageView | ||||||
|         android:id="@+id/map" |         android:id="@+id/map" | ||||||
| @@ -15,7 +16,8 @@ | |||||||
|     <androidx.core.widget.NestedScrollView |     <androidx.core.widget.NestedScrollView | ||||||
|         android:id="@+id/sv" |         android:id="@+id/sv" | ||||||
|         android:layout_width="match_parent" |         android:layout_width="match_parent" | ||||||
|         android:layout_height="wrap_content" |         android:layout_height="match_parent" | ||||||
|  |         android:scrollbars="vertical" | ||||||
|         android:layout_weight="1"> |         android:layout_weight="1"> | ||||||
|  |  | ||||||
|         <androidx.recyclerview.widget.RecyclerView |         <androidx.recyclerview.widget.RecyclerView | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								app/src/main/res/layout/activity_settings.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								app/src/main/res/layout/activity_settings.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | <?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" | ||||||
|  |     xmlns:tools="http://schemas.android.com/tools" | ||||||
|  |     android:orientation="vertical" | ||||||
|  |     android:theme="@style/Theme.Beendroid" | ||||||
|  |     android:layout_width="match_parent" | ||||||
|  |     android:layout_height="match_parent" | ||||||
|  |     tools:context=".activity.SettingsActivity"> | ||||||
|  |  | ||||||
|  | <androidx.fragment.app.FragmentContainerView | ||||||
|  |     android:id="@+id/fragment_view" | ||||||
|  |     android:layout_width="match_parent" | ||||||
|  |     android:layout_height="match_parent" /> | ||||||
|  |  | ||||||
|  | </LinearLayout> | ||||||
| @@ -9,54 +9,61 @@ | |||||||
|         android:layout_width="match_parent" |         android:layout_width="match_parent" | ||||||
|         android:layout_height="wrap_content"> |         android:layout_height="wrap_content"> | ||||||
|  |  | ||||||
|         <ImageView |         <com.google.android.material.button.MaterialButton | ||||||
|             android:id="@+id/expand" |             android:id="@+id/textView" | ||||||
|             android:layout_width="48dp" |             android:layout_width="0dp" | ||||||
|             android:layout_height="48dp" |             android:layout_height="50dp" | ||||||
|             android:contentDescription=">" |             app:cornerRadius="0dp" | ||||||
|             android:scaleX="0.5" |             android:gravity="start|center_vertical" | ||||||
|             android:scaleY="0.5" |             android:textColor="?attr/colorOnBackground" | ||||||
|             android:visibility="visible" |             android:textAllCaps="false" | ||||||
|             app:layout_constraintEnd_toStartOf="@+id/textView" |             android:textAppearance="?attr/textAppearanceBody2" | ||||||
|  |             android:clickable="true" | ||||||
|  |             android:focusable="true" | ||||||
|  |             android:paddingStart="20dp" | ||||||
|  |             android:paddingEnd="20dp" | ||||||
|  |             android:insetTop="4dp" | ||||||
|  |             android:insetBottom="4dp" | ||||||
|  |             app:layout_constraintBottom_toBottomOf="@id/text2checkbox" | ||||||
|  |             app:layout_constraintEnd_toStartOf="@id/text2checkbox" | ||||||
|             app:layout_constraintStart_toStartOf="parent" |             app:layout_constraintStart_toStartOf="parent" | ||||||
|             app:layout_constraintTop_toTopOf="parent" |             app:layout_constraintTop_toTopOf="parent" | ||||||
|             tools:ignore="HardcodedText" /> |             app:layout_constraintVertical_bias="1.0" /> | ||||||
|  |  | ||||||
|  |         <Space | ||||||
|  |             android:id="@+id/text2checkbox" | ||||||
|  |             android:layout_width="0.01dp" | ||||||
|  |             android:layout_height="50dp" | ||||||
|  |             android:gravity="start|center_vertical" | ||||||
|  |             app:layout_constraintTop_toTopOf="parent" | ||||||
|  |             app:layout_constraintBottom_toBottomOf="@id/textView" | ||||||
|  |             app:layout_constraintEnd_toStartOf="@id/checkBox" | ||||||
|  |             app:layout_constraintStart_toEndOf="@id/textView" /> | ||||||
|  |  | ||||||
|         <com.google.android.material.checkbox.MaterialCheckBox |         <com.google.android.material.checkbox.MaterialCheckBox | ||||||
|             android:id="@+id/checkBox" |             android:id="@+id/checkBox" | ||||||
|             android:layout_width="wrap_content" |             android:layout_width="0.01dp" | ||||||
|             android:layout_height="wrap_content" |             android:layout_height="50dp" | ||||||
|             app:checkedState="indeterminate" |             app:checkedState="indeterminate" | ||||||
|             app:layout_constraintBottom_toBottomOf="@+id/textView" |             android:visibility="invisible" | ||||||
|  |             app:layout_constraintBottom_toBottomOf="@id/textView" | ||||||
|             app:layout_constraintEnd_toEndOf="parent" |             app:layout_constraintEnd_toEndOf="parent" | ||||||
|             app:layout_constraintHorizontal_bias="1" |             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.5" /> |             app:layout_constraintVertical_bias="0.5" /> | ||||||
|  |  | ||||||
|         <com.google.android.material.textview.MaterialTextView |  | ||||||
|             android:id="@+id/textView" |  | ||||||
|             android:layout_width="0dp" |  | ||||||
|             android:layout_height="0dp" |  | ||||||
|             android:gravity="start|center_vertical" |  | ||||||
|             android:textColor="@color/design_default_color_on_primary" |  | ||||||
|             app:layout_constraintBottom_toBottomOf="@id/checkBox" |  | ||||||
|             app:layout_constraintEnd_toStartOf="@+id/checkBox" |  | ||||||
|             app:layout_constraintStart_toEndOf="@+id/expand" |  | ||||||
|             app:layout_constraintTop_toTopOf="@+id/expand" |  | ||||||
|             app:layout_constraintVertical_bias="1.0" /> |  | ||||||
|  |  | ||||||
|         <LinearLayout |         <LinearLayout | ||||||
|             android:id="@+id/sub_item" |             android:id="@+id/sub_item" | ||||||
|             android:layout_width="0dp" |             android:layout_width="0dp" | ||||||
|             android:layout_height="match_parent" |             android:layout_height="match_parent" | ||||||
|             android:layout_marginStart="32dp" |             android:layout_marginStart="0dp" | ||||||
|             android:orientation="vertical" |             android:orientation="vertical" | ||||||
|             android:visibility="gone" |             android:visibility="gone" | ||||||
|             app:layout_constraintBottom_toBottomOf="parent" |             app:layout_constraintBottom_toBottomOf="parent" | ||||||
|             app:layout_constraintEnd_toEndOf="parent" |             app:layout_constraintEnd_toEndOf="parent" | ||||||
|             app:layout_constraintStart_toStartOf="parent" |             app:layout_constraintStart_toStartOf="parent" | ||||||
|             app:layout_constraintTop_toBottomOf="@+id/checkBox"> |             app:layout_constraintTop_toBottomOf="@id/checkBox"> | ||||||
|  |  | ||||||
|             <androidx.recyclerview.widget.RecyclerView |             <androidx.recyclerview.widget.RecyclerView | ||||||
|                 android:id="@+id/list_list" |                 android:id="@+id/list_list" | ||||||
|   | |||||||
| @@ -2,6 +2,15 @@ | |||||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" |     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||||
|     xmlns:tools="http://schemas.android.com/tools" |     xmlns:tools="http://schemas.android.com/tools" | ||||||
|     tools:context="net.helcel.beendroid.activity.MainActivity" > |     tools:context="net.helcel.beendroid.activity.MainActivity" > | ||||||
|  |  | ||||||
|  |     <item | ||||||
|  |         android:id="@+id/action_edit" | ||||||
|  |         android:orderInCategory="100" | ||||||
|  |         android:icon="@drawable/edit" | ||||||
|  |         android:visible="false" | ||||||
|  |         android:title="@string/action_edit" | ||||||
|  |         app:showAsAction="ifRoom" /> | ||||||
|  |  | ||||||
|     <item |     <item | ||||||
|         android:id="@+id/action_settings" |         android:id="@+id/action_settings" | ||||||
|         android:orderInCategory="100" |         android:orderInCategory="100" | ||||||
|   | |||||||
| @@ -1,5 +1,9 @@ | |||||||
| <resources xmlns:tools="http://schemas.android.com/tools"> | <resources xmlns:tools="http://schemas.android.com/tools"> | ||||||
|     <style name="Theme.Beendroid" parent="Theme.Material3.DayNight.NoActionBar"> |     <style name="Theme.Beendroid" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> | ||||||
|  |         <item name="colorPrimary">@color/teal_700</item> | ||||||
|  |         <item name="android:colorPrimary">@color/teal_700</item> | ||||||
|  |         <item name="android:textColorTertiary">@color/darkgray</item> | ||||||
|         <item name="android:statusBarColor">?attr/colorPrimary</item> |         <item name="android:statusBarColor">?attr/colorPrimary</item> | ||||||
|  |         <item name="colorAccent">?attr/colorPrimary</item> | ||||||
|     </style> |     </style> | ||||||
| </resources> | </resources> | ||||||
							
								
								
									
										8
									
								
								app/src/main/res/values/arrays.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								app/src/main/res/values/arrays.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <resources> | ||||||
|  |     <string-array name="entries_theme" > | ||||||
|  |         <item>@string/system</item> | ||||||
|  |         <item>@string/light</item> | ||||||
|  |         <item>@string/dark</item> | ||||||
|  |     </string-array> | ||||||
|  | </resources> | ||||||
							
								
								
									
										13
									
								
								app/src/main/res/values/colors.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								app/src/main/res/values/colors.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <resources> | ||||||
|  |     <color name="purple_200">#FFBB86FC</color> | ||||||
|  |     <color name="purple_500">#FF6200EE</color> | ||||||
|  |     <color name="purple_700">#FF3700B3</color> | ||||||
|  |     <color name="teal_200">#FF03AFFF</color> | ||||||
|  |     <color name="teal_700">#FF0187FF</color> | ||||||
|  |     <color name="yellowish">#FFFFDD00</color> | ||||||
|  |     <color name="black">#FF000000</color> | ||||||
|  |     <color name="darkgray">#FF555555</color> | ||||||
|  |     <color name="lightgray">#FFBBBBBB</color> | ||||||
|  |     <color name="white">#FFFFFFFF</color> | ||||||
|  | </resources> | ||||||
| @@ -1,8 +1,12 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||||
| <resources> | <resources> | ||||||
|     <string name="app_name">Beendroid</string> |     <string name="app_name">BeenDroid</string> | ||||||
|     <string name="action_settings">Settings</string> |     <string name="action_settings">Settings</string> | ||||||
|  |     <string name="action_edit">Edit</string> | ||||||
|     <string name="welcome">Welcome!</string> |     <string name="welcome">Welcome!</string> | ||||||
|     <string name="change_lang">Change language</string> |     <string name="change_lang">Change language</string> | ||||||
|  |     <string name="key_theme">App theme</string> | ||||||
|  |     <string name="system">Same as system</string> | ||||||
|  |     <string name="light">Light theme</string> | ||||||
|  |     <string name="dark">Dark theme</string> | ||||||
| </resources> | </resources> | ||||||
| @@ -1,14 +1,9 @@ | |||||||
| <resources xmlns:tools="http://schemas.android.com/tools"> | <resources xmlns:tools="http://schemas.android.com/tools"> | ||||||
|     <style name="Theme.Beendroid" parent="Theme.Material3.DayNight.NoActionBar"> |     <style name="Theme.Beendroid" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> | ||||||
|  |         <item name="colorPrimary">@color/teal_700</item> | ||||||
|  |         <item name="android:colorPrimary">@color/teal_700</item> | ||||||
|  |         <item name="android:textColorTertiary">@color/lightgray</item> | ||||||
|         <item name="android:statusBarColor">?attr/colorPrimary</item> |         <item name="android:statusBarColor">?attr/colorPrimary</item> | ||||||
|  |         <item name="colorAccent">?attr/colorPrimary</item> | ||||||
|     </style> |     </style> | ||||||
|  |  | ||||||
|     <style name="Theme.Beendroid.NoActionBar"> |  | ||||||
|         <item name="windowActionBar">false</item> |  | ||||||
|         <item name="windowNoTitle">true</item> |  | ||||||
|     </style> |  | ||||||
|  |  | ||||||
|     <style name="Theme.Beendroid.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> |  | ||||||
|  |  | ||||||
|     <style name="Theme.Beendroid.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" /> |  | ||||||
| </resources> | </resources> | ||||||
							
								
								
									
										17
									
								
								app/src/main/res/xml/fragment_settings.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app/src/main/res/xml/fragment_settings.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto" | ||||||
|  |     xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     android:theme="@style/Theme.Beendroid"> | ||||||
|  |  | ||||||
|  |     <ListPreference | ||||||
|  |         app:enabled="true" | ||||||
|  |         app:key="@string/key_theme" | ||||||
|  |         app:icon="@drawable/palette" | ||||||
|  |         app:title="@string/key_theme" | ||||||
|  |         app:useSimpleSummaryProvider="true" | ||||||
|  |         app:entries="@array/entries_theme" | ||||||
|  |         app:entryValues="@array/entries_theme" | ||||||
|  |         app:defaultValue="@string/system" /> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | </PreferenceScreen> | ||||||
		Reference in New Issue
	
	Block a user