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