mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Change list to recyclerview
This commit is contained in:
@@ -242,7 +242,7 @@ class EntryActivity : LockingActivity() {
|
||||
val entryInfo = entry.getEntryInfo(mDatabase)
|
||||
|
||||
// Assign title icon
|
||||
titleIconView?.assignDatabaseIcon(mDatabase!!.drawFactory, entryInfo.icon, iconColor)
|
||||
titleIconView?.assignDatabaseIcon(mDatabase!!.iconDrawableFactory, entryInfo.icon, iconColor)
|
||||
|
||||
// Assign title text
|
||||
val entryTitle = entryInfo.title
|
||||
|
||||
@@ -208,7 +208,7 @@ class EntryEditActivity : LockingActivity(),
|
||||
.replace(R.id.entry_edit_contents, entryEditFragment!!, ENTRY_EDIT_FRAGMENT_TAG)
|
||||
.commit()
|
||||
entryEditFragment?.apply {
|
||||
drawFactory = mDatabase?.drawFactory
|
||||
drawFactory = mDatabase?.iconDrawableFactory
|
||||
setOnDateClickListener = {
|
||||
expiryTime.date.let { expiresDate ->
|
||||
val dateTime = DateTime(expiresDate)
|
||||
|
||||
@@ -535,8 +535,8 @@ class GroupActivity : LockingActivity(),
|
||||
// Assign the group icon depending of IconPack or custom icon
|
||||
iconView?.visibility = View.VISIBLE
|
||||
mCurrentGroup?.let {
|
||||
if (mDatabase?.drawFactory != null)
|
||||
iconView?.assignDatabaseIcon(mDatabase?.drawFactory!!, it.icon, mIconColor)
|
||||
if (mDatabase?.iconDrawableFactory != null)
|
||||
iconView?.assignDatabaseIcon(mDatabase?.iconDrawableFactory!!, it.icon, mIconColor)
|
||||
|
||||
if (toolbar != null) {
|
||||
if (mCurrentGroup?.containsParent() == true)
|
||||
|
||||
@@ -205,8 +205,8 @@ class GroupEditDialogFragment : DialogFragment(), IconPickerDialogFragment.IconP
|
||||
}
|
||||
|
||||
private fun assignIconView() {
|
||||
if (mDatabase?.drawFactory != null) {
|
||||
iconButtonView.assignDatabaseIcon(mDatabase?.drawFactory!!, mGroupInfo.icon, iconColor)
|
||||
if (mDatabase?.iconDrawableFactory != null) {
|
||||
iconButtonView.assignDatabaseIcon(mDatabase?.iconDrawableFactory!!, mGroupInfo.icon, iconColor)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,15 +24,13 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.*
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.fragments.IconCustomFragment
|
||||
import com.kunzisoft.keepass.activities.fragments.IconStandardFragment
|
||||
import com.kunzisoft.keepass.adapters.IconPickerPagerAdapter
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImage
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImageCustom
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImageStandard
|
||||
|
||||
|
||||
class IconPickerDialogFragment : DialogFragment() {
|
||||
@@ -45,7 +43,12 @@ class IconPickerDialogFragment : DialogFragment() {
|
||||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
try {
|
||||
iconPickerListener = context as IconPickerListener
|
||||
iconPickerListener = object : IconPickerListener {
|
||||
override fun iconPicked(icon: IconImage) {
|
||||
(context as IconPickerListener).iconPicked(icon)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
} catch (e: ClassCastException) {
|
||||
// The activity doesn't implement the interface, throw exception
|
||||
throw ClassCastException(context.toString()
|
||||
@@ -82,50 +85,14 @@ class IconPickerDialogFragment : DialogFragment() {
|
||||
val root = layoutInflater.inflate(R.layout.fragment_icon_picker, container)
|
||||
viewPager = root.findViewById(R.id.icon_picker_pager)
|
||||
tabLayout = root.findViewById(R.id.icon_picker_tabs)
|
||||
iconPickerPagerAdapter = IconPickerPagerAdapter(childFragmentManager, { icon ->
|
||||
iconPickerListener?.iconPicked(IconImage(icon))
|
||||
dismiss()
|
||||
}, { icon ->
|
||||
iconPickerListener?.iconPicked(IconImage(icon))
|
||||
dismiss()
|
||||
}
|
||||
)
|
||||
iconPickerPagerAdapter = IconPickerPagerAdapter(childFragmentManager)
|
||||
iconPickerPagerAdapter.iconSelected = iconPickerListener
|
||||
viewPager.adapter = iconPickerPagerAdapter
|
||||
tabLayout.setupWithViewPager(viewPager)
|
||||
|
||||
return root
|
||||
}
|
||||
|
||||
class IconPickerPagerAdapter(fragmentManager: FragmentManager,
|
||||
iconStandardSelected: (icon: IconImageStandard) -> Unit,
|
||||
iconCustomSelected: (icon: IconImageCustom) -> Unit)
|
||||
: FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_SET_USER_VISIBLE_HINT) {
|
||||
|
||||
private val iconStandardFragment = IconStandardFragment()
|
||||
private val iconCustomFragment = IconCustomFragment()
|
||||
|
||||
init {
|
||||
iconStandardFragment.iconStandardPickerListener = iconStandardSelected
|
||||
iconCustomFragment.iconCustomPickerListener = iconCustomSelected
|
||||
}
|
||||
|
||||
override fun getCount(): Int = 2
|
||||
|
||||
override fun getItem(i: Int): Fragment {
|
||||
return when (i) {
|
||||
1 -> iconCustomFragment
|
||||
else -> iconStandardFragment
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPageTitle(position: Int): CharSequence {
|
||||
return when (position) {
|
||||
1 -> "Custom" //context.getString(R.string.iconStandard)
|
||||
else -> "Standard" //context.getString(R.string.iconStandard)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface IconPickerListener {
|
||||
fun iconPicked(icon: IconImage)
|
||||
}
|
||||
|
||||
@@ -1,98 +1,20 @@
|
||||
package com.kunzisoft.keepass.activities.fragments
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.BaseAdapter
|
||||
import android.widget.GridView
|
||||
import android.widget.ImageView
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImage
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImageCustom
|
||||
import com.kunzisoft.keepass.database.element.icon.IconPool
|
||||
import com.kunzisoft.keepass.icons.IconDrawableFactory
|
||||
import com.kunzisoft.keepass.icons.assignDatabaseIcon
|
||||
|
||||
/**
|
||||
* Content fragments
|
||||
*/
|
||||
|
||||
class IconCustomFragment : Fragment() {
|
||||
class IconCustomFragment : IconFragment() {
|
||||
|
||||
private lateinit var currIconGridView: GridView
|
||||
private var iconPool: IconPool? = null
|
||||
private var iconDrawableFactory: IconDrawableFactory? = null
|
||||
var iconCustomPickerListener: ((icon: IconImageCustom) -> Unit)? = null
|
||||
|
||||
override fun onDetach() {
|
||||
iconCustomPickerListener = null
|
||||
super.onDetach()
|
||||
override fun retrieveMainLayoutId(): Int {
|
||||
return R.layout.fragment_icon_custom_picker
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View {
|
||||
val root = inflater.inflate(R.layout.fragment_icon_standard_picker, container, false)
|
||||
currIconGridView = root.findViewById(R.id.IconGridView)
|
||||
return root
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
|
||||
val database = Database.getInstance()
|
||||
iconPool = database.iconPool
|
||||
iconDrawableFactory = database.drawFactory
|
||||
|
||||
currIconGridView.adapter = IconCustomAdapter(requireActivity()).apply {
|
||||
iconPool?.doForEachCustomIcon {
|
||||
putIcon(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inner class IconCustomAdapter(private val context: Context) : BaseAdapter() {
|
||||
|
||||
private val customIconList = ArrayList<IconImageCustom>()
|
||||
|
||||
fun putIcon(icon: IconImageCustom) {
|
||||
customIconList.add(icon)
|
||||
}
|
||||
|
||||
override fun getCount(): Int {
|
||||
return customIconList.size
|
||||
}
|
||||
|
||||
override fun getItem(position: Int): Any {
|
||||
return customIconList[position]
|
||||
}
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
return customIconList[position].uuid.leastSignificantBits
|
||||
}
|
||||
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||
val currentView: View = convertView
|
||||
?: (context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater)
|
||||
.inflate(R.layout.item_icon, parent, false)
|
||||
|
||||
val iconImage = IconImage(customIconList[position])
|
||||
|
||||
iconDrawableFactory?.let {
|
||||
val iconImageView = currentView.findViewById<ImageView>(R.id.icon_image)
|
||||
iconImageView.assignDatabaseIcon(it, iconImage)
|
||||
}
|
||||
|
||||
currentView.setOnClickListener {
|
||||
iconCustomPickerListener?.invoke(iconImage.custom)
|
||||
}
|
||||
|
||||
return currentView
|
||||
}
|
||||
override fun defineIconList(database: Database): List<IconImage> {
|
||||
return database.iconPool.getCustomIconList()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.kunzisoft.keepass.activities.fragments
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.dialogs.IconPickerDialogFragment
|
||||
import com.kunzisoft.keepass.adapters.IconAdapter
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImage
|
||||
|
||||
abstract class IconFragment : Fragment() {
|
||||
|
||||
private lateinit var iconsGridView: RecyclerView
|
||||
private lateinit var iconAdapter: IconAdapter
|
||||
var iconListener: IconPickerDialogFragment.IconPickerListener? = null
|
||||
|
||||
abstract fun retrieveMainLayoutId(): Int
|
||||
|
||||
abstract fun defineIconList(database: Database): List<IconImage>
|
||||
|
||||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
|
||||
val database = Database.getInstance()
|
||||
|
||||
iconAdapter = IconAdapter(requireActivity()).apply {
|
||||
iconDrawableFactory = database.iconDrawableFactory
|
||||
setList(defineIconList(database))
|
||||
}
|
||||
iconAdapter.iconPickerListener = iconListener
|
||||
}
|
||||
|
||||
override fun onDetach() {
|
||||
iconAdapter.iconPickerListener = null
|
||||
super.onDetach()
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View {
|
||||
val root = inflater.inflate(retrieveMainLayoutId(), container, false)
|
||||
iconsGridView = root.findViewById(R.id.icons_grid_view)
|
||||
iconsGridView.adapter = iconAdapter
|
||||
return root
|
||||
}
|
||||
}
|
||||
@@ -1,89 +1,20 @@
|
||||
package com.kunzisoft.keepass.activities.fragments
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.BaseAdapter
|
||||
import android.widget.GridView
|
||||
import android.widget.ImageView
|
||||
import androidx.core.widget.ImageViewCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImageStandard
|
||||
import com.kunzisoft.keepass.icons.IconPack
|
||||
import com.kunzisoft.keepass.icons.IconPackChooser
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImage
|
||||
|
||||
/**
|
||||
* Content fragments
|
||||
*/
|
||||
|
||||
class IconStandardFragment : Fragment() {
|
||||
class IconStandardFragment : IconFragment() {
|
||||
|
||||
private lateinit var currIconGridView: GridView
|
||||
private var iconPack: IconPack? = null
|
||||
var iconStandardPickerListener: ((icon: IconImageStandard) -> Unit)? = null
|
||||
|
||||
override fun onDetach() {
|
||||
iconStandardPickerListener = null
|
||||
super.onDetach()
|
||||
override fun retrieveMainLayoutId(): Int {
|
||||
return R.layout.fragment_icon_standard_picker
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View {
|
||||
val root = inflater.inflate(R.layout.fragment_icon_standard_picker, container, false)
|
||||
currIconGridView = root.findViewById(R.id.IconGridView)
|
||||
return root
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
iconPack = IconPackChooser.getSelectedIconPack(requireContext())
|
||||
currIconGridView.adapter = IconStandardAdapter(requireActivity())
|
||||
}
|
||||
|
||||
inner class IconStandardAdapter(private val context: Context) : BaseAdapter() {
|
||||
|
||||
override fun getCount(): Int {
|
||||
return iconPack?.numberOfIcons() ?: 0
|
||||
}
|
||||
|
||||
override fun getItem(position: Int): Any? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||
val currentView: View = convertView
|
||||
?: (context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater)
|
||||
.inflate(R.layout.item_icon, parent, false)
|
||||
|
||||
iconPack?.let { iconPack ->
|
||||
val iconImageView = currentView.findViewById<ImageView>(R.id.icon_image)
|
||||
iconImageView.setImageResource(iconPack.iconToResId(position))
|
||||
|
||||
// Assign color if icons are tintable
|
||||
if (iconPack.tintable()) {
|
||||
// Retrieve the textColor to tint the icon
|
||||
val ta = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColor))
|
||||
ImageViewCompat.setImageTintList(iconImageView, ColorStateList.valueOf(ta.getColor(0, Color.BLACK)))
|
||||
ta.recycle()
|
||||
}
|
||||
}
|
||||
|
||||
currentView.setOnClickListener {
|
||||
iconStandardPickerListener?.invoke(IconImageStandard(position))
|
||||
}
|
||||
|
||||
return currentView
|
||||
}
|
||||
override fun defineIconList(database: Database): List<IconImage> {
|
||||
return database.iconPool.getStandardIconList()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.kunzisoft.keepass.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.dialogs.IconPickerDialogFragment
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImage
|
||||
import com.kunzisoft.keepass.icons.IconDrawableFactory
|
||||
import com.kunzisoft.keepass.icons.assignDatabaseIcon
|
||||
|
||||
class IconAdapter(context: Context) : RecyclerView.Adapter<IconAdapter.CustomIconViewHolder>() {
|
||||
|
||||
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
||||
|
||||
private val iconList = ArrayList<IconImage>()
|
||||
|
||||
var iconDrawableFactory: IconDrawableFactory? = null
|
||||
var iconPickerListener: IconPickerDialogFragment.IconPickerListener? = null
|
||||
|
||||
var tintColor : Int = Color.BLACK
|
||||
|
||||
init {
|
||||
// Retrieve the textColor to tint the icon
|
||||
val ta = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColor))
|
||||
tintColor = ta.getColor(0, Color.BLACK)
|
||||
ta.recycle()
|
||||
}
|
||||
|
||||
fun setList(icon: List<IconImage>) {
|
||||
iconList.clear()
|
||||
iconList.addAll(icon)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomIconViewHolder {
|
||||
val view = inflater.inflate(R.layout.item_icon, parent, false)
|
||||
return CustomIconViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: CustomIconViewHolder, position: Int) {
|
||||
val icon = iconList[position]
|
||||
iconDrawableFactory?.let {
|
||||
holder.iconImageView.assignDatabaseIcon(it, icon, tintColor)
|
||||
}
|
||||
holder.itemView.setOnClickListener { iconPickerListener?.iconPicked(icon) }
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return iconList.size
|
||||
}
|
||||
|
||||
inner class CustomIconViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
var iconImageView: ImageView = itemView.findViewById(R.id.icon_image)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.kunzisoft.keepass.adapters
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter
|
||||
import com.kunzisoft.keepass.activities.dialogs.IconPickerDialogFragment
|
||||
import com.kunzisoft.keepass.activities.fragments.IconCustomFragment
|
||||
import com.kunzisoft.keepass.activities.fragments.IconStandardFragment
|
||||
|
||||
class IconPickerPagerAdapter(fragmentManager: FragmentManager)
|
||||
: FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_SET_USER_VISIBLE_HINT) {
|
||||
|
||||
var iconSelected: IconPickerDialogFragment.IconPickerListener? = null
|
||||
private val iconStandardFragment = IconStandardFragment()
|
||||
private val iconCustomFragment = IconCustomFragment()
|
||||
|
||||
override fun getCount(): Int = 2
|
||||
|
||||
override fun getItem(i: Int): Fragment {
|
||||
return when (i) {
|
||||
1 -> iconCustomFragment
|
||||
else -> iconStandardFragment
|
||||
}.apply {
|
||||
iconListener = iconSelected
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPageTitle(position: Int): CharSequence {
|
||||
return when (position) {
|
||||
1 -> "Custom" //context.getString(R.string.iconStandard)
|
||||
else -> "Standard" //context.getString(R.string.iconStandard)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -304,7 +304,7 @@ class NodeAdapter (private val context: Context)
|
||||
}
|
||||
holder.imageIdentifier?.setColorFilter(iconColor)
|
||||
holder.icon.apply {
|
||||
assignDatabaseIcon(mDatabase.drawFactory, subNode.icon, iconColor)
|
||||
assignDatabaseIcon(mDatabase.iconDrawableFactory, subNode.icon, iconColor)
|
||||
// Relative size of the icon
|
||||
layoutParams?.apply {
|
||||
height = (mIconDefaultDimension * mPrefSizeMultiplier).toInt()
|
||||
|
||||
@@ -82,7 +82,7 @@ class SearchEntryCursorAdapter(private val context: Context,
|
||||
|
||||
// Assign image
|
||||
viewHolder.imageViewIcon?.assignDatabaseIcon(
|
||||
database.drawFactory,
|
||||
database.iconDrawableFactory,
|
||||
currentEntry.icon,
|
||||
iconColor)
|
||||
|
||||
|
||||
@@ -276,7 +276,7 @@ object AutofillHelper {
|
||||
if (remoteViewsIcon != null) {
|
||||
presentation.assignDatabaseIcon(context,
|
||||
R.id.autofill_entry_icon,
|
||||
Database.getInstance().drawFactory,
|
||||
Database.getInstance().iconDrawableFactory,
|
||||
remoteViewsIcon,
|
||||
ContextCompat.getColor(context, R.color.green))
|
||||
}
|
||||
@@ -285,7 +285,7 @@ object AutofillHelper {
|
||||
|
||||
private fun buildIconFromEntry(context: Context, entryInfo: EntryInfo): Icon? {
|
||||
return createIconFromDatabaseIcon(context,
|
||||
Database.getInstance().drawFactory,
|
||||
Database.getInstance().iconDrawableFactory,
|
||||
entryInfo.icon,
|
||||
ContextCompat.getColor(context, R.color.green))
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ class Database {
|
||||
|
||||
var isReadOnly = false
|
||||
|
||||
val drawFactory = IconDrawableFactory()
|
||||
val iconDrawableFactory = IconDrawableFactory()
|
||||
|
||||
var loaded = false
|
||||
set(value) {
|
||||
@@ -625,7 +625,7 @@ class Database {
|
||||
|
||||
fun clear(filesDirectory: File? = null) {
|
||||
iconPool.clearCache()
|
||||
drawFactory.clearCache()
|
||||
iconDrawableFactory.clearCache()
|
||||
// Delete the cache of the database if present
|
||||
mDatabaseKDB?.clearCache()
|
||||
mDatabaseKDBX?.clearCache()
|
||||
|
||||
@@ -21,6 +21,7 @@ package com.kunzisoft.keepass.database.element.icon
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import com.kunzisoft.keepass.icons.IconPack.Companion.NB_ICONS
|
||||
|
||||
class IconImageStandard : Parcelable {
|
||||
|
||||
@@ -31,7 +32,7 @@ class IconImageStandard : Parcelable {
|
||||
}
|
||||
|
||||
constructor(iconId: Int) {
|
||||
if (iconId < MIN_ID || iconId > MAX_ID)
|
||||
if (iconId < 0 || iconId > NB_ICONS)
|
||||
this.id = KEY_ID
|
||||
else
|
||||
this.id = iconId
|
||||
@@ -72,8 +73,6 @@ class IconImageStandard : Parcelable {
|
||||
const val KEY_ID = 0
|
||||
const val TRASH_ID = 43
|
||||
const val FOLDER_ID = 48
|
||||
const val MIN_ID = 0
|
||||
const val MAX_ID = 48
|
||||
|
||||
@JvmField
|
||||
val CREATOR: Parcelable.Creator<IconImageStandard> = object : Parcelable.Creator<IconImageStandard> {
|
||||
|
||||
@@ -19,22 +19,31 @@
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.element.icon
|
||||
|
||||
import com.kunzisoft.keepass.icons.IconPack.Companion.NB_ICONS
|
||||
import java.util.ArrayList
|
||||
import java.util.UUID
|
||||
|
||||
class IconPool {
|
||||
|
||||
private val standardCache = HashMap<Int, IconImageStandard?>()
|
||||
private val standardCache = List(NB_ICONS) {
|
||||
IconImageStandard(it)
|
||||
}
|
||||
private val customCache = HashMap<UUID, IconImageCustom?>()
|
||||
|
||||
fun getIcon(iconId: Int): IconImageStandard {
|
||||
var icon: IconImageStandard? = standardCache[iconId]
|
||||
|
||||
if (icon == null) {
|
||||
icon = IconImageStandard(iconId)
|
||||
standardCache[iconId] = icon
|
||||
return standardCache[iconId]
|
||||
}
|
||||
|
||||
return icon
|
||||
fun getStandardIconList(): List<IconImage> {
|
||||
return standardCache.mapIndexed { _, iconImageStandard -> IconImage(iconImageStandard) }
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom
|
||||
*/
|
||||
|
||||
fun putIcon(icon: IconImageCustom) {
|
||||
customCache[icon.uuid] = icon
|
||||
}
|
||||
|
||||
fun getIcon(iconUuid: UUID): IconImageCustom {
|
||||
@@ -48,25 +57,22 @@ class IconPool {
|
||||
return icon
|
||||
}
|
||||
|
||||
fun putIcon(icon: IconImageCustom) {
|
||||
customCache[icon.uuid] = icon
|
||||
}
|
||||
|
||||
fun containsCustomIcons(): Boolean {
|
||||
return customCache.isNotEmpty()
|
||||
}
|
||||
|
||||
fun doForEachCustomIcon(action: (customIcon: IconImageCustom) -> Unit) {
|
||||
fun getCustomIconList(): List<IconImage> {
|
||||
val list = ArrayList<IconImage>(customCache.size)
|
||||
for ((_, customIcon) in customCache) {
|
||||
action.invoke(customIcon!!)
|
||||
list.add(IconImage(customIcon!!))
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the cache of icons
|
||||
*/
|
||||
fun clearCache() {
|
||||
standardCache.clear()
|
||||
customCache.clear()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -701,11 +701,11 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
|
||||
|
||||
xml.startTag(null, DatabaseKDBXXML.ElemCustomIcons)
|
||||
|
||||
mDatabaseKDBX.iconPool.doForEachCustomIcon { customIcon ->
|
||||
mDatabaseKDBX.iconPool.getCustomIconList().forEach { icon ->
|
||||
xml.startTag(null, DatabaseKDBXXML.ElemCustomIconItem)
|
||||
|
||||
writeUuid(DatabaseKDBXXML.ElemCustomIconItemID, customIcon.uuid)
|
||||
writeObject(DatabaseKDBXXML.ElemCustomIconItemData, String(Base64.encode(customIcon.imageData, BASE_64_FLAG)))
|
||||
writeUuid(DatabaseKDBXXML.ElemCustomIconItemID, icon.custom.uuid)
|
||||
writeObject(DatabaseKDBXXML.ElemCustomIconItemData, String(Base64.encode(icon.custom.imageData, BASE_64_FLAG)))
|
||||
|
||||
xml.endTag(null, DatabaseKDBXXML.ElemCustomIconItem)
|
||||
}
|
||||
|
||||
@@ -111,19 +111,14 @@ class IconDrawableFactory {
|
||||
fun getIconSuperDrawable(context: Context, icon: IconImage, width: Int, tint: Boolean = false, tintColor: Int = Color.WHITE): SuperDrawable {
|
||||
return if (!icon.custom.isUnknown) {
|
||||
SuperDrawable(getIconDrawable(context.resources, icon.custom))
|
||||
} else IconPackChooser.getSelectedIconPack(context)?.iconToResId(icon.standard.id)?.let { resId ->
|
||||
getIconSuperDrawable(context, resId, width, tint, tintColor)
|
||||
} else {
|
||||
val iconPack = IconPackChooser.getSelectedIconPack(context)
|
||||
iconPack?.iconToResId(icon.standard.id)?.let { iconId ->
|
||||
SuperDrawable(getIconDrawable(context.resources, iconId, width, tint, tintColor), iconPack.tintable())
|
||||
} ?: run {
|
||||
SuperDrawable(PatternIcon(context.resources).blankDrawable)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the [SuperDrawable] IconImageStandard from [iconId] (cache, or build it and add it to the cache if not exists yet)
|
||||
* , then [tint] it with [tintColor] if needed
|
||||
*/
|
||||
fun getIconSuperDrawable(context: Context, iconId: Int, width: Int, tint: Boolean, tintColor: Int): SuperDrawable {
|
||||
return SuperDrawable(getIconDrawable(context.resources, iconId, width, tint, tintColor), true)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,28 +253,6 @@ class IconDrawableFactory {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a default database icon to an ImageView and tint it with [tintColor] if needed
|
||||
*/
|
||||
fun ImageView.assignDefaultDatabaseIcon(iconFactory: IconDrawableFactory,
|
||||
tintColor: Int = Color.WHITE) {
|
||||
try {
|
||||
IconPackChooser.getSelectedIconPack(context)?.let { selectedIconPack ->
|
||||
iconFactory.assignDrawableToImageView(
|
||||
iconFactory.getIconSuperDrawable(context,
|
||||
selectedIconPack.defaultIconId,
|
||||
width,
|
||||
selectedIconPack.tintable(),
|
||||
tintColor),
|
||||
this,
|
||||
selectedIconPack.tintable(),
|
||||
tintColor)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(ImageView::class.java.name, "Unable to assign icon in image view", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a database [icon] to an ImageView and tint it with [tintColor] if needed
|
||||
*/
|
||||
|
||||
@@ -134,7 +134,6 @@ class IconPack(packageName: String, resources: Resources, resourceId: Int) {
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val NB_ICONS = 68
|
||||
const val NB_ICONS = 68
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ object IconPackChooser {
|
||||
fun setSelectedIconPack(iconPackIdString: String?) {
|
||||
for (iconPack in iconPackList) {
|
||||
if (iconPack.id == iconPackIdString) {
|
||||
Database.getInstance().drawFactory.clearCache()
|
||||
Database.getInstance().iconDrawableFactory.clearCache()
|
||||
iconPackSelected = iconPack
|
||||
break
|
||||
}
|
||||
|
||||
35
app/src/main/res/layout/fragment_icon_custom_picker.xml
Normal file
35
app/src/main/res/layout/fragment_icon_custom_picker.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2021 Jeremy Jamet / Kunzisoft.
|
||||
|
||||
This file is part of KeePassDX.
|
||||
|
||||
KeePassDX is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
KeePassDX is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/icons_grid_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
|
||||
app:spanCount="2"
|
||||
android:verticalSpacing="32dp"
|
||||
android:paddingTop="20dp"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:columnWidth="64dp"
|
||||
android:numColumns="auto_fit"
|
||||
android:stretchMode="spacingWidthUniform">
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
@@ -17,10 +17,14 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/IconGridView"
|
||||
android:layout_width="wrap_content"
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/icons_grid_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
|
||||
app:spanCount="2"
|
||||
android:verticalSpacing="32dp"
|
||||
android:paddingTop="20dp"
|
||||
android:gravity="center"
|
||||
@@ -28,4 +32,4 @@
|
||||
android:columnWidth="64dp"
|
||||
android:numColumns="auto_fit"
|
||||
android:stretchMode="spacingWidthUniform">
|
||||
</GridView>
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
|
||||
Reference in New Issue
Block a user