mirror of
https://github.com/gedoor/legado.git
synced 2025-08-10 00:52:30 +00:00
优化
This commit is contained in:
@@ -36,8 +36,8 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
}
|
||||
private var callBack: CallBack
|
||||
private val visibleRect = RectF()
|
||||
private val selectStart = arrayOf(0, 0, 0)
|
||||
private val selectEnd = arrayOf(0, 0, 0)
|
||||
private val selectStart = Pos(0, 0, 0)
|
||||
private val selectEnd = Pos(0, 0, 0)
|
||||
var textPage: TextPage = TextPage()
|
||||
private set
|
||||
|
||||
@@ -240,16 +240,10 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
*/
|
||||
fun selectStartMove(x: Float, y: Float) {
|
||||
touch(x, y) { relativePos, _, relativeOffset, lineIndex, textLine, charIndex, textChar ->
|
||||
if (selectStart[0] != relativePos ||
|
||||
selectStart[1] != lineIndex ||
|
||||
selectStart[2] != charIndex
|
||||
) {
|
||||
if (selectToInt(relativePos, lineIndex, charIndex)
|
||||
<= selectToInt(selectEnd)
|
||||
) {
|
||||
selectStart[0] = relativePos
|
||||
selectStart[1] = lineIndex
|
||||
selectStart[2] = charIndex
|
||||
val pos = Pos(relativePos, lineIndex, charIndex)
|
||||
if (selectStart.compare(pos) != 0) {
|
||||
if (pos.compare(selectEnd) <= 0) {
|
||||
selectStart.upData(pos = pos)
|
||||
upSelectedStart(
|
||||
textChar.start,
|
||||
textLine.lineBottom + relativeOffset,
|
||||
@@ -266,16 +260,10 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
*/
|
||||
fun selectEndMove(x: Float, y: Float) {
|
||||
touch(x, y) { relativePos, _, relativeOffset, lineIndex, textLine, charIndex, textChar ->
|
||||
if (selectEnd[0] != relativePos
|
||||
|| selectEnd[1] != lineIndex
|
||||
|| selectEnd[2] != charIndex
|
||||
) {
|
||||
if (selectToInt(relativePos, lineIndex, charIndex)
|
||||
>= selectToInt(selectStart)
|
||||
) {
|
||||
selectEnd[0] = relativePos
|
||||
selectEnd[1] = lineIndex
|
||||
selectEnd[2] = charIndex
|
||||
val pos = Pos(relativePos, lineIndex, charIndex)
|
||||
if (pos.compare(selectEnd) != 0) {
|
||||
if (pos.compare(selectStart) >= 0) {
|
||||
selectEnd.upData(pos)
|
||||
upSelectedEnd(textChar.end, textLine.lineBottom + relativeOffset)
|
||||
upSelectChars()
|
||||
}
|
||||
@@ -329,9 +317,9 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
* 选择开始文字
|
||||
*/
|
||||
fun selectStartMoveIndex(relativePage: Int, lineIndex: Int, charIndex: Int) {
|
||||
selectStart[0] = relativePage
|
||||
selectStart[1] = lineIndex
|
||||
selectStart[2] = charIndex
|
||||
selectStart.relativePos = relativePage
|
||||
selectStart.lineIndex = lineIndex
|
||||
selectStart.charIndex = charIndex
|
||||
val textLine = relativePage(relativePage).getLine(lineIndex)
|
||||
val textChar = textLine.getTextChar(charIndex)
|
||||
upSelectedStart(
|
||||
@@ -346,9 +334,9 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
* 选择结束文字
|
||||
*/
|
||||
fun selectEndMoveIndex(relativePage: Int, lineIndex: Int, charIndex: Int) {
|
||||
selectEnd[0] = relativePage
|
||||
selectEnd[1] = lineIndex
|
||||
selectEnd[2] = charIndex
|
||||
selectEnd.relativePos = relativePage
|
||||
selectEnd.lineIndex = lineIndex
|
||||
selectEnd.charIndex = charIndex
|
||||
val textLine = relativePage(relativePage).getLine(lineIndex)
|
||||
val textChar = textLine.getTextChar(charIndex)
|
||||
upSelectedEnd(textChar.end, textLine.lineBottom + relativeOffset(relativePage))
|
||||
@@ -357,35 +345,13 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
|
||||
private fun upSelectChars() {
|
||||
val last = if (callBack.isScroll) 2 else 0
|
||||
val charPos = Pos(0, 0, 0)
|
||||
for (relativePos in 0..last) {
|
||||
for ((lineIndex, textLine) in relativePage(relativePos).textLines.withIndex()) {
|
||||
for ((charIndex, textChar) in textLine.textChars.withIndex()) {
|
||||
textChar.selected = when {
|
||||
relativePos == selectStart[0]
|
||||
&& relativePos == selectEnd[0]
|
||||
&& lineIndex == selectStart[1]
|
||||
&& lineIndex == selectEnd[1] -> {
|
||||
charIndex in selectStart[2]..selectEnd[2]
|
||||
}
|
||||
relativePos == selectStart[0] && lineIndex == selectStart[1] -> {
|
||||
charIndex >= selectStart[2]
|
||||
}
|
||||
relativePos == selectEnd[0] && lineIndex == selectEnd[1] -> {
|
||||
charIndex <= selectEnd[2]
|
||||
}
|
||||
relativePos == selectStart[0] && relativePos == selectEnd[0] -> {
|
||||
lineIndex in (selectStart[1] + 1) until selectEnd[1]
|
||||
}
|
||||
relativePos == selectStart[0] -> {
|
||||
lineIndex > selectStart[1]
|
||||
}
|
||||
relativePos == selectEnd[0] -> {
|
||||
lineIndex < selectEnd[1]
|
||||
}
|
||||
else -> {
|
||||
relativePos in selectStart[0] + 1 until selectEnd[0]
|
||||
}
|
||||
}
|
||||
charPos.upData(relativePos, lineIndex, charIndex)
|
||||
textChar.selected =
|
||||
charPos.compare(selectStart) >= 0 && charPos.compare(selectEnd) <= 0
|
||||
textChar.isSearchResult = textChar.selected && callBack.isSelectingSearchResult
|
||||
}
|
||||
}
|
||||
@@ -414,103 +380,51 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
callBack.onCancelSelect()
|
||||
}
|
||||
|
||||
val selectedText: String
|
||||
get() {
|
||||
val stringBuilder = StringBuilder()
|
||||
for (relativePos in selectStart[0]..selectEnd[0]) {
|
||||
val textPage = relativePage(relativePos)
|
||||
when {
|
||||
relativePos == selectStart[0] && relativePos == selectEnd[0] -> {
|
||||
for (lineIndex in selectStart[1]..selectEnd[1]) {
|
||||
when {
|
||||
lineIndex == selectStart[1] && lineIndex == selectEnd[1] -> {
|
||||
stringBuilder.append(
|
||||
textPage.textLines[lineIndex].text
|
||||
.substring(selectStart[2], selectEnd[2] + 1)
|
||||
)
|
||||
}
|
||||
lineIndex == selectStart[1] -> {
|
||||
stringBuilder.append(
|
||||
textPage.textLines[lineIndex].text
|
||||
.substring(selectStart[2])
|
||||
)
|
||||
}
|
||||
lineIndex == selectEnd[1] -> {
|
||||
stringBuilder.append(
|
||||
textPage.textLines[lineIndex].text
|
||||
.substring(0, selectEnd[2] + 1)
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
stringBuilder.append(textPage.textLines[lineIndex].text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
relativePos == selectStart[0] -> {
|
||||
for (lineIndex in selectStart[1] until textPage.textLines.size) {
|
||||
when (lineIndex) {
|
||||
selectStart[1] -> {
|
||||
stringBuilder.append(
|
||||
textPage.textLines[lineIndex].text
|
||||
.substring(selectStart[2])
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
stringBuilder.append(textPage.textLines[lineIndex].text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
relativePos == selectEnd[0] -> {
|
||||
for (lineIndex in 0..selectEnd[1]) {
|
||||
when (lineIndex) {
|
||||
selectEnd[1] -> {
|
||||
stringBuilder.append(
|
||||
textPage.textLines[lineIndex].text
|
||||
.substring(0, selectEnd[2] + 1)
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
stringBuilder.append(textPage.textLines[lineIndex].text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
relativePos in selectStart[0] + 1 until selectEnd[0] -> {
|
||||
for (lineIndex in selectStart[1]..selectEnd[1]) {
|
||||
stringBuilder.append(textPage.textLines[lineIndex].text)
|
||||
fun getSelectedText(): String {
|
||||
val pos = Pos(0, 0, 0)
|
||||
val builder = StringBuilder()
|
||||
for (relativePos in selectStart.relativePos..selectEnd.relativePos) {
|
||||
val textPage = relativePage(relativePos)
|
||||
pos.relativePos = relativePos
|
||||
textPage.textLines.forEachIndexed { lineIndex, textLine ->
|
||||
pos.lineIndex = lineIndex
|
||||
textLine.textChars.forEachIndexed { charIndex, textChar ->
|
||||
pos.charIndex = charIndex
|
||||
if (pos.compare(selectStart) >= 0
|
||||
&& pos.compare(selectEnd) <= 0
|
||||
) {
|
||||
builder.append(textChar.charData)
|
||||
if (charIndex == textLine.charSize - 1
|
||||
&& textLine.text.endsWith("\n")
|
||||
) {
|
||||
builder.append("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stringBuilder.toString()
|
||||
}
|
||||
if (builder.endsWith("\n")) {
|
||||
return builder.substring(0, builder.lastIndex)
|
||||
}
|
||||
return builder.toString()
|
||||
}
|
||||
|
||||
fun createBookmark(): Bookmark? {
|
||||
val page = relativePage(selectStart[0])
|
||||
val page = relativePage(selectStart.relativePos)
|
||||
page.getTextChapter()?.let { chapter ->
|
||||
ReadBook.book?.let { book ->
|
||||
return book.createBookMark().apply {
|
||||
chapterIndex = page.chapterIndex
|
||||
chapterPos = chapter.getReadLength(page.index) +
|
||||
page.getSelectStartLength(selectStart[1], selectStart[2])
|
||||
page.getSelectStartLength(selectStart.lineIndex, selectStart.charIndex)
|
||||
chapterName = chapter.title
|
||||
bookText = selectedText
|
||||
bookText = getSelectedText()
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun selectToInt(page: Int, line: Int, char: Int): Int {
|
||||
return page * 10000000 + line * 100000 + char
|
||||
}
|
||||
|
||||
private fun selectToInt(select: Array<Int>): Int {
|
||||
return select[0] * 10000000 + select[1] * 100000 + select[2]
|
||||
}
|
||||
|
||||
private fun relativeOffset(relativePos: Int): Float {
|
||||
return when (relativePos) {
|
||||
0 -> pageOffset.toFloat()
|
||||
@@ -527,6 +441,35 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
}
|
||||
}
|
||||
|
||||
private data class Pos(
|
||||
var relativePos: Int,
|
||||
var lineIndex: Int,
|
||||
var charIndex: Int
|
||||
) {
|
||||
|
||||
fun upData(relativePos: Int, lineIndex: Int, charIndex: Int) {
|
||||
this.relativePos = relativePos
|
||||
this.lineIndex = lineIndex
|
||||
this.charIndex = charIndex
|
||||
}
|
||||
|
||||
fun upData(pos: Pos) {
|
||||
relativePos = pos.relativePos
|
||||
lineIndex = pos.lineIndex
|
||||
charIndex = pos.charIndex
|
||||
}
|
||||
|
||||
fun compare(pos: Pos): Int {
|
||||
if (relativePos < pos.relativePos) return -1
|
||||
if (relativePos > pos.relativePos) return 1
|
||||
if (lineIndex < pos.lineIndex) return -1
|
||||
if (lineIndex > pos.lineIndex) return 1
|
||||
if (charIndex < pos.charIndex) return -1
|
||||
if (charIndex > pos.charIndex) return 1
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
interface CallBack {
|
||||
fun upSelectedStart(x: Float, y: Float, top: Float)
|
||||
fun upSelectedEnd(x: Float, y: Float)
|
||||
|
||||
@@ -295,7 +295,7 @@ class PageView(context: Context) : FrameLayout(context) {
|
||||
return binding.contentTextView.relativePage(relativePos)
|
||||
}
|
||||
|
||||
val selectedText: String get() = binding.contentTextView.selectedText
|
||||
val selectedText: String get() = binding.contentTextView.getSelectedText()
|
||||
|
||||
val textPage get() = binding.contentTextView.textPage
|
||||
}
|
||||
@@ -276,7 +276,7 @@ class ReadView(context: Context, attrs: AttributeSet) :
|
||||
private fun onLongPress() {
|
||||
kotlin.runCatching {
|
||||
curPage.selectText(startX, startY) { relativePage, lineIndex, charIndex ->
|
||||
val page = if (isScroll) curPage.relativePage(relativePage) else curPage.textPage
|
||||
val page = curPage.relativePage(relativePage)
|
||||
with(page) {
|
||||
isTextSelected = true
|
||||
firstRelativePage = relativePage
|
||||
|
||||
@@ -4,7 +4,7 @@ import android.text.TextPaint
|
||||
import io.legado.app.ui.book.read.page.provider.ChapterProvider
|
||||
import io.legado.app.utils.textHeight
|
||||
|
||||
@Suppress("unused")
|
||||
@Suppress("unused", "MemberVisibilityCanBePrivate")
|
||||
data class TextLine(
|
||||
var text: String = "",
|
||||
val textChars: ArrayList<TextChar> = arrayListOf(),
|
||||
|
||||
Reference in New Issue
Block a user