Skip to content

Commit

Permalink
Bugfix/#37 NaN when visibility gone (#39)
Browse files Browse the repository at this point in the history
* wait for engine to initialize before using it for layout calculations
still needs some investigation into the initialization procedure of individual views, since there is some flickering in the beginning

* use getter function instead of manually setting the state
simplification
  • Loading branch information
markusressel committed Apr 10, 2021
1 parent 5277f2e commit 01b801c
Showing 1 changed file with 55 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ constructor(
*/
lateinit var codeEditorView: CodeEditorView

/**
* Indicates whether the engine has fully initialized
**/
private val isEngineInitialized: Boolean
get() = codeEditorView.engine.computeVerticalScrollRange() > 0
&& codeEditorView.engine.computeHorizontalScrollRange() > 0

/**
* The view displaying line numbers.
* This is also a [ZoomLayout] so the line numbers can be scaled and panned according to the
Expand Down Expand Up @@ -103,8 +110,6 @@ constructor(
var text: String
set(value) {
codeEditorView.text = value
updateLineNumbers()
updateMinimap()
}
get() = codeEditorView.text

Expand Down Expand Up @@ -230,9 +235,6 @@ constructor(
inflateViews(LayoutInflater.from(context))
readParameters(attrs, defStyleAttr)
setListeners()

updateLineNumbers()
updateMinimapBorder()
}

private fun inflateViews(layoutInflater: LayoutInflater) {
Expand Down Expand Up @@ -309,13 +311,19 @@ constructor(
override fun onIdle(engine: ZoomEngine) {}

override fun onUpdate(engine: ZoomEngine, matrix: Matrix) {
if (!isEngineInitialized) return

val editorRect = calculateVisibleCodeArea()
updateLineNumbers(editorRect, updateLineCount = false)
updateMinimapIndicator(editorRect)
}
})

codeEditorView.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
if (!isEngineInitialized) return@addOnLayoutChangeListener
// linenumbers always have to be the exact same size as the content
lineNumberTextView.height = codeEditorView.engine.computeVerticalScrollRange()
updateLineNumbers()
updateMinimap()
}

Expand Down Expand Up @@ -354,13 +362,13 @@ constructor(

codeEditorView.selectionChangedListener = object : SelectionChangedListener {
override fun onSelectionChanged(start: Int, end: Int, hasSelection: Boolean) {
if (isMoveWithCursorEnabled) {
internalMoveWithCursorEnabled = true
try {
moveToCursorIfNecessary()
} catch (e: Throwable) {
Log.e(CodeEditorView.TAG, "Error moving screen with cursor", e)
}
if (!isMoveWithCursorEnabled) return

internalMoveWithCursorEnabled = true
try {
moveToCursorIfNecessary()
} catch (e: Throwable) {
Log.e(CodeEditorView.TAG, "Error moving screen with cursor", e)
}
}
}
Expand Down Expand Up @@ -397,6 +405,7 @@ constructor(
*/
private fun updateMinimap() {
if (!showMinimap) return
if (!isEngineInitialized) return

updateMinimapImage()
updateMinimapIndicator()
Expand Down Expand Up @@ -447,20 +456,18 @@ constructor(
private fun updateMinimapIndicator(editorRect: Rect = calculateVisibleCodeArea()) {
if (!showMinimap) return

codeEditorView.post {
val engine = codeEditorView.engine
val engine = codeEditorView.engine

// update minimap indicator position and size
(minimapIndicator.layoutParams as MarginLayoutParams).apply {
topMargin = ((minimapZoomLayout.height *
(engine.computeVerticalScrollOffset().toFloat() / engine.computeVerticalScrollRange()))).roundToInt()
leftMargin = ((minimapZoomLayout.width *
(engine.computeHorizontalScrollOffset().toFloat() / engine.computeHorizontalScrollRange()))).roundToInt()
// update minimap indicator position and size
(minimapIndicator.layoutParams as MarginLayoutParams).apply {
topMargin = ((minimapZoomLayout.height *
(engine.computeVerticalScrollOffset().toFloat() / engine.computeVerticalScrollRange()))).roundToInt()
leftMargin = ((minimapZoomLayout.width *
(engine.computeHorizontalScrollOffset().toFloat() / engine.computeHorizontalScrollRange()))).roundToInt()

width = (minimapZoomLayout.width * (editorRect.width().toFloat() / engine.computeHorizontalScrollRange())).roundToInt()
height = (minimapZoomLayout.height * (editorRect.height().toFloat() / engine.computeVerticalScrollRange())).roundToInt()
minimapIndicator.layoutParams = this
}
width = (minimapZoomLayout.width * (editorRect.width().toFloat() / engine.computeHorizontalScrollRange())).roundToInt()
height = (minimapZoomLayout.height * (editorRect.height().toFloat() / engine.computeVerticalScrollRange())).roundToInt()
minimapIndicator.layoutParams = this
}
}

Expand All @@ -476,25 +483,23 @@ constructor(
updateLineNumberText()
}

codeEditorView.post {
// adjust width of line numbers based on zoom
val engine = codeEditorView.engine
// adjust width of line numbers based on zoom
val engine = codeEditorView.engine

val scaledWidth = lineNumberTextView.width * engine.realZoom
val maxWidth = editorRect.width() / 3F
val targetWidth = min(scaledWidth, maxWidth).roundToInt()
lineNumberZoomLayout.layoutParams.apply {
width = targetWidth
lineNumberZoomLayout.layoutParams = this
}

// synchronize zoom and vertical pan to match code editor
lineNumberZoomLayout.moveTo(
engine.zoom,
-engine.computeHorizontalScrollRange().toFloat(),
engine.panY,
false)
val scaledWidth = lineNumberTextView.width * engine.realZoom
val maxWidth = editorRect.width() / 3F
val targetWidth = min(scaledWidth, maxWidth).roundToInt()
lineNumberZoomLayout.layoutParams.apply {
width = targetWidth
lineNumberZoomLayout.layoutParams = this
}

// synchronize zoom and vertical pan to match code editor
lineNumberZoomLayout.moveTo(
engine.zoom,
-engine.computeHorizontalScrollRange().toFloat(),
engine.panY,
false)
}

/**
Expand All @@ -510,11 +515,6 @@ constructor(

currentDrawnLineCount = linesToDraw
lineNumberTextView.text = createLineNumberText(linesToDraw)

codeEditorView.post {
// linenumbers always have to be the exact same size as the content
lineNumberTextView.height = codeEditorView.engine.computeVerticalScrollRange()
}
}

/**
Expand All @@ -531,17 +531,15 @@ constructor(
* Moves the screen so that the cursor is visible.
*/
private fun moveToCursorIfNecessary() {
codeEditorView.post {
val cursorPosition = getCursorScreenPosition() ?: return@post
val targetArea = calculateVisibleCodeArea()
val padding = (32 * codeEditorView.realZoom).toInt()
targetArea.inset(padding, padding)
targetArea.offset(0, -padding)

if (!targetArea.contains(cursorPosition.x.roundToInt(), cursorPosition.y.roundToInt())) {
val targetLocation = calculateTargetPoint(cursorPosition, targetArea)
codeEditorView.moveTo(codeEditorView.zoom, targetLocation.x, targetLocation.y, false)
}
val cursorPosition = getCursorScreenPosition() ?: return
val targetArea = calculateVisibleCodeArea()
val padding = (32 * codeEditorView.realZoom).toInt()
targetArea.inset(padding, padding)
targetArea.offset(0, -padding)

if (!targetArea.contains(cursorPosition.x.roundToInt(), cursorPosition.y.roundToInt())) {
val targetLocation = calculateTargetPoint(cursorPosition, targetArea)
codeEditorView.moveTo(codeEditorView.zoom, targetLocation.x, targetLocation.y, false)
}
}

Expand Down

0 comments on commit 01b801c

Please sign in to comment.