Add foreground and background colors in list

This commit is contained in:
J-Jamet
2022-01-12 19:50:38 +01:00
parent 05fad24eda
commit cfdc0237d7
6 changed files with 174 additions and 129 deletions

View File

@@ -21,7 +21,6 @@ package com.kunzisoft.keepass.adapters
import android.content.Context
import android.graphics.Color
import android.graphics.PorterDuff
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
@@ -32,10 +31,10 @@ import android.widget.TextView
import android.widget.Toast
import androidx.annotation.ColorInt
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SortedList
import androidx.recyclerview.widget.SortedListAdapterCallback
import com.google.android.material.progressindicator.CircularProgressIndicator
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.Entry
@@ -91,9 +90,15 @@ class NodesAdapter (private val context: Context,
@ColorInt
private val mContentSelectionColor: Int
@ColorInt
private val mIconGroupColor: Int
private val mTextColorPrimary: Int
@ColorInt
private val mIconEntryColor: Int
private val mTextColor: Int
@ColorInt
private val mTextColorSecondary: Int
@ColorInt
private val mColorAccentLight: Int
@ColorInt
private val mTextColorInverse: Int
/**
* Determine if the adapter contains or not any element
@@ -114,12 +119,24 @@ class NodesAdapter (private val context: Context,
this.mContentSelectionColor = ContextCompat.getColor(context, R.color.white)
// Retrieve the color to tint the icon
val taTextColorPrimary = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColorPrimary))
this.mIconGroupColor = taTextColorPrimary.getColor(0, Color.BLACK)
this.mTextColorPrimary = taTextColorPrimary.getColor(0, Color.BLACK)
taTextColorPrimary.recycle()
// In two times to fix bug compilation
// To get text color
val taTextColor = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColor))
this.mIconEntryColor = taTextColor.getColor(0, Color.BLACK)
this.mTextColor = taTextColor.getColor(0, Color.BLACK)
taTextColor.recycle()
// To get text color secondary
val taTextColorSecondary = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColorSecondary))
this.mTextColorSecondary = taTextColorSecondary.getColor(0, Color.BLACK)
taTextColorSecondary.recycle()
// To get background color for selection
val taSelectionColor = context.theme.obtainStyledAttributes(intArrayOf(R.attr.colorAccentLight))
this.mColorAccentLight = taSelectionColor.getColor(0, Color.GRAY)
taSelectionColor.recycle()
// To get text color for selection
val taSelectionTextColor = context.theme.obtainStyledAttributes(intArrayOf(R.attr.textColorInverse))
this.mTextColorInverse = taSelectionTextColor.getColor(0, Color.WHITE)
taSelectionTextColor.recycle()
}
private fun assignPreferences() {
@@ -167,6 +184,8 @@ class NodesAdapter (private val context: Context,
if (oldItem is Entry && newItem is Entry) {
typeContentTheSame = oldItem.getVisualTitle() == newItem.getVisualTitle()
&& oldItem.username == newItem.username
&& oldItem.backgroundColor == newItem.backgroundColor
&& oldItem.foregroundColor == newItem.foregroundColor
&& oldItem.getOtpElement() == newItem.getOtpElement()
&& oldItem.containsAttachment() == newItem.containsAttachment()
} else if (oldItem is Group && newItem is Group) {
@@ -336,8 +355,8 @@ class NodesAdapter (private val context: Context,
val iconColor = if (holder.container.isSelected)
mContentSelectionColor
else when (subNode.type) {
Type.GROUP -> mIconGroupColor
Type.ENTRY -> mIconEntryColor
Type.GROUP -> mTextColorPrimary
Type.ENTRY -> mTextColor
}
holder.imageIdentifier?.setColorFilter(iconColor)
holder.icon.apply {
@@ -381,25 +400,6 @@ class NodesAdapter (private val context: Context,
val entry = subNode as Entry
database.startManageEntry(entry)
// Assign colors
val backgroundColor = entry.backgroundColor
if (backgroundColor != null) {
holder.backgroundView?.setColorFilter(backgroundColor, PorterDuff.Mode.SRC_ATOP)
holder.backgroundView?.isVisible = true
} else {
holder.backgroundView?.isVisible = false
}
val foregroundColor = entry.foregroundColor
if (foregroundColor != null) {
holder.foregroundView?.setColorFilter(foregroundColor, PorterDuff.Mode.SRC_ATOP)
holder.icon.apply {
database.iconDrawableFactory.assignDatabaseIcon(this, subNode.icon, foregroundColor)
}
holder.foregroundView?.isVisible = true
} else {
holder.foregroundView?.isVisible = false
}
holder.text.text = entry.getVisualTitle()
// Add subText with username
holder.subText?.apply {
@@ -436,6 +436,64 @@ class NodesAdapter (private val context: Context,
holder.attachmentIcon?.visibility =
if (entry.containsAttachment()) View.VISIBLE else View.GONE
// Assign colors
val backgroundColor = entry.backgroundColor
if (!holder.container.isSelected) {
if (backgroundColor != null) {
holder.container.setBackgroundColor(backgroundColor)
} else {
holder.container.setBackgroundColor(Color.TRANSPARENT)
}
} else {
holder.container.setBackgroundColor(mColorAccentLight)
}
val foregroundColor = entry.foregroundColor
if (!holder.container.isSelected) {
if (foregroundColor != null) {
holder.text.setTextColor(foregroundColor)
holder.subText?.setTextColor(foregroundColor)
holder.otpToken?.setTextColor(foregroundColor)
holder.otpProgress?.setIndicatorColor(foregroundColor)
holder.attachmentIcon?.setColorFilter(foregroundColor)
holder.meta.setTextColor(foregroundColor)
holder.icon.apply {
database.iconDrawableFactory.assignDatabaseIcon(
this,
subNode.icon,
foregroundColor
)
}
} else {
holder.text.setTextColor(mTextColor)
holder.subText?.setTextColor(mTextColorSecondary)
holder.otpToken?.setTextColor(mTextColorSecondary)
holder.otpProgress?.setIndicatorColor(mTextColorSecondary)
holder.attachmentIcon?.setColorFilter(mTextColorSecondary)
holder.meta.setTextColor(mTextColor)
holder.icon.apply {
database.iconDrawableFactory.assignDatabaseIcon(
this,
subNode.icon,
mTextColor
)
}
}
} else {
holder.text.setTextColor(mTextColorInverse)
holder.subText?.setTextColor(mTextColorInverse)
holder.otpToken?.setTextColor(mTextColorInverse)
holder.otpProgress?.setIndicatorColor(mTextColorInverse)
holder.attachmentIcon?.setColorFilter(mTextColorInverse)
holder.meta.setTextColor(mTextColorInverse)
holder.icon.apply {
database.iconDrawableFactory.assignDatabaseIcon(
this,
subNode.icon,
mTextColorInverse
)
}
}
database.stopManageEntry(entry)
}
@@ -468,13 +526,13 @@ class NodesAdapter (private val context: Context,
OtpType.HOTP -> {
holder?.otpProgress?.apply {
max = 100
progress = 100
setProgressCompat(100, true)
}
}
OtpType.TOTP -> {
holder?.otpProgress?.apply {
max = otpElement.period
progress = otpElement.secondsRemaining
setProgressCompat(otpElement.secondsRemaining, true)
}
}
null -> {}
@@ -533,14 +591,12 @@ class NodesAdapter (private val context: Context,
var container: View = itemView.findViewById(R.id.node_container)
var imageIdentifier: ImageView? = itemView.findViewById(R.id.node_image_identifier)
var icon: ImageView = itemView.findViewById(R.id.node_icon)
var backgroundView: ImageView? = itemView.findViewById(R.id.background_view)
var foregroundView: ImageView? = itemView.findViewById(R.id.foreground_view)
var text: TextView = itemView.findViewById(R.id.node_text)
var subText: TextView? = itemView.findViewById(R.id.node_subtext)
var meta: TextView = itemView.findViewById(R.id.node_meta)
var path: TextView? = itemView.findViewById(R.id.node_path)
var otpContainer: ViewGroup? = itemView.findViewById(R.id.node_otp_container)
var otpProgress: ProgressBar? = itemView.findViewById(R.id.node_otp_progress)
var otpProgress: CircularProgressIndicator? = itemView.findViewById(R.id.node_otp_progress)
var otpToken: TextView? = itemView.findViewById(R.id.node_otp_token)
var otpRunnable: OtpRunnable = OtpRunnable(otpContainer)
var numberChildren: TextView? = itemView.findViewById(R.id.node_child_numbers)

View File

@@ -1,6 +1,8 @@
package com.kunzisoft.keepass.view
import android.content.Context
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.os.Build
import android.util.AttributeSet
import android.view.View
@@ -63,6 +65,9 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
}
fun setBackgroundColor(color: Int?) {
color?.let {
backgroundColorButton.colorFilter = PorterDuffColorFilter(it, PorterDuff.Mode.SRC_ATOP)
}
mEntryInfo?.backgroundColor = color
}
@@ -75,6 +80,9 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
}
fun setForegroundColor(color: Int?) {
color?.let {
foregroundColorButton.colorFilter = PorterDuffColorFilter(it, PorterDuff.Mode.SRC_ATOP)
}
mEntryInfo?.foregroundColor = color
}
@@ -220,6 +228,12 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
override fun populateViewsWithEntryInfo(showEmptyFields: Boolean): List<ViewField> {
refreshIcon()
mEntryInfo?.backgroundColor?.let {
backgroundColorButton.colorFilter = PorterDuffColorFilter(it, PorterDuff.Mode.SRC_ATOP)
}
mEntryInfo?.foregroundColor?.let {
foregroundColorButton.colorFilter = PorterDuffColorFilter(it, PorterDuff.Mode.SRC_ATOP)
}
return super.populateViewsWithEntryInfo(showEmptyFields)
}

View File

@@ -22,7 +22,7 @@
android:id="@+id/icon_container"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@drawable/background_item_selection">
style="@style/KeepassDXStyle.Selectable.Item">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon_image"
android:layout_width="wrap_content"

View File

@@ -27,80 +27,53 @@
style="@style/KeepassDXStyle.Selectable.Item">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:background="?android:attr/selectableItemBackground"
android:minHeight="48dp"
app:layout_constraintWidth_percent="@dimen/content_percent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:background="?android:attr/selectableItemBackground" >
<ImageView
android:id="@+id/background_view"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="4dp"
android:layout_gravity="center"
android:contentDescription="@string/content_description_entry_background_color"
android:src="@drawable/background_rounded_square"
app:layout_constraintBottom_toBottomOf="@+id/node_icon"
app:layout_constraintEnd_toEndOf="@+id/node_icon"
app:layout_constraintStart_toStartOf="@+id/node_icon"
app:layout_constraintTop_toTopOf="@+id/node_icon"
app:tint="@color/white" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="@dimen/content_percent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/node_icon"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginTop="@dimen/image_list_margin_horizontal"
android:layout_marginBottom="@dimen/image_list_margin_horizontal"
android:layout_marginLeft="@dimen/image_list_margin_vertical"
android:layout_marginStart="@dimen/image_list_margin_vertical"
android:layout_marginRight="@dimen/image_list_margin_vertical"
android:layout_marginEnd="@dimen/image_list_margin_vertical"
android:layout_gravity="center"
android:layout_marginStart="@dimen/image_list_margin_vertical"
android:layout_marginLeft="@dimen/image_list_margin_vertical"
android:layout_marginTop="@dimen/image_list_margin_horizontal"
android:layout_marginEnd="@dimen/image_list_margin_vertical"
android:layout_marginRight="@dimen/image_list_margin_vertical"
android:layout_marginBottom="@dimen/image_list_margin_horizontal"
android:scaleType="fitXY"
android:src="@drawable/ic_blank_32dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
<ImageView
android:id="@+id/foreground_view"
android:layout_width="9dp"
android:layout_height="9dp"
android:layout_marginStart="14dp"
android:layout_marginLeft="14dp"
android:layout_marginBottom="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:contentDescription="@string/content_description_entry_foreground_color"
android:src="@drawable/background_rounded_square" />
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/node_container_info"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:layout_marginStart="@dimen/image_list_margin_vertical"
android:layout_marginLeft="@dimen/image_list_margin_vertical"
android:layout_marginEnd="12dp"
android:layout_marginRight="12dp"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
android:paddingTop="4dp"
android:paddingBottom="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/node_icon"
app:layout_constraintLeft_toRightOf="@+id/node_icon"
app:layout_constraintEnd_toStartOf="@+id/node_options"
app:layout_constraintRight_toLeftOf="@+id/node_options">
app:layout_constraintLeft_toRightOf="@+id/node_icon"
app:layout_constraintRight_toLeftOf="@+id/node_options"
app:layout_constraintStart_toEndOf="@+id/node_icon"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/node_text"
@@ -144,26 +117,26 @@
android:id="@+id/node_options"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="end"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
app:layout_constraintTop_toTopOf="parent"
android:gravity="end"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent">
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:id="@+id/node_otp_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:layout_marginRight="12dp"
android:padding="4dp"
android:orientation="horizontal"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:background="?android:attr/selectableItemBackground"
app:layout_constraintTop_toTopOf="parent"
android:orientation="horizontal"
android:padding="4dp"
app:layout_constraintBottom_toTopOf="@+id/node_attachment_icon"
app:layout_constraintEnd_toEndOf="parent">
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/node_otp_token"
@@ -172,20 +145,22 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
tools:text="5136" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="4dp"
android:layout_marginLeft="4dp">
<ProgressBar
<com.google.android.material.progressindicator.CircularProgressIndicator
android:id="@+id/node_otp_progress"
style="@style/KeepassDXStyle.ProgressBar.Circle.Secondary"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_gravity="center"
android:max="100"
android:progress="60" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:indicatorSize="16dp"
app:trackThickness="2dp"
app:indicatorDirectionCircular="counterclockwise"
android:layout_gravity="center" />
</FrameLayout>
</LinearLayout>
@@ -207,12 +182,12 @@
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider"
android:layout_marginLeft="72dp"
android:layout_marginStart="72dp"
android:layout_marginRight="48dp"
android:layout_marginLeft="72dp"
android:layout_marginEnd="48dp"
app:layout_constraintBottom_toBottomOf="parent"/>
android:layout_marginRight="48dp"
android:background="?android:attr/listDivider"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -33,6 +33,26 @@
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/template_foreground_color_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:layout_gravity="top|start"
android:src="@drawable/ic_color_foreground_white_24dp"
android:contentDescription="@string/content_description_entry_background_color"
style="@style/KeepassDXStyle.ImageButton.Simple.Mini" />
<ImageView
android:id="@+id/template_background_color_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:layout_gravity="top|end"
android:src="@drawable/ic_color_background_white_24dp"
android:contentDescription="@string/content_description_entry_background_color"
style="@style/KeepassDXStyle.ImageButton.Simple.Mini" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
@@ -45,10 +65,9 @@
android:id="@+id/template_icon_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:src="@drawable/ic_blank_32dp"
android:contentDescription="@string/content_description_entry_icon"
android:layout_gravity="center"/>
android:layout_gravity="center"
android:contentDescription="@string/content_description_entry_icon"/>
<!-- Title -->
<FrameLayout
@@ -56,28 +75,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_gravity="end">
<ImageView
android:id="@+id/template_background_color_button"
android:layout_width="42dp"
android:layout_height="42dp"
android:padding="12dp"
android:src="@drawable/ic_color_background_white_24dp"
android:contentDescription="@string/content_description_entry_background_color"
style="@style/KeepassDXStyle.ImageButton.Simple" />
<ImageView
android:id="@+id/template_foreground_color_button"
android:layout_width="42dp"
android:layout_height="42dp"
android:padding="12dp"
android:src="@drawable/ic_color_foreground_white_24dp"
android:contentDescription="@string/content_description_entry_background_color"
style="@style/KeepassDXStyle.ImageButton.Simple" />
</LinearLayout>
</FrameLayout>
</androidx.cardview.widget.CardView>

View File

@@ -436,6 +436,13 @@
<item name="android:colorForeground">@color/background_button_color_secondary</item>
<item name="tint">@color/background_button_color_secondary</item>
</style>
<style name="KeepassDXStyle.ImageButton.Simple.Mini" parent="KeepassDXStyle.ImageButton.Simple">
<item name="android:padding">12dp</item>
<item name="android:layout_width">36dp</item>
<item name="android:layout_height">36dp</item>
<item name="android:colorForeground">@color/background_button_color_secondary</item>
<item name="tint">?android:attr/textColor</item>
</style>
<!-- Item Style -->
<style name="KeepassDXStyle.Selectable.Item" parent="KeepassDXStyle.Light">
@@ -492,10 +499,6 @@
</style>
<!-- Progress bar -->
<style name="KeepassDXStyle.ProgressBar.Circle.Secondary" parent="Widget.AppCompat.ProgressBar.Horizontal">
<item name="android:progressDrawable">@drawable/foreground_progress_circle_secondary</item>
<item name="android:background">@null</item>
</style>
<style name="KeepassDXStyle.ProgressBar.Circle" parent="Widget.AppCompat.ProgressBar.Horizontal">
<item name="android:progressDrawable">@drawable/foreground_progress_circle</item>
<item name="android:background">@drawable/background_progress_circle</item>