From 6077e39013e1928f415f33c68ee5a2d5317c823e Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 15 Apr 2022 11:01:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/read/page/ContentTextView.kt | 207 +++++++----------- .../legado/app/ui/book/read/page/PageView.kt | 2 +- .../legado/app/ui/book/read/page/ReadView.kt | 2 +- .../ui/book/read/page/entities/TextLine.kt | 2 +- 4 files changed, 78 insertions(+), 135 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index 5fd7e37cd..bfeb3252d 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -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 { - 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) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt index f09bc7195..ee9937c9f 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt @@ -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 } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt index 7610d17ca..7d90054c9 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt @@ -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 diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt index bc05317b8..53eb60cec 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt @@ -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 = arrayListOf(),