优化
This commit is contained in:
@@ -317,16 +317,16 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
|||||||
/**
|
/**
|
||||||
* 选择开始文字
|
* 选择开始文字
|
||||||
*/
|
*/
|
||||||
fun selectStartMoveIndex(relativePage: Int, lineIndex: Int, charIndex: Int) {
|
fun selectStartMoveIndex(relativePagePos: Int, lineIndex: Int, charIndex: Int) {
|
||||||
selectStart.relativePos = relativePage
|
selectStart.relativePagePos = relativePagePos
|
||||||
selectStart.lineIndex = lineIndex
|
selectStart.lineIndex = lineIndex
|
||||||
selectStart.charIndex = charIndex
|
selectStart.charIndex = charIndex
|
||||||
val textLine = relativePage(relativePage).getLine(lineIndex)
|
val textLine = relativePage(relativePagePos).getLine(lineIndex)
|
||||||
val textChar = textLine.getTextChar(charIndex)
|
val textChar = textLine.getTextChar(charIndex)
|
||||||
upSelectedStart(
|
upSelectedStart(
|
||||||
textChar.start,
|
textChar.start,
|
||||||
textLine.lineBottom + relativeOffset(relativePage),
|
textLine.lineBottom + relativeOffset(relativePagePos),
|
||||||
textLine.lineTop + relativeOffset(relativePage)
|
textLine.lineTop + relativeOffset(relativePagePos)
|
||||||
)
|
)
|
||||||
upSelectChars()
|
upSelectChars()
|
||||||
}
|
}
|
||||||
@@ -335,7 +335,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
|||||||
* 选择结束文字
|
* 选择结束文字
|
||||||
*/
|
*/
|
||||||
fun selectEndMoveIndex(relativePage: Int, lineIndex: Int, charIndex: Int) {
|
fun selectEndMoveIndex(relativePage: Int, lineIndex: Int, charIndex: Int) {
|
||||||
selectEnd.relativePos = relativePage
|
selectEnd.relativePagePos = relativePage
|
||||||
selectEnd.lineIndex = lineIndex
|
selectEnd.lineIndex = lineIndex
|
||||||
selectEnd.charIndex = charIndex
|
selectEnd.charIndex = charIndex
|
||||||
val textLine = relativePage(relativePage).getLine(lineIndex)
|
val textLine = relativePage(relativePage).getLine(lineIndex)
|
||||||
@@ -348,7 +348,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
|||||||
val last = if (callBack.isScroll) 2 else 0
|
val last = if (callBack.isScroll) 2 else 0
|
||||||
val textPos = TextPos(0, 0, 0)
|
val textPos = TextPos(0, 0, 0)
|
||||||
for (relativePos in 0..last) {
|
for (relativePos in 0..last) {
|
||||||
textPos.relativePos = relativePos
|
textPos.relativePagePos = relativePos
|
||||||
for ((lineIndex, textLine) in relativePage(relativePos).textLines.withIndex()) {
|
for ((lineIndex, textLine) in relativePage(relativePos).textLines.withIndex()) {
|
||||||
textPos.lineIndex = lineIndex
|
textPos.lineIndex = lineIndex
|
||||||
for ((charIndex, textChar) in textLine.textChars.withIndex()) {
|
for ((charIndex, textChar) in textLine.textChars.withIndex()) {
|
||||||
@@ -386,9 +386,9 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
|||||||
fun getSelectedText(): String {
|
fun getSelectedText(): String {
|
||||||
val textPos = TextPos(0, 0, 0)
|
val textPos = TextPos(0, 0, 0)
|
||||||
val builder = StringBuilder()
|
val builder = StringBuilder()
|
||||||
for (relativePos in selectStart.relativePos..selectEnd.relativePos) {
|
for (relativePos in selectStart.relativePagePos..selectEnd.relativePagePos) {
|
||||||
val textPage = relativePage(relativePos)
|
val textPage = relativePage(relativePos)
|
||||||
textPos.relativePos = relativePos
|
textPos.relativePagePos = relativePos
|
||||||
textPage.textLines.forEachIndexed { lineIndex, textLine ->
|
textPage.textLines.forEachIndexed { lineIndex, textLine ->
|
||||||
textPos.lineIndex = lineIndex
|
textPos.lineIndex = lineIndex
|
||||||
textLine.textChars.forEachIndexed { charIndex, textChar ->
|
textLine.textChars.forEachIndexed { charIndex, textChar ->
|
||||||
@@ -412,7 +412,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun createBookmark(): Bookmark? {
|
fun createBookmark(): Bookmark? {
|
||||||
val page = relativePage(selectStart.relativePos)
|
val page = relativePage(selectStart.relativePagePos)
|
||||||
page.getTextChapter()?.let { chapter ->
|
page.getTextChapter()?.let { chapter ->
|
||||||
ReadBook.book?.let { book ->
|
ReadBook.book?.let { book ->
|
||||||
return book.createBookMark().apply {
|
return book.createBookMark().apply {
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ class PageView(context: Context) : FrameLayout(context) {
|
|||||||
|
|
||||||
fun selectText(
|
fun selectText(
|
||||||
x: Float, y: Float,
|
x: Float, y: Float,
|
||||||
select: (relativePage: Int, lineIndex: Int, charIndex: Int) -> Unit,
|
select: (relativePagePos: Int, lineIndex: Int, charIndex: Int) -> Unit,
|
||||||
) {
|
) {
|
||||||
return binding.contentTextView.selectText(x, y - headerHeight, select)
|
return binding.contentTextView.selectText(x, y - headerHeight, select)
|
||||||
}
|
}
|
||||||
@@ -271,16 +271,16 @@ class PageView(context: Context) : FrameLayout(context) {
|
|||||||
binding.contentTextView.selectStartMove(x, y - headerHeight)
|
binding.contentTextView.selectStartMove(x, y - headerHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun selectStartMoveIndex(relativePage: Int, lineIndex: Int, charIndex: Int) {
|
fun selectStartMoveIndex(relativePagePos: Int, lineIndex: Int, charIndex: Int) {
|
||||||
binding.contentTextView.selectStartMoveIndex(relativePage, lineIndex, charIndex)
|
binding.contentTextView.selectStartMoveIndex(relativePagePos, lineIndex, charIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun selectEndMove(x: Float, y: Float) {
|
fun selectEndMove(x: Float, y: Float) {
|
||||||
binding.contentTextView.selectEndMove(x, y - headerHeight)
|
binding.contentTextView.selectEndMove(x, y - headerHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun selectEndMoveIndex(relativePage: Int, lineIndex: Int, charIndex: Int) {
|
fun selectEndMoveIndex(relativePagePos: Int, lineIndex: Int, charIndex: Int) {
|
||||||
binding.contentTextView.selectEndMoveIndex(relativePage, lineIndex, charIndex)
|
binding.contentTextView.selectEndMoveIndex(relativePagePos, lineIndex, charIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun cancelSelect() {
|
fun cancelSelect() {
|
||||||
@@ -291,8 +291,8 @@ class PageView(context: Context) : FrameLayout(context) {
|
|||||||
return binding.contentTextView.createBookmark()
|
return binding.contentTextView.createBookmark()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun relativePage(relativePos: Int): TextPage {
|
fun relativePage(relativePagePos: Int): TextPage {
|
||||||
return binding.contentTextView.relativePage(relativePos)
|
return binding.contentTextView.relativePage(relativePagePos)
|
||||||
}
|
}
|
||||||
|
|
||||||
val selectedText: String get() = binding.contentTextView.getSelectedText()
|
val selectedText: String get() = binding.contentTextView.getSelectedText()
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import io.legado.app.ui.book.read.page.api.DataSource
|
|||||||
import io.legado.app.ui.book.read.page.delegate.*
|
import io.legado.app.ui.book.read.page.delegate.*
|
||||||
import io.legado.app.ui.book.read.page.entities.PageDirection
|
import io.legado.app.ui.book.read.page.entities.PageDirection
|
||||||
import io.legado.app.ui.book.read.page.entities.TextChapter
|
import io.legado.app.ui.book.read.page.entities.TextChapter
|
||||||
|
import io.legado.app.ui.book.read.page.entities.TextPos
|
||||||
import io.legado.app.ui.book.read.page.provider.ChapterProvider
|
import io.legado.app.ui.book.read.page.provider.ChapterProvider
|
||||||
import io.legado.app.ui.book.read.page.provider.TextPageFactory
|
import io.legado.app.ui.book.read.page.provider.TextPageFactory
|
||||||
import io.legado.app.utils.activity
|
import io.legado.app.utils.activity
|
||||||
@@ -76,9 +77,7 @@ class ReadView(context: Context, attrs: AttributeSet) :
|
|||||||
}
|
}
|
||||||
var isTextSelected = false
|
var isTextSelected = false
|
||||||
private var pressOnTextSelected = false
|
private var pressOnTextSelected = false
|
||||||
private var firstRelativePage = 0
|
private val initialTextPos = TextPos(0, 0, 0)
|
||||||
private var firstLineIndex: Int = 0
|
|
||||||
private var firstCharIndex: Int = 0
|
|
||||||
|
|
||||||
val slopSquare by lazy { ViewConfiguration.get(context).scaledTouchSlop }
|
val slopSquare by lazy { ViewConfiguration.get(context).scaledTouchSlop }
|
||||||
private val tlRect = RectF()
|
private val tlRect = RectF()
|
||||||
@@ -275,106 +274,73 @@ class ReadView(context: Context, attrs: AttributeSet) :
|
|||||||
*/
|
*/
|
||||||
private fun onLongPress() {
|
private fun onLongPress() {
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
curPage.selectText(startX, startY) { relativePage, lineIndex, charIndex ->
|
curPage.selectText(startX, startY) { relativePos, lineIndex, charIndex ->
|
||||||
isTextSelected = true
|
isTextSelected = true
|
||||||
firstRelativePage = relativePage
|
initialTextPos.upData(relativePos, lineIndex, charIndex)
|
||||||
firstLineIndex = lineIndex
|
val startPos = TextPos(relativePos, lineIndex, charIndex)
|
||||||
firstCharIndex = charIndex
|
val endPos = TextPos(relativePos, lineIndex, charIndex)
|
||||||
val page = curPage.relativePage(relativePage)
|
val page = curPage.relativePage(relativePos)
|
||||||
with(page) {
|
val stringBuilder = StringBuilder()
|
||||||
var lineStart = lineIndex
|
var cIndex = charIndex
|
||||||
var lineEnd = lineIndex
|
var lineStart = lineIndex
|
||||||
var start: Int
|
var lineEnd = lineIndex
|
||||||
var end: Int
|
for (index in lineIndex - 1 downTo 0) {
|
||||||
if (lineIndex - 1 > 0 && lineIndex + 1 < lineSize) {
|
val textLine = page.getLine(index)
|
||||||
// 中间行
|
if (textLine.isLastLine) {
|
||||||
val lineText = with(textLines) {
|
break
|
||||||
get(lineIndex - 1).text + get(lineIndex).text + get(lineIndex + 1).text
|
|
||||||
}
|
|
||||||
boundary.setText(lineText)
|
|
||||||
start = boundary.first()
|
|
||||||
end = boundary.next()
|
|
||||||
val cIndex = textLines[lineIndex - 1].text.length + charIndex
|
|
||||||
while (end != BreakIterator.DONE) {
|
|
||||||
if (cIndex in start until end) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
start = end
|
|
||||||
end = boundary.next()
|
|
||||||
}
|
|
||||||
if (start < textLines[lineIndex - 1].text.length) {
|
|
||||||
lineStart = lineIndex - 1
|
|
||||||
} else {
|
|
||||||
start -= textLines[lineIndex - 1].text.length
|
|
||||||
}
|
|
||||||
if (end > textLines[lineIndex - 1].text.length + textLines[lineIndex].text.length) {
|
|
||||||
lineEnd = lineIndex + 1
|
|
||||||
end = (end - textLines[lineIndex - 1].text.length
|
|
||||||
- textLines[lineIndex].text.length)
|
|
||||||
} else {
|
|
||||||
end = end - textLines[lineIndex - 1].text.length - 1
|
|
||||||
}
|
|
||||||
} else if (lineIndex - 1 > 0) {
|
|
||||||
// 尾行
|
|
||||||
val lineText = with(textLines) {
|
|
||||||
get(lineIndex - 1).text + get(lineIndex).text
|
|
||||||
}
|
|
||||||
boundary.setText(lineText)
|
|
||||||
start = boundary.first()
|
|
||||||
end = boundary.next()
|
|
||||||
val cIndex = textLines[lineIndex - 1].text.length + charIndex
|
|
||||||
while (end != BreakIterator.DONE) {
|
|
||||||
if (cIndex in start until end) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
start = end
|
|
||||||
end = boundary.next()
|
|
||||||
}
|
|
||||||
if (start < textLines[lineIndex - 1].text.length) {
|
|
||||||
lineStart = lineIndex - 1
|
|
||||||
} else {
|
|
||||||
start -= textLines[lineIndex - 1].text.length
|
|
||||||
}
|
|
||||||
end = end - textLines[lineIndex - 1].text.length - 1
|
|
||||||
} else if (lineIndex + 1 < lineSize) {
|
|
||||||
// 首行
|
|
||||||
val lineText = with(textLines) {
|
|
||||||
get(lineIndex).text + get(lineIndex + 1).text
|
|
||||||
}
|
|
||||||
boundary.setText(lineText)
|
|
||||||
start = boundary.first()
|
|
||||||
end = boundary.next()
|
|
||||||
while (end != BreakIterator.DONE) {
|
|
||||||
if (charIndex in start until end) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
start = end
|
|
||||||
end = boundary.next()
|
|
||||||
}
|
|
||||||
if (end > textLines[lineIndex].text.length) {
|
|
||||||
lineEnd = lineIndex + 1
|
|
||||||
end -= textLines[lineIndex].text.length
|
|
||||||
} else {
|
|
||||||
end -= 1
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 单行
|
stringBuilder.insert(0, textLine.text)
|
||||||
val lineText = textLines[lineIndex].text
|
lineStart -= 1
|
||||||
boundary.setText(lineText)
|
cIndex += textLine.charSize
|
||||||
start = boundary.first()
|
|
||||||
end = boundary.next()
|
|
||||||
while (end != BreakIterator.DONE) {
|
|
||||||
if (charIndex in start until end) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
start = end
|
|
||||||
end = boundary.next()
|
|
||||||
}
|
|
||||||
end -= 1
|
|
||||||
}
|
}
|
||||||
curPage.selectStartMoveIndex(firstRelativePage, lineStart, start)
|
|
||||||
curPage.selectEndMoveIndex(firstRelativePage, lineEnd, end)
|
|
||||||
}
|
}
|
||||||
|
for (index in lineIndex until page.lineSize) {
|
||||||
|
val textLine = page.getLine(index)
|
||||||
|
stringBuilder.append(textLine.text)
|
||||||
|
lineEnd += 1
|
||||||
|
if (textLine.isLastLine) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var start: Int
|
||||||
|
var end: Int
|
||||||
|
boundary.setText(stringBuilder.toString())
|
||||||
|
start = boundary.first()
|
||||||
|
end = boundary.next()
|
||||||
|
while (end != BreakIterator.DONE) {
|
||||||
|
if (cIndex in start until end) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
start = end
|
||||||
|
end = boundary.next()
|
||||||
|
}
|
||||||
|
kotlin.run {
|
||||||
|
var ci = 0
|
||||||
|
for (index in lineStart..lineEnd) {
|
||||||
|
val textLine = page.getLine(index)
|
||||||
|
for (j in 0 until textLine.charSize) {
|
||||||
|
if (ci == start) {
|
||||||
|
startPos.lineIndex = index
|
||||||
|
startPos.charIndex = j
|
||||||
|
} else if (ci == end) {
|
||||||
|
endPos.lineIndex = index
|
||||||
|
endPos.charIndex = j - 1
|
||||||
|
return@run
|
||||||
|
}
|
||||||
|
ci++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curPage.selectStartMoveIndex(
|
||||||
|
startPos.relativePagePos,
|
||||||
|
startPos.lineIndex,
|
||||||
|
startPos.charIndex
|
||||||
|
)
|
||||||
|
curPage.selectEndMoveIndex(
|
||||||
|
endPos.relativePagePos,
|
||||||
|
endPos.lineIndex,
|
||||||
|
endPos.charIndex
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -431,31 +397,24 @@ class ReadView(context: Context, attrs: AttributeSet) :
|
|||||||
* 选择文本
|
* 选择文本
|
||||||
*/
|
*/
|
||||||
private fun selectText(x: Float, y: Float) {
|
private fun selectText(x: Float, y: Float) {
|
||||||
curPage.selectText(x, y) { relativePage, lineIndex, charIndex ->
|
curPage.selectText(x, y) { relativePagePos, lineIndex, charIndex ->
|
||||||
|
val compare = initialTextPos.compare(relativePagePos, lineIndex, charIndex)
|
||||||
when {
|
when {
|
||||||
relativePage > firstRelativePage -> {
|
compare >= 0 -> {
|
||||||
curPage.selectStartMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
|
curPage.selectStartMoveIndex(relativePagePos, lineIndex, charIndex)
|
||||||
curPage.selectEndMoveIndex(relativePage, lineIndex, charIndex)
|
curPage.selectEndMoveIndex(
|
||||||
}
|
initialTextPos.relativePagePos,
|
||||||
relativePage < firstRelativePage -> {
|
initialTextPos.lineIndex,
|
||||||
curPage.selectEndMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
|
initialTextPos.charIndex
|
||||||
curPage.selectStartMoveIndex(relativePage, lineIndex, charIndex)
|
)
|
||||||
}
|
|
||||||
lineIndex > firstLineIndex -> {
|
|
||||||
curPage.selectStartMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
|
|
||||||
curPage.selectEndMoveIndex(relativePage, lineIndex, charIndex)
|
|
||||||
}
|
|
||||||
lineIndex < firstLineIndex -> {
|
|
||||||
curPage.selectEndMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
|
|
||||||
curPage.selectStartMoveIndex(relativePage, lineIndex, charIndex)
|
|
||||||
}
|
|
||||||
charIndex > firstCharIndex -> {
|
|
||||||
curPage.selectStartMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
|
|
||||||
curPage.selectEndMoveIndex(relativePage, lineIndex, charIndex)
|
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
curPage.selectEndMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
|
curPage.selectStartMoveIndex(
|
||||||
curPage.selectStartMoveIndex(relativePage, lineIndex, charIndex)
|
initialTextPos.relativePagePos,
|
||||||
|
initialTextPos.lineIndex,
|
||||||
|
initialTextPos.charIndex
|
||||||
|
)
|
||||||
|
curPage.selectEndMoveIndex(relativePagePos, lineIndex, charIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,27 @@
|
|||||||
package io.legado.app.ui.book.read.page.entities
|
package io.legado.app.ui.book.read.page.entities
|
||||||
|
|
||||||
data class TextPos(
|
data class TextPos(
|
||||||
var relativePos: Int,
|
var relativePagePos: Int,
|
||||||
var lineIndex: Int,
|
var lineIndex: Int,
|
||||||
var charIndex: Int
|
var charIndex: Int
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
fun upData(relativePos: Int, lineIndex: Int, charIndex: Int) {
|
||||||
|
this.relativePagePos = relativePos
|
||||||
|
this.lineIndex = lineIndex
|
||||||
|
this.charIndex = charIndex
|
||||||
|
}
|
||||||
|
|
||||||
fun upData(pos: TextPos) {
|
fun upData(pos: TextPos) {
|
||||||
relativePos = pos.relativePos
|
relativePagePos = pos.relativePagePos
|
||||||
lineIndex = pos.lineIndex
|
lineIndex = pos.lineIndex
|
||||||
charIndex = pos.charIndex
|
charIndex = pos.charIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
fun compare(pos: TextPos): Int {
|
fun compare(pos: TextPos): Int {
|
||||||
return when {
|
return when {
|
||||||
relativePos < pos.relativePos -> -3
|
relativePagePos < pos.relativePagePos -> -3
|
||||||
relativePos > pos.relativePos -> 3
|
relativePagePos > pos.relativePagePos -> 3
|
||||||
lineIndex < pos.lineIndex -> -2
|
lineIndex < pos.lineIndex -> -2
|
||||||
lineIndex > pos.lineIndex -> 2
|
lineIndex > pos.lineIndex -> 2
|
||||||
charIndex < pos.charIndex -> -1
|
charIndex < pos.charIndex -> -1
|
||||||
@@ -23,4 +29,16 @@ data class TextPos(
|
|||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun compare(relativePos: Int, lineIndex: Int, charIndex: Int): Int {
|
||||||
|
return when {
|
||||||
|
this.relativePagePos < relativePos -> -3
|
||||||
|
this.relativePagePos > relativePos -> 3
|
||||||
|
this.lineIndex < lineIndex -> -2
|
||||||
|
this.lineIndex > lineIndex -> 2
|
||||||
|
this.charIndex < charIndex -> -1
|
||||||
|
this.charIndex > charIndex -> 1
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user