Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve breadcrumbs #48

Merged
merged 8 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.content.pm.PackageManager
import android.content.res.Configuration
import android.graphics.Color
import android.view.ViewGroup
import androidx.core.content.res.ResourcesCompat
import androidx.loader.content.CursorLoader
import org.fossify.commons.R
import org.fossify.commons.helpers.*
Expand Down Expand Up @@ -216,3 +217,13 @@ fun Context.getBottomNavigationBackgroundColor(): Int {
}
return bottomColor
}

fun Context.getDialogBackgroundColor(): Int {
return when {
isDynamicTheme() -> ResourcesCompat.getColor(
resources, R.color.you_dialog_background_color, theme
)

else -> baseConfig.backgroundColor
}
}
152 changes: 75 additions & 77 deletions commons/src/main/kotlin/org/fossify/commons/views/Breadcrumbs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,50 @@ package org.fossify.commons.views

import android.content.Context
import android.content.res.ColorStateList
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.RippleDrawable
import android.util.AttributeSet
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.widget.HorizontalScrollView
import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.view.ViewCompat
import androidx.core.view.updatePadding
import androidx.core.widget.TextViewCompat
import org.fossify.commons.R
import org.fossify.commons.databinding.ItemBreadcrumbBinding
import org.fossify.commons.databinding.ItemBreadcrumbFirstBinding
import org.fossify.commons.extensions.*
import org.fossify.commons.extensions.adjustAlpha
import org.fossify.commons.extensions.getBasePath
import org.fossify.commons.extensions.getDialogBackgroundColor
import org.fossify.commons.extensions.getProperPrimaryColor
import org.fossify.commons.extensions.getProperTextColor
import org.fossify.commons.extensions.humanizePath
import org.fossify.commons.extensions.onGlobalLayout
import org.fossify.commons.extensions.setDrawablesRelativeWithIntrinsicBounds
import org.fossify.commons.helpers.MEDIUM_ALPHA
import org.fossify.commons.models.FileDirItem

class Breadcrumbs(context: Context, attrs: AttributeSet) : HorizontalScrollView(context, attrs) {
private val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
private val inflater =
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
private val itemsLayout: LinearLayout
private var textColor = context.getProperTextColor()
private var accentColor = context.getProperPrimaryColor()
private var fontSize = resources.getDimension(R.dimen.bigger_text_size)
private var lastPath = ""
private var isLayoutDirty = true
private var isScrollToSelectedItemPending = false
private var isFirstScroll = true
private var stickyRootInitialLeft = 0
private var rootStartPadding = 0

private val textColorStateList: ColorStateList
get() = ColorStateList(
arrayOf(intArrayOf(android.R.attr.state_activated), intArrayOf()),
intArrayOf(
textColor,
textColor.adjustAlpha(0.6f)
accentColor,
textColor
)
)

Expand All @@ -45,8 +56,7 @@ class Breadcrumbs(context: Context, attrs: AttributeSet) : HorizontalScrollView(
isHorizontalScrollBarEnabled = false
itemsLayout = LinearLayout(context)
itemsLayout.orientation = LinearLayout.HORIZONTAL
rootStartPadding = paddingStart
itemsLayout.setPaddingRelative(0, paddingTop, paddingEnd, paddingBottom)
itemsLayout.setPaddingRelative(paddingStart, paddingTop, paddingEnd, paddingBottom)
setPaddingRelative(0, 0, 0, 0)
addView(itemsLayout, LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT))
onGlobalLayout {
Expand Down Expand Up @@ -146,87 +156,75 @@ class Breadcrumbs(context: Context, attrs: AttributeSet) : HorizontalScrollView(
val tempPath = context.humanizePath(fullPath)

itemsLayout.removeAllViews()
val dirs = tempPath.split("/").dropLastWhile(String::isEmpty)
for (i in dirs.indices) {
val dir = dirs[i]
if (i > 0) {
currPath += dir + "/"
}

if (dir.isEmpty()) {
continue
tempPath.split("/")
.dropLastWhile(String::isEmpty)
.forEachIndexed { i, dir ->
if (i > 0) {
currPath += "$dir/"
}
if (dir.isEmpty()) {
return@forEachIndexed
}
currPath = "${currPath.trimEnd('/')}/"
val item = FileDirItem(currPath, dir, true, 0, 0, 0)
addBreadcrumb(
item = item,
index = i,
isLast = item.path.trimEnd('/') == lastPath.trimEnd('/')
)
scrollToSelectedItem()
}

currPath = "${currPath.trimEnd('/')}/"
val item = FileDirItem(currPath, dir, true, 0, 0, 0)
addBreadcrumb(item, i, i > 0)
scrollToSelectedItem()
}
}

private fun addBreadcrumb(item: FileDirItem, index: Int, addPrefix: Boolean) {
if (itemsLayout.childCount == 0) {
val firstItemBgColor = if (isShownInDialog && context.isDynamicTheme()) {
resources.getColor(R.color.you_dialog_background_color, context.theme)
} else {
context.getProperBackgroundColor()
}

private fun addBreadcrumb(item: FileDirItem, index: Int, isLast: Boolean) {
ItemBreadcrumbBinding.inflate(inflater, itemsLayout, false).apply {
breadcrumbText.isActivated = isLast

ItemBreadcrumbFirstBinding.inflate(inflater, itemsLayout, false).apply {
resources.apply {
breadcrumbText.background = ContextCompat.getDrawable(context, R.drawable.button_background)
breadcrumbText.background.applyColorFilter(textColor)
elevation = 1f
background = ColorDrawable(firstItemBgColor)
val medium = getDimension(R.dimen.medium_margin).toInt()
breadcrumbText.setPadding(medium, medium, medium, medium)
setPadding(rootStartPadding, 0, 0, 0)
}
breadcrumbText.text = item.name
breadcrumbText.setTextColor(textColorStateList)
breadcrumbText.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize)

isActivated = item.path.trimEnd('/') == lastPath.trimEnd('/')
breadcrumbText.text = item.name
breadcrumbText.setTextColor(textColorStateList)
breadcrumbText.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize)
itemsLayout.addView(root)
if (index > 0) {
breadcrumbText.setDrawablesRelativeWithIntrinsicBounds(
start = AppCompatResources.getDrawable(
context, R.drawable.ic_chevron_right_vector
)
)

itemsLayout.addView(this.root)
TextViewCompat.setCompoundDrawableTintList(breadcrumbText, textColorStateList)
} else {
breadcrumbText.elevation = context.resources.getDimension(R.dimen.one_dp)
setupStickyBreadcrumbBackground(breadcrumbText)
val horizontalPadding =
context.resources.getDimensionPixelSize(R.dimen.normal_margin)
breadcrumbText.updatePadding(left = horizontalPadding, right = horizontalPadding)
}

breadcrumbText.setOnClickListener {
if (itemsLayout.getChildAt(index) != null) {
breadcrumbText.setOnClickListener { v ->
if (itemsLayout.getChildAt(index) != null && itemsLayout.getChildAt(index) == v) {
if (index != 0 && isLast) {
scrollToSelectedItem()
} else {
listener?.breadcrumbClicked(index)
}
}

root.tag = item
}
} else {
ItemBreadcrumbBinding.inflate(inflater, itemsLayout, false).apply {
var textToAdd = item.name
if (addPrefix) {
textToAdd = "> $textToAdd"
}

isActivated = item.path.trimEnd('/') == lastPath.trimEnd('/')

breadcrumbText.text = textToAdd
breadcrumbText.setTextColor(textColorStateList)
breadcrumbText.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize)

itemsLayout.addView(root)

breadcrumbText.setOnClickListener { v ->
if (itemsLayout.getChildAt(index) != null && itemsLayout.getChildAt(index) == v) {
if ((v.tag as? FileDirItem)?.path?.trimEnd('/') == lastPath.trimEnd('/')) {
scrollToSelectedItem()
} else {
listener?.breadcrumbClicked(index)
}
}
}
root.tag = item
}
}

root.tag = item
private fun setupStickyBreadcrumbBackground(view: MyTextView) {
val drawable = view.background.mutate() as RippleDrawable
(drawable.getDrawable(0) as GradientDrawable)
.apply {
setColor(context.getDialogBackgroundColor())
setStroke(
context.resources.getDimensionPixelSize(R.dimen.one_dp),
context.getProperPrimaryColor().adjustAlpha(MEDIUM_ALPHA)
)
}
}
}

fun updateColor(color: Int) {
Expand Down
17 changes: 17 additions & 0 deletions commons/src/main/res/drawable/breadcrumb_button_background.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:attr/colorControlHighlight">
<item android:id="@android:id/background">
<shape android:shape="rectangle">
<solid android:color="@android:color/transparent" />
<corners android:radius="@dimen/material_button_corner_radius" />
</shape>
</item>

<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<solid android:color="@color/white" />
<corners android:radius="@dimen/material_button_corner_radius" />
</shape>
</item>
</ripple>
13 changes: 8 additions & 5 deletions commons/src/main/res/layout/item_breadcrumb.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fossify.commons.views.MyTextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/breadcrumb_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/breadcrumb_button_background"
android:gravity="center_vertical"
android:minHeight="@dimen/breadcrumbs_layout_height"
android:paddingLeft="@dimen/small_margin"
android:paddingTop="@dimen/medium_margin"
android:paddingRight="@dimen/small_margin"
android:paddingBottom="@dimen/medium_margin"
android:textSize="@dimen/normal_text_size" />
android:paddingVertical="@dimen/medium_margin"
android:paddingStart="0dp"
android:paddingEnd="@dimen/tiny_margin"
android:textSize="@dimen/normal_text_size"
tools:drawableStart="@drawable/ic_chevron_right_vector"
tools:text="Fossify" />
19 changes: 0 additions & 19 deletions commons/src/main/res/layout/item_breadcrumb_first.xml

This file was deleted.

Loading