增加无极字重切换
This commit is contained in:
+167
-12
@@ -1,25 +1,32 @@
|
||||
package io.legato.kazusa.ui.font
|
||||
package io.legato.kazusa.ui.book.read.config
|
||||
|
||||
import android.net.Uri
|
||||
//import io.legado.app.lib.theme.primaryColor
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.net.toUri
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import io.legato.kazusa.R
|
||||
import io.legato.kazusa.base.BaseBottomSheetDialogFragment
|
||||
import io.legato.kazusa.base.BaseDialogFragment
|
||||
import io.legato.kazusa.base.adapter.ItemViewHolder
|
||||
import io.legato.kazusa.base.adapter.RecyclerAdapter
|
||||
import io.legato.kazusa.constant.AppLog
|
||||
import io.legato.kazusa.constant.EventBus
|
||||
import io.legato.kazusa.constant.PreferKey
|
||||
import io.legato.kazusa.databinding.DialogFontSelectBinding
|
||||
import io.legato.kazusa.databinding.ItemFontBinding
|
||||
import io.legato.kazusa.help.config.AppConfig
|
||||
import io.legato.kazusa.help.config.ReadBookConfig
|
||||
import io.legato.kazusa.lib.dialogs.SelectItem
|
||||
import io.legato.kazusa.lib.dialogs.alert
|
||||
import io.legato.kazusa.lib.permission.Permissions
|
||||
import io.legato.kazusa.lib.permission.PermissionsCompat
|
||||
//import io.legado.app.lib.theme.primaryColor
|
||||
import io.legato.kazusa.ui.file.HandleFileContract
|
||||
import io.legato.kazusa.utils.FileDoc
|
||||
import io.legato.kazusa.utils.FileUtils
|
||||
@@ -28,28 +35,30 @@ import io.legato.kazusa.utils.applyTint
|
||||
import io.legato.kazusa.utils.cnCompare
|
||||
import io.legato.kazusa.utils.externalFiles
|
||||
import io.legato.kazusa.utils.getPrefString
|
||||
import io.legato.kazusa.utils.invisible
|
||||
import io.legato.kazusa.utils.isContentScheme
|
||||
import io.legato.kazusa.utils.list
|
||||
import io.legato.kazusa.utils.listFileDocs
|
||||
import io.legato.kazusa.utils.postEvent
|
||||
import io.legato.kazusa.utils.printOnDebug
|
||||
import io.legato.kazusa.utils.putPrefString
|
||||
import io.legato.kazusa.utils.setLayout
|
||||
import io.legato.kazusa.utils.toastOnUi
|
||||
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
||||
import io.legato.kazusa.utils.visible
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
import androidx.core.net.toUri
|
||||
import java.net.URLDecoder
|
||||
|
||||
/**
|
||||
* 字体选择对话框
|
||||
*/
|
||||
class FontSelectDialog : BaseBottomSheetDialogFragment(R.layout.dialog_font_select),
|
||||
Toolbar.OnMenuItemClickListener,
|
||||
FontAdapter.CallBack {
|
||||
Toolbar.OnMenuItemClickListener {
|
||||
private val fontRegex = Regex("(?i).*\\.[ot]tf")
|
||||
private val binding by viewBinding(DialogFontSelectBinding::bind)
|
||||
private val adapter by lazy {
|
||||
val curFontPath = callBack?.curFontPath ?: ""
|
||||
FontAdapter(requireContext(), curFontPath, this)
|
||||
FontAdapter(requireContext(), curFontPath)
|
||||
}
|
||||
private val selectFontDir = registerForActivityResult(HandleFileContract()) {
|
||||
it.uri?.let { uri ->
|
||||
@@ -78,9 +87,17 @@ class FontSelectDialog : BaseBottomSheetDialogFragment(R.layout.dialog_font_sele
|
||||
binding.toolBar.inflateMenu(R.menu.font_select)
|
||||
binding.toolBar.menu.applyTint(requireContext())
|
||||
binding.toolBar.setOnMenuItemClickListener(this)
|
||||
binding.recyclerView.layoutManager = LinearLayoutManager(context)
|
||||
binding.recyclerView.layoutManager = GridLayoutManager(context, 2)
|
||||
binding.recyclerView.adapter = adapter
|
||||
|
||||
|
||||
initView()
|
||||
upView()
|
||||
initViewEvent()
|
||||
}
|
||||
|
||||
private fun initView() = binding.run {
|
||||
|
||||
val fontPath = getPrefString(PreferKey.fontFolder)
|
||||
if (fontPath.isNullOrEmpty()) {
|
||||
openFolder()
|
||||
@@ -96,6 +113,93 @@ class FontSelectDialog : BaseBottomSheetDialogFragment(R.layout.dialog_font_sele
|
||||
loadFontFilesByPermission(fontPath)
|
||||
}
|
||||
}
|
||||
|
||||
dsbTextLetterSpacing.valueFormat = {
|
||||
((it - 50) / 100f).toString()
|
||||
}
|
||||
dsbLineSize.valueFormat = { ((it - 10) / 10f).toString() }
|
||||
|
||||
binding.bgTextIndent.apply {
|
||||
val currentIndex = ReadBookConfig.paragraphIndent.length.coerceAtMost(childCount - 1)
|
||||
val defaultButtonId = getChildAt(currentIndex).id
|
||||
check(defaultButtonId)
|
||||
|
||||
addOnButtonCheckedListener { group, checkedId, isChecked ->
|
||||
if (isChecked) {
|
||||
val checkedIndex = (0 until group.childCount)
|
||||
.firstOrNull { group.getChildAt(it).id == checkedId }
|
||||
?: return@addOnButtonCheckedListener
|
||||
|
||||
ReadBookConfig.paragraphIndent = " ".repeat(checkedIndex)
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(8, 5))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val weightOptions = context?.resources?.getStringArray(R.array.text_font_weight)
|
||||
val weightValues = listOf(500, 700, 300)
|
||||
val initialIndex = weightValues.indexOf(ReadBookConfig.textBold)
|
||||
|
||||
binding.textFontWeightConverter.text = weightOptions?.getOrNull(initialIndex) ?: "自定义"
|
||||
binding.textFontWeightConverter.setOnClickListener {
|
||||
context?.alert(titleResource = R.string.text_font_weight_converter) {
|
||||
weightOptions?.let { options ->
|
||||
items(options.toList()) { _, i ->
|
||||
ReadBookConfig.textBold = weightValues[i]
|
||||
binding.sliderFontWeight.value =
|
||||
ReadBookConfig.textBold.toFloat().coerceAtLeast(100f)
|
||||
binding.textFontWeightConverter.text = options.getOrNull(i) ?: ""
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(8, 9, 6))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binding.sliderFontWeight.apply {
|
||||
valueFrom = 100f
|
||||
valueTo = 900f
|
||||
stepSize = 10f
|
||||
value = ReadBookConfig.textBold.toFloat().coerceAtLeast(100f)
|
||||
addOnChangeListener { _, newValue, _ ->
|
||||
binding.textFontWeightConverter.text = "自定义"
|
||||
ReadBookConfig.textBold = newValue.toInt()
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(8, 9, 6))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initViewEvent() = binding.run {
|
||||
dsbTextLetterSpacing.onChanged = {
|
||||
ReadBookConfig.letterSpacing = (it - 50) / 100f
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(8, 5))
|
||||
}
|
||||
dsbLineSize.onChanged = {
|
||||
ReadBookConfig.lineSpacingExtra = it
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(8, 5))
|
||||
}
|
||||
binding.dsbParagraphSpacing.apply {
|
||||
valueFrom = 0f
|
||||
valueTo = 20f
|
||||
stepSize = 1f
|
||||
value = ReadBookConfig.paragraphSpacing.toFloat()
|
||||
textParagraphSpacing.text = (ReadBookConfig.paragraphSpacing.toFloat() / 10f).toString()
|
||||
addOnChangeListener { slider, newValue, fromUser ->
|
||||
binding.textParagraphSpacing.text = (newValue / 10f).toString()
|
||||
|
||||
if (fromUser) {
|
||||
ReadBookConfig.paragraphSpacing = newValue.toInt()
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(8, 5))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun upView() = binding.run {
|
||||
ReadBookConfig.let {
|
||||
dsbTextLetterSpacing.progress = (it.letterSpacing * 100).toInt() + 50
|
||||
dsbLineSize.progress = it.lineSpacingExtra
|
||||
dsbParagraphSpacing.value = it.paragraphSpacing.toFloat()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(item: MenuItem?): Boolean {
|
||||
@@ -183,7 +287,7 @@ class FontSelectDialog : BaseBottomSheetDialogFragment(R.layout.dialog_font_sele
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFontSelect(docItem: FileDoc) {
|
||||
fun onFontSelect(docItem: FileDoc) {
|
||||
execute {
|
||||
callBack?.selectFont(docItem.toString())
|
||||
}.onSuccess {
|
||||
@@ -198,6 +302,57 @@ class FontSelectDialog : BaseBottomSheetDialogFragment(R.layout.dialog_font_sele
|
||||
private val callBack: CallBack?
|
||||
get() = (parentFragment as? CallBack) ?: (activity as? CallBack)
|
||||
|
||||
inner class FontAdapter(context: Context, curFilePath: String) :
|
||||
RecyclerAdapter<FileDoc, ItemFontBinding>(context) {
|
||||
|
||||
private val curName = runCatching {
|
||||
URLDecoder.decode(curFilePath, "utf-8")
|
||||
}.getOrNull()?.substringAfterLast(File.separator)
|
||||
|
||||
override fun getViewBinding(parent: ViewGroup): ItemFontBinding {
|
||||
return ItemFontBinding.inflate(inflater, parent, false)
|
||||
}
|
||||
|
||||
override fun convert(
|
||||
holder: ItemViewHolder,
|
||||
binding: ItemFontBinding,
|
||||
item: FileDoc,
|
||||
payloads: MutableList<Any>
|
||||
) {
|
||||
binding.run {
|
||||
runCatching {
|
||||
val typeface: Typeface? = if (item.isContentScheme) {
|
||||
context.contentResolver
|
||||
.openFileDescriptor(item.uri, "r")?.use {
|
||||
Typeface.Builder(it.fileDescriptor).build()
|
||||
}
|
||||
} else {
|
||||
Typeface.createFromFile(item.uri.path!!)
|
||||
}
|
||||
tvFont.typeface = typeface
|
||||
}.onFailure {
|
||||
it.printOnDebug()
|
||||
AppLog.put("读取字体 ${item.name} 出错\n${it.localizedMessage}", it, true)
|
||||
}
|
||||
tvFont.text = item.name
|
||||
root.setOnClickListener { onFontSelect(item) }
|
||||
if (item.name == curName) {
|
||||
ivChecked.visible()
|
||||
} else {
|
||||
ivChecked.invisible()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerListener(holder: ItemViewHolder, binding: ItemFontBinding) {
|
||||
holder.itemView.setOnClickListener {
|
||||
getItem(holder.layoutPosition)?.let {
|
||||
onFontSelect(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface CallBack {
|
||||
fun selectFont(path: String)
|
||||
val curFontPath: String
|
||||
@@ -912,24 +912,18 @@ object ChapterProvider {
|
||||
|
||||
private fun getPaints(typeface: Typeface?): Pair<TextPaint, TextPaint> {
|
||||
// 字体统一处理
|
||||
val bold = Typeface.create(typeface, Typeface.BOLD)
|
||||
val normal = Typeface.create(typeface, Typeface.NORMAL)
|
||||
val (titleFont, textFont) = when (ReadBookConfig.textBold) {
|
||||
1 -> {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
|
||||
Pair(Typeface.create(typeface, 900, false), bold)
|
||||
else
|
||||
Pair(bold, bold)
|
||||
val (titleFont, textFont) = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
Pair(
|
||||
Typeface.create(typeface, ReadBookConfig.textBold, false),
|
||||
Typeface.create(typeface, ReadBookConfig.textBold, false)
|
||||
)
|
||||
} else {
|
||||
val tf = when (ReadBookConfig.textBold) {
|
||||
in 700..900 -> Typeface.DEFAULT_BOLD
|
||||
in 300..499 -> Typeface.DEFAULT
|
||||
else -> Typeface.DEFAULT
|
||||
}
|
||||
|
||||
2 -> {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
|
||||
Pair(normal, Typeface.create(typeface, 300, false))
|
||||
else
|
||||
Pair(normal, normal)
|
||||
}
|
||||
|
||||
else -> Pair(bold, normal)
|
||||
Pair(tf, tf)
|
||||
}
|
||||
|
||||
//标题
|
||||
|
||||
Reference in New Issue
Block a user