diff --git a/assets/mods/basegame/books/btex.xml b/assets/mods/basegame/books/btex.xml
index b3625e784..6d582cb8f 100644
--- a/assets/mods/basegame/books/btex.xml
+++ b/assets/mods/basegame/books/btex.xml
@@ -107,7 +107,7 @@
This is the part where you actually write your body texts in. The body text can have the following tags:
part — inserts part separation page to your book
- chapter, section — inserts a new chapter/section. If an alternative name is required on the Table of Contents, the alt attribute can be used. If the chapter/section needs to be hidden on the Table of Contents, add the hide="1" attribute. If the chapter must start on a new page, see The Macro Definition
+ chapter, section — inserts a new chapter/section. If an alternative name is required on the Table of Contents, the alt attribute can be used. If the chapter/section needs to be hidden on the Table of Contents, add the hide="1" attribute. If the chapter must start on a new page, see the Macro Definition
p — inserts a new paragraph. The body texts must be written inside this tag. All paragraphs will have a 16-pixel indentation, with the following exceptions: first p of the part/chapter/section; first p after br, newpage, callout, ul, ol or anonbreak
span — allows changing the colour or the style of the texts. The colour must be specified in the colour attribute. Six-digit hex code, three-digit hex code and CSS Colours Level 4 named colours are supported. Note that all the colours will be rounded to the nearest three-digit hex code
emph — is a special case of the span tag. The resulting text will be red
@@ -136,7 +136,7 @@
I — use majuscule Roman numerals for the number (I, II, III, …)
1 — use Arabic numerals (1, 2, 3)
- By default, parts use majuscule Roman numerals and others use Arabic. Alternative styling for the part and the chapter can be defined using the Macro Definition.
+ By default, parts use majuscule Roman numerals and others use Arabic. Alternative styling for the part and the chapter can be defined using the Macro Definition.
@@ -311,7 +311,7 @@
notified and will send the mail containing finished books to the player; if the process exits
with errors, the mail containing details of the errors will be sent instead.
- For this reason the “printing press” is not exposed to the player, they only get to interact with it
+
For this reason, the “printing press” is not exposed to the player, they only get to interact with it
indirectly through the “publisher” via mail.
diff --git a/assets/mods/basegame/books/btex_ko.xml b/assets/mods/basegame/books/btex_ko.xml
index 475b3a959..ac4526f59 100644
--- a/assets/mods/basegame/books/btex_ko.xml
+++ b/assets/mods/basegame/books/btex_ko.xml
@@ -103,7 +103,7 @@
원고는 책의 진짜 본문이 담긴 부분을 말한다. 본문에는 다음의 태그를 사용할 수 있다.
part — 원고에 새 부(part)를 추가함
- chapter, section — 원고에 새 장(chapter)·절(section)을 추가함. 목차 페이지에는 다른 이름을 표시하고 싶다면 alt 속성을 사용할 수 있음. 목차 페이지에서 숨기고 싶다면 hide="1" 속성을 추가할 것. 장이 새 페이지에서 시작되게 하려면 매크로 정의문을 볼 것
+ chapter, section — 원고에 새 장(chapter)·절(section)을 추가함. 목차 페이지에는 다른 이름을 표시하고 싶다면 alt 속성을 사용할 수 있음. 목차 페이지에서 숨기고 싶다면 hide="1" 속성을 추가할 것. 장이 새 페이지에서 시작되게 하려면 매크로 정의문을 볼 것
p — 새 문단을 삽입함. 본문의 글은 반드시 이 태그 내부에 작성되어야 함. 모든 문단는 16픽셀의 들여쓰기로 조판되나, 다음의 경우 들여쓰기가 적용되지 않음: 부·장·절의 첫 문단, br, newpage, callout, ul, ol, anonbreak 태그 직후의 문단
span — 문구의 색상이나 스타일을 변경함. 색상은 colour 속성에 작성되어야 함. 6자리 헥스코드, 3자리 헥스코드, CSS Colours Level 4에 정의된 색상명을 사용할 수 있음. 모든 색상은 내부적으로 가장 가까운 3자리 헥스코드로 변경됨에 유의할 것
emph — span의 특수한 경우로, 문구를 빨간색으로 인자함
@@ -132,7 +132,7 @@
I — 번호로 로마 숫자 대문자를 사용함 (I, II, III, …)
1 — 번호로 아라비아 숫자를 사용함 (1, 2, 3)
- 기본값은, 부는 로마 숫자 대문자, 장·절은 아라비아 숫자를 사용한다. 부의 경우 영어로 “Part I”과 같이 찍히고, 이를 “제1절”로 변경하는 등의 심화된 스타일은 매크로 정의문에서 정의할 수 있다.
+ 기본값은, 부는 로마 숫자 대문자, 장·절은 아라비아 숫자를 사용한다. 부의 경우 영어로 “Part I”과 같이 찍히고, 이를 “제1절”로 변경하는 등의 심화된 스타일은 매크로 정의문에서 정의할 수 있다.
diff --git a/src/net/torvald/btex/BTeXDocViewer.kt b/src/net/torvald/btex/BTeXDocViewer.kt
new file mode 100644
index 000000000..c717b9531
--- /dev/null
+++ b/src/net/torvald/btex/BTeXDocViewer.kt
@@ -0,0 +1,110 @@
+package net.torvald.btex
+
+import com.badlogic.gdx.graphics.Color
+import com.badlogic.gdx.graphics.g2d.SpriteBatch
+import net.torvald.terrarum.btex.BTeXDocument
+import net.torvald.terrarum.ceilToInt
+import net.torvald.terrarum.inUse
+
+/**
+ * Created by minjaesong on 2024-05-17.
+ */
+class BTeXDocViewer(val doc: BTeXDocument) {
+
+ private val pageGap = 6
+ private var currentPage = 0
+ private val isTome = (doc.context == "tome")
+
+ val pageCount = doc.pageIndices.endInclusive + 1
+
+ fun gotoPage(page: Int) {
+ val page = page.coerceIn(doc.pageIndices)
+ if (isTome)
+ currentPage = (page / 2) * 2
+ else
+ currentPage = page
+ }
+ fun gotoIndex(id: String) {
+ gotoPage(doc.indexTable[id]!!)
+ }
+
+ fun currentPageStr(): String {
+ // TODO non-tome
+ if (isTome) {
+ return if (currentPage == 0)
+ "1"
+ else
+ "${currentPage}-${currentPage+1}"
+ }
+ else {
+ return (currentPage + 1).toString()
+ }
+ }
+
+
+ /**
+ * @param x top-centre
+ * @param y top-centre
+ */
+ fun render(batch: SpriteBatch, x: Float, y: Float) {
+ val x1 = if (isTome)
+ x.toInt() - pageGap/2 - doc.pageDimensionWidth
+ else
+ x.toInt() - doc.pageDimensionWidth / 2
+
+ val x2 = if (isTome)
+ x.toInt() + pageGap/2
+ else
+ 0
+
+ val y = y.toInt()
+
+ if (doc.isFinalised || doc.fromArchive) {
+ if (isTome) {
+ batch.color = Color.WHITE
+
+ if (currentPage - 1 in doc.pageIndices)
+ doc.render(0f, batch, currentPage - 1, x1, y)
+ if (currentPage in doc.pageIndices)
+ doc.render(0f, batch, currentPage, x2, y)
+ }
+ else {
+ batch.color = Color.WHITE
+
+ if (currentPage in doc.pageIndices)
+ doc.render(0f, batch, currentPage, x1, y)
+ }
+ }
+ }
+
+ fun prevPage() {
+ if (isTome) {
+ currentPage = (currentPage - 2).coerceAtLeast(0)
+ }
+ else {
+ currentPage = (currentPage - 1).coerceAtLeast(0)
+ }
+ }
+
+ fun nextPage() {
+ if (isTome) {
+ currentPage = (currentPage + 2).coerceAtMost(doc.pageIndices.endInclusive.toFloat().div(2f).ceilToInt().times(2))
+ }
+ else {
+ currentPage = (currentPage + 1).coerceAtLeast(doc.pageIndices.endInclusive)
+ }
+ }
+
+ fun gotoFirstPage() {
+ gotoPage(0)
+ }
+
+ fun gotoLastPage() {
+ if (isTome) {
+ currentPage = doc.pageIndices.endInclusive.toFloat().div(2f).ceilToInt().times(2)
+ }
+ else {
+ gotoPage(doc.pageIndices.endInclusive)
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/net/torvald/btex/BTeXDocument.kt b/src/net/torvald/btex/BTeXDocument.kt
index b03d115d8..ac9967825 100644
--- a/src/net/torvald/btex/BTeXDocument.kt
+++ b/src/net/torvald/btex/BTeXDocument.kt
@@ -6,6 +6,7 @@ import com.badlogic.gdx.graphics.*
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.utils.Disposable
+import net.torvald.btex.BTeXDocViewer
import net.torvald.terrarum.ceilToInt
import net.torvald.terrarum.concurrent.ThreadExecutor
import net.torvald.terrarum.imagefont.TinyAlphNum
@@ -55,6 +56,8 @@ class BTeXDocument : Disposable {
var endOfPageStart = 2147483647
var tocPageStart = 2
+ val indexTable = HashMap()
+
companion object {
val DEFAULT_PAGE_BACK = Color(0xe0dfdb_ff.toInt())
// val DEFAULT_PAGE_FORE = Color(0x0a0706_ff)
@@ -260,12 +263,6 @@ class BTeXDocument : Disposable {
*
* `currentLine` *will* be updated automatically.
*/
- fun appendDrawCall(drawCall: BTeXDrawCall) {
- pages.last().appendDrawCall(drawCall)
-
- linesPrintedOnPage[linesPrintedOnPage.lastIndex] += drawCall.lineCount
- }
-
fun appendDrawCall(page: BTeXPage, drawCall: BTeXDrawCall) {
page.appendDrawCall(drawCall)
@@ -273,6 +270,10 @@ class BTeXDocument : Disposable {
linesPrintedOnPage[pagenum] += drawCall.lineCount
}
+ fun appendClickable(page: BTeXPage, clickable: BTeXClickable) {
+ page.appendClickable(clickable)
+ }
+
fun render(frameDelta: Float, batch: SpriteBatch, page: Int, x: Int, y: Int) {
batch.color = Color.WHITE
@@ -330,16 +331,26 @@ class BTeXDocument : Disposable {
}
}
+data class BTeXClickable(
+ val posX: Int, val posY: Int, val width: Int, val height: Int,
+ val onClick: (BTeXDocViewer) -> Unit,
+// val onHover: () -> Unit = {}
+)
+
class BTeXPage(
val back: Color,
val width: Int,
val height: Int,
) {
internal val drawCalls = ArrayList()
+ internal val clickableElements = ArrayList()
fun appendDrawCall(drawCall: BTeXDrawCall) {
if (drawCall.isNotBlank()) drawCalls.add(drawCall)
}
+ fun appendClickable(clickable: BTeXClickable) {
+ clickableElements.add(clickable)
+ }
private var prerender = false
@@ -357,9 +368,24 @@ class BTeXPage(
}
}
+ fun touchDown(viewer: BTeXDocViewer, screenX: Int, screenY: Int, pointer: Int, button: Int) {
+ val pageRelX = screenX - drawX
+ val pageRelY = screenY - drawY
+ // filter clickable elements that are under the cursor
+ clickableElements.filter {
+ pageRelX in it.posX until it.posX+it.width &&
+ pageRelY in it.posY until it.posY+it.height
+ }.forEach { it.onClick(viewer) }
+ }
+
fun isEmpty() = drawCalls.isEmpty()
fun isNotEmpty() = drawCalls.isNotEmpty()
+
+ private var drawX = 0
+ private var drawY = 0
+
fun renderToPixmap(pixmap: Pixmap, x: Int, y: Int, marginH: Int, marginV: Int) {
+ drawX = x; drawY = y
drawCalls.sortedBy { if (it.text != null) 16 else 0 }.let { drawCalls ->
val backCol = back.cpy().also { it.a = 0.93f }
pixmap.setColor(backCol)
diff --git a/src/net/torvald/btex/BTeXParser.kt b/src/net/torvald/btex/BTeXParser.kt
index d289c073e..da1763f24 100644
--- a/src/net/torvald/btex/BTeXParser.kt
+++ b/src/net/torvald/btex/BTeXParser.kt
@@ -12,11 +12,8 @@ import com.jme3.math.FastMath.DEG_TO_RAD
import net.torvald.colourutil.OKLch
import net.torvald.colourutil.tosRGB
import net.torvald.terrarum.*
-import net.torvald.terrarum.btex.BTeXBatchDrawCall
-import net.torvald.terrarum.btex.BTeXDocument
+import net.torvald.terrarum.btex.*
import net.torvald.terrarum.btex.BTeXDocument.Companion.DEFAULT_ORNAMENTS_COL
-import net.torvald.terrarum.btex.BTeXDrawCall
-import net.torvald.terrarum.btex.TypesetDrawCall
import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.ui.Toolkit
@@ -88,6 +85,7 @@ object BTeXParser {
private var tagHistory = ArrayList()
private var currentHrefId: String? = null // any Unicode string that is not empty
+ private var oldHrefTarget: String? = null
private var currentTheme = ""
@@ -104,6 +102,7 @@ object BTeXParser {
}
private val objDict = HashMap BTeXBatchDrawCall>()
+ private val hrefDict = HashMap()
private val objWidthDict = HashMap()
private var lastTagAtDepth = Array(24) { "" }
@@ -119,7 +118,6 @@ object BTeXParser {
private val cptSectStack = ArrayList()
- private val indexMap = HashMap() // id to pagenum
private val cptSectMap = ArrayList()
private var tocPage: Int? = null
@@ -335,10 +333,6 @@ object BTeXParser {
// printdbg(" End element \t($popped)")
}
- private var oldSpanColour: String? = null
- private var oldCodeMode = false
- private var oldHrefMode = false
- private var oldBucksMode = false
private val CODE_TAG_MARGIN = 2
private val CODEMODE_BEGIN = "${spacingBlockToString(CODE_TAG_MARGIN)}$ccCode${TerrarumSansBitmap.charsetOverrideCodestyle}"
@@ -365,12 +359,50 @@ object BTeXParser {
)
}
+ private val REGEX_WHITESPACES = Regex("\\s+")
+
override fun characters(ch: CharArray, start: Int, length: Int) {
var str =
String(ch.sliceArray(start until start + length)).replace('\n', ' ').replace(Regex(" +"), " ")//.trim()
if (str.isNotEmpty()) {
-// printdbg("Characters [col:${spanColour}] \t\"$str\"")
+
+
+ // rising/falling edge of the hrefId
+ if (currentHrefId != oldHrefTarget) {
+ // rising edge
+ if (currentHrefId != null) {
+ printdbg("Href IN($currentHrefId) \t\"$str\"")
+
+ // put OBJ on every word, separated by whitespaces
+ // transform the word such that:
+ // word1 word2 -> [OBJ:XXX]word1 [OBJ:YYY]word2
+ str = str.trim().split(" ").map {
+ val wordWidth = getFont().getWidth(it)
+ val btexObjName = "HREF@${makeRandomObjName()}"
+
+ hrefDict[btexObjName] = currentHrefId!!
+
+ objectMarkerWithWidth(btexObjName, 0) + it
+ }.joinToString(" ")
+
+ }
+ // falling edge
+ else {
+ printdbg("Href OUT(null) \t\"$str\"")
+ }
+ }
+ // hrefId held high
+ else if (currentHrefId != null) {
+ printdbg("Href($currentHrefId) \t\"$str\"")
+ }
+ else {
+ printdbg("String \t\"$str\"")
+ }
+
+
+
+ oldHrefTarget = currentHrefId
paragraphBuffer.append(str)
}
}
@@ -725,6 +757,9 @@ object BTeXParser {
@CloseTag
fun closeElemA(handler: BTeXHandler, doc: BTeXDocument, uri: String, siblingIndex: Int) {
paragraphBuffer.append(HREF_END)
+
+
+
currentHrefId = null
}
@@ -776,8 +811,8 @@ object BTeXParser {
// prepare contents
val pageWidth = doc.textWidth
- indexMap.keys.toList().sorted().forEach { key ->
- typesetTOCline("", key, indexMap[key]!! - 1, handler)
+ doc.indexTable.keys.toList().sorted().forEach { key ->
+ typesetTOCline("", key, doc.indexTable[key]!! - 1, handler)
}
}
@@ -792,7 +827,7 @@ object BTeXParser {
@CloseTag
fun closeElemMANUSCRIPT(handler: BTeXHandler, doc: BTeXDocument, uri: String, siblingIndex: Int) {
- // if tocPage != null, estimate TOC page size, renumber indexMap and cptSectMap if needed, then typeset the toc
+ // if tocPage != null, estimate TOC page size, renumber doc.indexTable and cptSectMap if needed, then typeset the toc
if (tocPage != null) {
// estimate the number of TOC pages
// TOC page always takes up a full paper, therefore tocSizeInPages is always multiple of 2
@@ -800,13 +835,13 @@ object BTeXParser {
if (tocSizeInPages == 0) tocSizeInPages = 2
if (tocSizeInPages % 2 == 1) tocSizeInPages += 1
- println("TOC number of entries: ${cptSectMap.size}, estimated page count: $tocSizeInPages")
+// printdbg("TOC number of entries: ${cptSectMap.size}, estimated page count: $tocSizeInPages")
// renumber things
if (tocSizeInPages > 1) {
val pageDelta = tocSizeInPages - 1
- indexMap.keys.forEach {
- indexMap[it] = indexMap[it]!! + pageDelta
+ doc.indexTable.keys.forEach {
+ doc.indexTable[it] = doc.indexTable[it]!! + pageDelta
}
cptSectMap.forEach { it.pagenum += pageDelta }
@@ -841,7 +876,7 @@ object BTeXParser {
@OpenTag // reflective access is impossible with 'private'
fun processElemINDEX(handler: BTeXHandler, doc: BTeXDocument, uri: String, attribs: HashMap) {
attribs["id"]?.let {
- indexMap[it] = doc.currentPage + 1
+ doc.indexTable[it] = doc.currentPage + 1
}
}
@@ -1614,6 +1649,18 @@ object BTeXParser {
doc.appendDrawCall(doc.pages[pageNum], it); drawCalls.add(it)
}
}
+ val hrefs = parseAndGetHref(textDrawCalls[0], font, handler, posYline, slugs, subset.first, subset.second)
+ hrefs.forEach {
+ // search for:
+ // ..... [OBJ:RSETNFAOON]word setaf
+ // get width of "word"
+ val searchStr = slugs.typesettedSlugs.subList(subset.first, subset.first + subset.second)
+ printdbg("HREF searchStr: ${searchStr.joinToString { it.toReadable() }}")
+// val clickable = BTeXClickable(it.x, it.y, undefined, doc.lineHeightInPx) { viewer ->
+// viewer.gotoIndex(it.hrefTarget)
+// }
+// doc.appendClickable(doc.pages[pageNum], it)
+ }
linesOut += remainder
slugHeight -= remainder
@@ -1634,6 +1681,13 @@ object BTeXParser {
doc.appendDrawCall(doc.pages[pageNum], it); drawCalls.add(it)
}
}
+ // >>> HREF code here!! <<<
+ val hrefs = parseAndGetHref(textDrawCalls[0], font, handler, posYline, slugs, subset.first, subset.second)
+ hrefs.forEach {
+ val searchStr = slugs.typesettedSlugs.subList(subset.first, subset.first + subset.second)
+ printdbg("HREF searchStr: ${searchStr.joinToString { it.toReadable() }}")
+ }
+ // >>> HREF code ends here!! <<<
linesOut += remainder
slugHeight -= remainder
@@ -1652,10 +1706,7 @@ object BTeXParser {
private fun textToDrawCall(handler: BTeXHandler, posYline: Int, slugs: MovableType, lineStart: Int, lineCount: Int): List {
return listOf(
BTeXDrawCall(
- doc,
- 0,
- posYline * doc.lineHeightInPx,
- currentTheme,
+ doc, 0, posYline * doc.lineHeightInPx, currentTheme,
TypesetDrawCall(slugs, lineStart, lineCount)
)
)
@@ -1688,16 +1739,51 @@ object BTeXParser {
c += 1
}
- val extraDrawCall = BTeXDrawCall(
- doc,
- x,
- y,
- currentTheme,
- cmd = objDict[idbuf.toString()]?.invoke(textDrawCall) ?: throw NullPointerException("No OBJ with id '$idbuf' exists"),
- font = font,
- )
+ if (!idbuf.startsWith("HREF@")) {
+ out.add(BTeXDrawCall(
+ doc, x, y, currentTheme,
+ cmd = objDict[idbuf.toString()]?.invoke(textDrawCall)
+ ?: throw NullPointerException("No OBJ with id '$idbuf' exists"),
+ font = font,
+ ))
+ }
+ }
+ }
- out.add(extraDrawCall)
+ return out
+ }
+
+ private fun parseAndGetHref(
+ textDrawCall: BTeXDrawCall,
+ font: TerrarumSansBitmap,
+ handler: BTeXHandler,
+ posYline: Int,
+ slugs: MovableType,
+ lineStart: Int,
+ lineCount: Int
+ ): List<_HrefObject> {
+ val out = ArrayList<_HrefObject>()
+
+ slugs.typesettedSlugs.subList(lineStart, lineStart + lineCount).forEachIndexed { lineNumCnt, line ->
+ line.mapIndexed { i, c -> i to c }.filter { it.second == OBJ }.map { it.first }.forEach { xIndex ->
+ val x = font.getWidthNormalised(CodepointSequence(line.subList(0, xIndex)))
+ val y = (posYline + lineNumCnt) * doc.lineHeightInPx
+
+ // get OBJ id
+ val idbuf = StringBuilder()
+
+ var c = xIndex + 1
+ while (true) {
+ val codepoint = line[c]
+ if (codepoint == 0xFFF9F) break
+ idbuf.append(codepointToObjIdChar(codepoint))
+ c += 1
+ }
+
+ if (idbuf.startsWith("HREF@")) {
+ val id = hrefDict[idbuf.toString()]!!
+ out.add(_HrefObject(x, y, id))
+ }
}
}
@@ -1788,6 +1874,7 @@ object BTeXParser {
doc.addNewPage()
}
+ private data class _HrefObject(val x: Int, val y: Int, val hrefTarget: String)
companion object {
init {
diff --git a/src/net/torvald/terrarum/tests/BTeXTest.kt b/src/net/torvald/terrarum/tests/BTeXTest.kt
index 5534b533f..8717590d1 100644
--- a/src/net/torvald/terrarum/tests/BTeXTest.kt
+++ b/src/net/torvald/terrarum/tests/BTeXTest.kt
@@ -10,6 +10,7 @@ import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.graphics.glutils.ShaderProgram
+import net.torvald.btex.BTeXDocViewer
import net.torvald.btex.BTeXParser
import net.torvald.terrarum.*
import net.torvald.terrarum.btex.BTeXDocument
@@ -94,42 +95,44 @@ class BTeXTest : ApplicationAdapter() {
}
}
- private var scroll = 0
+ var init = false
+ private lateinit var viewer: BTeXDocViewer
- val pageGap = 6
+ private val drawY = 24
override fun render() {
Gdx.graphics.setTitle("BTeXTest $EMDASH F: ${Gdx.graphics.framesPerSecond}")
gdxClearAndEnableBlend(.063f, .070f, .086f, 1f)
+
if (::document.isInitialized) {
- if (document.isFinalised || document.fromArchive) {
- val drawX = (1280 - (pageGap + document.pageDimensionWidth * 2)) / 2
- val drawY = 24
-
+ if (!init) {
+ init = true
+ viewer = BTeXDocViewer(document)
+ }
+ else {
batch.inUse {
- batch.color = Color.WHITE
batch.draw(bg, 0f, 0f)
+ viewer.render(batch, 640f, drawY.toFloat())
- if (scroll - 1 in document.pageIndices)
- document.render(0f, batch, scroll - 1, drawX, drawY)
- if (scroll in document.pageIndices)
- document.render(0f, batch, scroll, drawX + (6 + document.pageDimensionWidth), drawY)
+ batch.color = Color.WHITE
+ val pageText = "${viewer.currentPageStr()}/${viewer.pageCount}"
+ Toolkit.drawTextCentered(
+ batch, TinyAlphNum, pageText,
+ 1280, 0, drawY + document.pageDimensionHeight + 12
+ )
}
-
+ // control
if (Gdx.input.isKeyJustPressed(Input.Keys.LEFT))
- scroll = (scroll - 2).coerceAtLeast(0)
+ viewer.prevPage()
else if (Gdx.input.isKeyJustPressed(Input.Keys.RIGHT))
- scroll =
- (scroll + 2).coerceAtMost(
- document.pageIndices.endInclusive.toFloat().div(2f).ceilToInt().times(2)
- )
+ viewer.nextPage()
else if (Gdx.input.isKeyJustPressed(Input.Keys.PAGE_UP))
- scroll = 0
+ viewer.gotoFirstPage()
else if (Gdx.input.isKeyJustPressed(Input.Keys.PAGE_DOWN))
- scroll = document.pageIndices.endInclusive.toFloat().div(2f).ceilToInt().times(2)
+ viewer.gotoLastPage()
}
}
}