@ -3,15 +3,14 @@ package io.legado.app.ui.book.read.page
import android.content.Context
import android.content.Context
import android.graphics.Canvas
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Paint
import android.text.Layout
import android.graphics.RectF
import android.text.StaticLayout
import android.util.AttributeSet
import android.util.AttributeSet
import android.view.View
import android.view.View
import io.legado.app.R
import io.legado.app.R
import io.legado.app.constant.PreferKey
import io.legado.app.constant.PreferKey
import io.legado.app.help.ReadBookConfig
import io.legado.app.help.ReadBookConfig
import io.legado.app.lib.theme.accentColor
import io.legado.app.lib.theme.accentColor
import io.legado.app.service.help.ReadBook
import io.legado.app.ui.book.read.page.entities.TextChar
import io.legado.app.ui.book.read.page.entities.TextPage
import io.legado.app.ui.book.read.page.entities.TextPage
import io.legado.app.utils.activity
import io.legado.app.utils.activity
import io.legado.app.utils.getCompatColor
import io.legado.app.utils.getCompatColor
@ -19,26 +18,26 @@ import io.legado.app.utils.getPrefBoolean
class ContentTextView ( context : Context , attrs : AttributeSet ? ) : View ( context , attrs ) {
class ContentTextView ( context : Context , attrs : AttributeSet ? ) : View ( context , attrs ) {
var selectAble = context . getPrefBoolean ( PreferKey . textSelectAble )
var upView : ( ( TextPage ) -> Unit ) ? = null
private val selectedPaint by lazy {
private val selectedPaint by lazy {
Paint ( ) . apply {
Paint ( ) . apply {
color = context . getCompatColor ( R . color . btn _bg _press _2 )
color = context . getCompatColor ( R . color . btn _bg _press _2 )
style = Paint . Style . FILL
style = Paint . Style . FILL
}
}
}
}
private var activityCallBack : CallBack
private var callBack : CallBack
var selectAble = context . getPrefBoolean ( PreferKey . textSelectAble )
private val visibleRect = RectF ( )
private var selectLineStart = 0
private val selectStart = arrayOf ( 0 , 0 , 0 )
private var selectCharStart = 0
private val selectEnd = arrayOf ( 0 , 0 , 0 )
private var selectLineEnd = 0
private var selectCharEnd = 0
private var textPage : TextPage = TextPage ( )
private var textPage : TextPage = TextPage ( )
//滚动参数
//滚动参数
private val pageFactory : TextPageFactory get ( ) = callBack . pageFactory
private val maxScrollOffset = 100f
private val maxScrollOffset = 100f
private var pageOffset = 0f
private var pageOffset = 0f
private var isLastPage = false
init {
init {
a ctivityC allBack = activity as CallBack
callBack = activity as CallBack
contentDescription = textPage . text
contentDescription = textPage . text
}
}
@ -48,72 +47,114 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
invalidate ( )
invalidate ( )
}
}
fun upVisibleRect ( ) {
visibleRect . set (
ChapterProvider . paddingLeft . toFloat ( ) ,
ChapterProvider . paddingTop . toFloat ( ) ,
ChapterProvider . visibleRight . toFloat ( ) ,
ChapterProvider . visibleBottom . toFloat ( )
)
}
override fun onSizeChanged ( w : Int , h : Int , oldw : Int , oldh : Int ) {
override fun onSizeChanged ( w : Int , h : Int , oldw : Int , oldh : Int ) {
super . onSizeChanged ( w , h , oldw , oldh )
super . onSizeChanged ( w , h , oldw , oldh )
ReadBookConfig . durConfig . let {
ChapterProvider . viewWidth = w
ChapterProvider . viewWidth = w
ChapterProvider . viewHeight = h
ChapterProvider . viewHeight = h
ChapterProvider . upSize ( ReadBookConfig . durConfig )
ChapterProvider . upSize ( )
}
upVisibleRect ( )
textPage . format ( )
}
}
override fun onDraw ( canvas : Canvas ) {
override fun onDraw ( canvas : Canvas ) {
super . onDraw ( canvas )
super . onDraw ( canvas )
if ( textPage . textLines . isEmpty ( ) ) {
canvas . clipRect ( visibleRect )
drawMsg ( canvas , textPage . text )
drawPage ( canvas )
} else {
drawHorizontalPage ( canvas )
}
}
}
@Suppress ( " DEPRECATION " )
/ * *
private fun drawMsg ( canvas : Canvas , msg : String ) {
* 绘制页面
val layout = StaticLayout (
* /
msg , ChapterProvider . contentPaint , width ,
private fun drawPage ( canvas : Canvas ) {
Layout . Alignment . ALIGN _NORMAL , 1f , 0f , false
var relativeOffset = relativeOffset ( 0 )
textPage . textLines . forEach { textLine ->
val lineTop = textLine . lineTop + relativeOffset
val lineBase = textLine . lineBase + relativeOffset
val lineBottom = textLine . lineBottom + relativeOffset
drawChars (
canvas ,
textLine . textChars ,
lineTop ,
lineBase ,
lineBottom ,
textLine . isTitle ,
textLine . isReadAloud
)
)
val y = ( height - layout . height ) / 2f
for ( lineIndex in 0 until layout . lineCount ) {
val x = ( width - layout . getLineMax ( lineIndex ) ) / 2
val words =
msg . substring ( layout . getLineStart ( lineIndex ) , layout . getLineEnd ( lineIndex ) )
canvas . drawText ( words , x , y , ChapterProvider . contentPaint )
}
}
if ( ! ReadBookConfig . isScroll ) return
//滚动翻页
val nextPage = relativePage ( 1 )
relativeOffset = relativeOffset ( 1 )
nextPage . textLines . forEach { textLine ->
val lineTop = textLine . lineTop + relativeOffset
val lineBase = textLine . lineBase + relativeOffset
val lineBottom = textLine . lineBottom + relativeOffset
drawChars (
canvas ,
textLine . textChars ,
lineTop ,
lineBase ,
lineBottom ,
textLine . isTitle ,
textLine . isReadAloud
)
}
}
relativeOffset = relativeOffset ( 2 )
private fun drawHorizontalPage ( canvas : Canvas ) {
if ( relativeOffset < ChapterProvider . visibleHeight ) {
textPage . textLines . forEach { textLine ->
relativePage ( 2 ) . textLines . forEach { textLine ->
val textPaint = if ( textLine . isTitle ) {
val lineTop = textLine . lineTop + relativeOffset
ChapterProvider . titlePaint
val lineBase = textLine . lineBase + relativeOffset
} else {
val lineBottom = textLine . lineBottom + relativeOffset
ChapterProvider . contentPaint
drawChars (
canvas ,
textLine . textChars ,
lineTop ,
lineBase ,
lineBottom ,
textLine . isTitle ,
textLine . isReadAloud
)
}
}
textPaint . color = if ( textLine . isReadAloud ) {
context . accentColor
} else {
ReadBookConfig . durConfig . textColor ( )
}
}
textLine . textChars . forEach {
canvas . drawText (
it . charData ,
it . leftBottomPosition . x ,
it . leftBottomPosition . y ,
textPaint
)
if ( it . selected ) {
canvas . drawRect (
it . leftBottomPosition . x ,
it . rightTopPosition . y ,
it . rightTopPosition . x ,
it . leftBottomPosition . y ,
selectedPaint
)
}
}
/ * *
* 绘制文字
* /
private fun drawChars (
canvas : Canvas ,
textChars : List < TextChar > ,
lineTop : Float ,
lineBase : Float ,
lineBottom : Float ,
isTitle : Boolean ,
isReadAloud : Boolean
) {
val textPaint = if ( isTitle ) ChapterProvider . titlePaint else ChapterProvider . contentPaint
textPaint . color =
if ( isReadAloud ) context . accentColor else ReadBookConfig . durConfig . textColor ( )
textChars . forEach {
canvas . drawText ( it . charData , it . start , lineBase , textPaint )
if ( it . selected ) {
canvas . drawRect ( it . start , lineTop , it . end , lineBottom , selectedPaint )
}
}
}
}
}
}
/ * *
* 滚动事件
* /
fun onScroll ( mOffset : Float ) {
fun onScroll ( mOffset : Float ) {
if ( mOffset == 0f ) return
var offset = mOffset
var offset = mOffset
if ( offset > maxScrollOffset ) {
if ( offset > maxScrollOffset ) {
offset = maxScrollOffset
offset = maxScrollOffset
@ -121,102 +162,315 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
offset = - maxScrollOffset
offset = - maxScrollOffset
}
}
if ( !is LastPage || offset < 0 ) {
pageOffset += offset
pageOffset += offset
isLastPage = false
if ( pageOffset > 0 ) {
}
if ( ! pageFactory . hasPrev ( ) ) {
// 首页
if ( pageOffset < 0 && ReadBook . durChapterIndex == 0 && ReadBook . durPageIndex == 0 ) {
pageOffset = 0f
pageOffset = 0f
} else {
pageFactory . moveToPrev ( )
textPage = pageFactory . currentPage
pageOffset -= textPage . height
upView ?. invoke ( textPage )
}
} else if ( pageOffset < - textPage . height ) {
if ( ! pageFactory . hasNext ( ) ) {
pageOffset = - textPage . height . toFloat ( )
} else {
pageOffset += textPage . height
pageFactory . moveToNext ( )
textPage = pageFactory . currentPage
upView ?. invoke ( textPage )
}
}
invalidate ( )
}
}
fun resetPageOffset ( ) {
pageOffset = 0f
}
}
fun selectText ( x : Float , y : Float ) : Boolean {
/ * *
* 选择初始文字
* /
fun selectText (
x : Float ,
y : Float ,
select : ( relativePage : Int , lineIndex : Int , charIndex : Int ) -> Unit
) {
if ( ! selectAble ) return
if ( ! visibleRect . contains ( x , y ) ) return
var relativeOffset = relativeOffset ( 0 )
for ( ( lineIndex , textLine ) in textPage . textLines . withIndex ( ) ) {
for ( ( lineIndex , textLine ) in textPage . textLines . withIndex ( ) ) {
if ( y > textLine . lineTop && y < textLine . lineBottom ) {
if ( y > textLine . lineTop + relativeOffset && y < textLine . lineBottom + relativeOffset ) {
for ( ( charIndex , textChar ) in textLine . textChars . withIndex ( ) ) {
for ( ( charIndex , textChar ) in textLine . textChars . withIndex ( ) ) {
if ( x > textChar . leftBottomPosition . x && x < textChar . rightTopPosition . x ) {
if ( x > textChar . start && x < textChar . end ) {
textChar . selected = true
textChar . selected = true
invalidate ( )
invalidate ( )
selectLineStart = lineIndex
selectStart [ 0 ] = 0
selectCharStart = charIndex
selectStart [ 1 ] = lineIndex
selectLineEnd = lineIndex
selectStart [ 2 ] = charIndex
selectCharEnd = charIndex
selectEnd [ 0 ] = 0
upSelectedStart (
selectEnd [ 1 ] = lineIndex
textChar . leftBottomPosition . x ,
selectEnd [ 2 ] = charIndex
textChar . leftBottomPosition . y
upSelectedStart ( textChar . start , textLine . lineBottom + relativeOffset )
)
upSelectedEnd ( textChar . end , textLine . lineBottom + relativeOffset )
upSelectedEnd (
select ( 0 , lineIndex , charIndex )
textChar . rightTopPosition . x ,
return
textChar . leftBottomPosition . y
}
)
}
return true
return
}
}
if ( ! ReadBookConfig . isScroll ) return
//滚动翻页
relativeOffset = relativeOffset ( 1 )
if ( relativeOffset >= ChapterProvider . visibleHeight ) return
val nextPage = relativePage ( 1 )
for ( ( lineIndex , textLine ) in nextPage . textLines . withIndex ( ) ) {
if ( y > textLine . lineTop + relativeOffset && y < textLine . lineBottom + relativeOffset ) {
for ( ( charIndex , textChar ) in textLine . textChars . withIndex ( ) ) {
if ( x > textChar . start && x < textChar . end ) {
textChar . selected = true
invalidate ( )
selectStart [ 0 ] = 1
selectStart [ 1 ] = lineIndex
selectStart [ 2 ] = charIndex
selectEnd [ 0 ] = 1
selectEnd [ 1 ] = lineIndex
selectEnd [ 2 ] = charIndex
upSelectedStart ( textChar . start , textLine . lineBottom + relativeOffset )
upSelectedEnd ( textChar . end , textLine . lineBottom + relativeOffset )
select ( 1 , lineIndex , charIndex )
return
}
}
}
return
}
}
break
}
relativeOffset = relativeOffset ( 2 )
if ( relativeOffset >= ChapterProvider . visibleHeight ) return
for ( ( lineIndex , textLine ) in relativePage ( 2 ) . textLines . withIndex ( ) ) {
if ( y > textLine . lineTop + relativeOffset && y < textLine . lineBottom + relativeOffset ) {
for ( ( charIndex , textChar ) in textLine . textChars . withIndex ( ) ) {
if ( x > textChar . start && x < textChar . end ) {
textChar . selected = true
invalidate ( )
selectStart [ 0 ] = 2
selectStart [ 1 ] = lineIndex
selectStart [ 2 ] = charIndex
selectEnd [ 0 ] = 2
selectEnd [ 1 ] = lineIndex
selectEnd [ 2 ] = charIndex
upSelectedStart ( textChar . start , textLine . lineBottom + relativeOffset )
upSelectedEnd ( textChar . end , textLine . lineBottom + relativeOffset )
select ( 2 , lineIndex , charIndex )
return
}
}
return
}
}
}
}
return false
}
}
/ * *
* 开始选择符移动
* /
fun selectStartMove ( x : Float , y : Float ) {
fun selectStartMove ( x : Float , y : Float ) {
if ( ! visibleRect . contains ( x , y ) ) return
var relativeOffset = relativeOffset ( 0 )
for ( ( lineIndex , textLine ) in textPage . textLines . withIndex ( ) ) {
for ( ( lineIndex , textLine ) in textPage . textLines . withIndex ( ) ) {
if ( y > textLine . lineTop && y < textLine . lineBottom ) {
if ( y > textLine . lineTop + relativeOffset && y < textLine . lineBottom + relativeOffset ) {
for ( ( charIndex , textChar ) in textLine . textChars . withIndex ( ) ) {
for ( ( charIndex , textChar ) in textLine . textChars . withIndex ( ) ) {
if ( x > textChar . leftBottomPosition . x && x < textChar . rightTopPosition . x ) {
if ( x > textChar . start && x < textChar . end ) {
if ( selectLineStart != lineIndex || selectCharStart != charIndex ) {
if ( selectStart [ 0 ] != 0 || selectStart [ 1 ] != lineIndex || selectStart [ 2 ] != charIndex ) {
selectLineStart = lineIndex
if ( selectToInt ( 0 , lineIndex , charIndex ) > selectToInt ( selectEnd ) ) {
selectCharStart = charIndex
return
upSelectedStart (
textChar . leftBottomPosition . x ,
textChar . leftBottomPosition . y
)
upSelectChars ( textPage )
}
}
break
selectStart [ 0 ] = 0
selectStart [ 1 ] = lineIndex
selectStart [ 2 ] = charIndex
upSelectedStart ( textChar . start , textLine . lineBottom + relativeOffset )
upSelectChars ( )
}
return
}
}
return
}
}
if ( ! ReadBookConfig . isScroll ) return
//滚动翻页
relativeOffset = relativeOffset ( 1 )
if ( relativeOffset >= ChapterProvider . visibleHeight ) return
for ( ( lineIndex , textLine ) in relativePage ( 1 ) . textLines . withIndex ( ) ) {
if ( y > textLine . lineTop + relativeOffset && y < textLine . lineBottom + relativeOffset ) {
for ( ( charIndex , textChar ) in textLine . textChars . withIndex ( ) ) {
if ( x > textChar . start && x < textChar . end ) {
if ( selectStart [ 0 ] != 1 || selectStart [ 1 ] != lineIndex || selectStart [ 2 ] != charIndex ) {
if ( selectToInt ( 1 , lineIndex , charIndex ) > selectToInt ( selectEnd ) ) {
return
}
selectStart [ 0 ] = 1
selectStart [ 1 ] = lineIndex
selectStart [ 2 ] = charIndex
upSelectedStart ( textChar . start , textLine . lineBottom + relativeOffset )
upSelectChars ( )
}
return
}
}
return
}
}
relativeOffset = relativeOffset ( 2 )
if ( relativeOffset >= ChapterProvider . visibleHeight ) return
for ( ( lineIndex , textLine ) in relativePage ( 2 ) . textLines . withIndex ( ) ) {
if ( y > textLine . lineTop + relativeOffset && y < textLine . lineBottom + relativeOffset ) {
for ( ( charIndex , textChar ) in textLine . textChars . withIndex ( ) ) {
if ( x > textChar . start && x < textChar . end ) {
if ( selectStart [ 0 ] != 2 || selectStart [ 1 ] != lineIndex || selectStart [ 2 ] != charIndex ) {
if ( selectToInt ( 2 , lineIndex , charIndex ) > selectToInt ( selectEnd ) ) {
return
}
}
selectStart [ 0 ] = 2
selectStart [ 1 ] = lineIndex
selectStart [ 2 ] = charIndex
upSelectedStart ( textChar . start , textLine . lineBottom + relativeOffset )
upSelectChars ( )
}
}
break
return
}
}
return
}
}
}
}
}
}
/ * *
* 结束选择符移动
* /
fun selectEndMove ( x : Float , y : Float ) {
fun selectEndMove ( x : Float , y : Float ) {
if ( ! visibleRect . contains ( x , y ) ) return
var relativeOffset = relativeOffset ( 0 )
for ( ( lineIndex , textLine ) in textPage . textLines . withIndex ( ) ) {
for ( ( lineIndex , textLine ) in textPage . textLines . withIndex ( ) ) {
if ( y > textLine . lineTop && y < textLine . lineBottom ) {
if ( y > textLine . lineTop + relativeOffset && y < textLine . lineBottom + relativeOffset ) {
for ( ( charIndex , textChar ) in textLine . textChars . withIndex ( ) ) {
for ( ( charIndex , textChar ) in textLine . textChars . withIndex ( ) ) {
if ( x > textChar . leftBottomPosition . x && x < textChar . rightTopPosition . x ) {
if ( x > textChar . start && x < textChar . end ) {
if ( selectLineEnd != lineIndex || selectCharEnd != charIndex ) {
if ( selectEnd [ 0 ] != 0 || selectEnd [ 1 ] != lineIndex || selectEnd [ 2 ] != charIndex ) {
selectLineEnd = lineIndex
if ( selectToInt ( 0 , lineIndex , charIndex ) < selectToInt ( selectStart ) ) {
selectCharEnd = charIndex
return
upSelectedEnd (
}
textChar . rightTopPosition . x ,
selectEnd [ 0 ] = 0
textChar . leftBottomPosition . y
selectEnd [ 1 ] = lineIndex
)
selectEnd [ 2 ] = charIndex
upSelectChars ( textPage )
upSelectedEnd ( textChar . end , textLine . lineBottom + relativeOffset )
upSelectChars ( )
}
return
}
}
return
}
}
break
}
if ( ! ReadBookConfig . isScroll ) return
//滚动翻页
relativeOffset = relativeOffset ( 1 )
if ( relativeOffset >= ChapterProvider . visibleHeight ) return
for ( ( lineIndex , textLine ) in relativePage ( 1 ) . textLines . withIndex ( ) ) {
if ( y > textLine . lineTop + relativeOffset && y < textLine . lineBottom + relativeOffset ) {
for ( ( charIndex , textChar ) in textLine . textChars . withIndex ( ) ) {
if ( x > textChar . start && x < textChar . end ) {
if ( selectEnd [ 0 ] != 1 || selectEnd [ 1 ] != lineIndex || selectEnd [ 2 ] != charIndex ) {
if ( selectToInt ( 1 , lineIndex , charIndex ) < selectToInt ( selectStart ) ) {
return
}
selectEnd [ 0 ] = 1
selectEnd [ 1 ] = lineIndex
selectEnd [ 2 ] = charIndex
upSelectedEnd ( textChar . end , textLine . lineBottom + relativeOffset )
upSelectChars ( )
}
return
}
}
}
}
break
return
}
}
relativeOffset = relativeOffset ( 2 )
if ( relativeOffset >= ChapterProvider . visibleHeight ) return
for ( ( lineIndex , textLine ) in relativePage ( 2 ) . textLines . withIndex ( ) ) {
if ( y > textLine . lineTop + relativeOffset && y < textLine . lineBottom + relativeOffset ) {
for ( ( charIndex , textChar ) in textLine . textChars . withIndex ( ) ) {
if ( x > textChar . start && x < textChar . end ) {
if ( selectEnd [ 0 ] != 2 || selectEnd [ 1 ] != lineIndex || selectEnd [ 2 ] != charIndex ) {
if ( selectToInt ( 2 , lineIndex , charIndex ) < selectToInt ( selectStart ) ) {
return
}
selectEnd [ 0 ] = 2
selectEnd [ 1 ] = lineIndex
selectEnd [ 2 ] = charIndex
upSelectedEnd ( textChar . end , textLine . lineBottom + relativeOffset )
upSelectChars ( )
}
return
}
}
return
}
}
}
}
}
}
private fun upSelectChars ( textPage : TextPage ) {
/ * *
for ( ( lineIndex , textLine ) in textPage . textLines . withIndex ( ) ) {
* 选择开始文字
* /
fun selectStartMoveIndex ( relativePage : Int , lineIndex : Int , charIndex : Int ) {
selectStart [ 0 ] = relativePage
selectStart [ 1 ] = lineIndex
selectStart [ 2 ] = charIndex
val textLine = relativePage ( relativePage ) . textLines [ lineIndex ]
val textChar = textLine . textChars [ charIndex ]
upSelectedStart ( textChar . start , textLine . lineBottom + relativeOffset ( relativePage ) )
upSelectChars ( )
}
/ * *
* 选择结束文字
* /
fun selectEndMoveIndex ( relativePage : Int , lineIndex : Int , charIndex : Int ) {
selectEnd [ 0 ] = relativePage
selectEnd [ 1 ] = lineIndex
selectEnd [ 2 ] = charIndex
val textLine = relativePage ( relativePage ) . textLines [ lineIndex ]
val textChar = textLine . textChars [ charIndex ]
upSelectedEnd ( textChar . end , textLine . lineBottom + relativeOffset ( relativePage ) )
upSelectChars ( )
}
private fun upSelectChars ( ) {
val last = if ( ReadBookConfig . isScroll ) 2 else 0
for ( relativePos in 0. . last ) {
for ( ( lineIndex , textLine ) in relativePage ( relativePos ) . textLines . withIndex ( ) ) {
for ( ( charIndex , textChar ) in textLine . textChars . withIndex ( ) ) {
for ( ( charIndex , textChar ) in textLine . textChars . withIndex ( ) ) {
textChar . selected =
textChar . selected =
if ( lineIndex == selectLineStart && lineIndex == selectLineEnd ) {
if ( relativePos == selectStart [ 0 ]
charIndex in selectCharStart .. selectCharEnd
&& relativePos == selectEnd [ 0 ]
} else if ( lineIndex == selectLineStart ) {
&& lineIndex == selectStart [ 1 ]
charIndex >= selectCharStart
&& lineIndex == selectEnd [ 1 ]
} else if ( lineIndex == selectLineEnd ) {
) {
charIndex <= selectCharEnd
charIndex in selectStart [ 2 ] .. selectEnd [ 2 ]
} else if ( relativePos == selectStart [ 0 ] && lineIndex == selectStart [ 1 ] ) {
charIndex >= selectStart [ 2 ]
} else if ( relativePos == selectEnd [ 0 ] && lineIndex == selectEnd [ 1 ] ) {
charIndex <= selectEnd [ 2 ]
} else if ( relativePos == selectStart [ 0 ] && relativePos == selectEnd [ 0 ] ) {
lineIndex in ( selectStart [ 1 ] + 1 ) until selectEnd [ 1 ]
} else if ( relativePos == selectStart [ 0 ] ) {
lineIndex > selectStart [ 1 ]
} else if ( relativePos == selectEnd [ 0 ] ) {
lineIndex < selectEnd [ 1 ]
} else {
} else {
lineIndex in ( selectLineStart + 1 ) until selectLineEnd
relativePos in selectStart [ 0 ] + 1 until selectEnd [ 0 ]
}
}
}
}
}
}
}
@ -224,55 +478,114 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
}
}
private fun upSelectedStart ( x : Float , y : Float ) {
private fun upSelectedStart ( x : Float , y : Float ) {
a ctivityC allBack. upSelectedStart ( x , y + a ctivityC allBack. headerHeight )
callBack . upSelectedStart ( x , y + callBack . headerHeight )
}
}
private fun upSelectedEnd ( x : Float , y : Float ) {
private fun upSelectedEnd ( x : Float , y : Float ) {
a ctivityC allBack. upSelectedEnd ( x , y + a ctivityC allBack. headerHeight )
callBack . upSelectedEnd ( x , y + callBack . headerHeight )
}
}
fun cancelSelect ( ) {
fun cancelSelect ( ) {
textPage . textLines . forEach { textLine ->
val last = if ( ReadBookConfig . isScroll ) 2 else 0
for ( relativePos in 0. . last ) {
relativePage ( relativePos ) . textLines . forEach { textLine ->
textLine . textChars . forEach {
textLine . textChars . forEach {
it . selected = false
it . selected = false
}
}
}
}
}
invalidate ( )
invalidate ( )
a ctivityC allBack. onCancelSelect ( )
callBack . onCancelSelect ( )
}
}
val selectedText : String
val selectedText : String
get ( ) {
get ( ) {
val stringBuilder = StringBuilder ( )
val stringBuilder = StringBuilder ( )
for ( lineIndex in selectLineStart .. selectLineEnd ) {
for ( relativePos in selectStart [ 0 ] .. selectEnd [ 0 ] ) {
if ( lineIndex == selectLineStart && lineIndex == selectLineEnd ) {
val textPage = relativePage ( relativePos )
if ( relativePos == selectStart [ 0 ] && relativePos == selectEnd [ 0 ] ) {
for ( lineIndex in selectStart [ 1 ] .. selectEnd [ 1 ] ) {
if ( lineIndex == selectStart [ 1 ] && lineIndex == selectEnd [ 1 ] ) {
stringBuilder . append (
textPage . textLines [ lineIndex ] . text . substring (
selectStart [ 2 ] ,
selectEnd [ 2 ] + 1
)
)
} else if ( lineIndex == selectStart [ 1 ] ) {
stringBuilder . append (
stringBuilder . append (
textPage . textLines [ lineIndex ] . text . substring (
textPage . textLines [ lineIndex ] . text . substring (
selectCharStart ,
selectStart [ 2 ]
selectCharEnd + 1
)
)
)
)
} else if ( lineIndex == selectLineStart ) {
} else if ( lineIndex == selectEnd [ 1 ] ) {
stringBuilder . append (
textPage . textLines [ lineIndex ] . text . substring ( 0 , selectEnd [ 2 ] + 1 )
)
} else {
stringBuilder . append ( textPage . textLines [ lineIndex ] . text )
}
}
} else if ( relativePos == selectStart [ 0 ] ) {
for ( lineIndex in selectStart [ 1 ] until relativePage ( relativePos ) . textLines . size ) {
if ( lineIndex == selectStart [ 1 ] ) {
stringBuilder . append (
stringBuilder . append (
textPage . textLines [ lineIndex ] . text . substring (
textPage . textLines [ lineIndex ] . text . substring (
selectCharStart
selectStart [ 2 ]
)
)
)
)
} else if ( lineIndex == selectLineEnd ) {
} else {
stringBuilder . append ( textPage . textLines [ lineIndex ] . text )
}
}
} else if ( relativePos == selectEnd [ 0 ] ) {
for ( lineIndex in 0. . selectEnd [ 1 ] ) {
if ( lineIndex == selectEnd [ 1 ] ) {
stringBuilder . append (
stringBuilder . append (
textPage . textLines [ lineIndex ] . text . substring ( 0 , selectCharEnd + 1 )
textPage . textLines [ lineIndex ] . text . substring ( 0 , selectEnd [ 2 ] + 1 )
)
)
} else {
} else {
stringBuilder . append ( textPage . textLines [ lineIndex ] . text )
stringBuilder . append ( textPage . textLines [ lineIndex ] . text )
}
}
}
}
} else if ( relativePos in selectStart [ 0 ] + 1 until selectEnd [ 0 ] ) {
for ( lineIndex in selectStart [ 1 ] .. selectEnd [ 1 ] ) {
stringBuilder . append ( textPage . textLines [ lineIndex ] . text )
}
}
}
return stringBuilder . toString ( )
return stringBuilder . toString ( )
}
}
private fun selectToInt ( page : Int , line : Int , char : Int ) : Int {
return page * 1000000 + line * 100000 + char
}
private fun selectToInt ( select : Array < Int > ) : Int {
return select [ 0 ] * 1000000 + select [ 1 ] * 100000 + select [ 2 ]
}
private fun relativeOffset ( relativePos : Int ) : Float {
return when ( relativePos ) {
0 -> pageOffset
1 -> pageOffset + textPage . height
else -> pageOffset + textPage . height + pageFactory . nextPage . height
}
}
private fun relativePage ( relativePos : Int ) : TextPage {
return when ( relativePos ) {
0 -> textPage
1 -> pageFactory . nextPage
else -> pageFactory . nextPagePlus
}
}
interface CallBack {
interface CallBack {
fun upSelectedStart ( x : Float , y : Float )
fun upSelectedStart ( x : Float , y : Float )
fun upSelectedEnd ( x : Float , y : Float )
fun upSelectedEnd ( x : Float , y : Float )
fun onCancelSelect ( )
fun onCancelSelect ( )
val headerHeight : Int
val headerHeight : Int
val pageFactory : TextPageFactory
}
}
}
}