mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[markdown][compose] IJPL-175966 Provide smoother animation
GitOrigin-RevId: 12880ed9794077b5f6ad185fe38c25113f1d53a2
This commit is contained in:
committed by
intellij-monorepo-bot
parent
0458e409ee
commit
22d7628468
@@ -581,6 +581,7 @@ a:org.jetbrains.jewel.markdown.scrolling.ScrollingSynchronizer
|
||||
- pa:afterProcessing():V
|
||||
- pa:beforeProcessing():V
|
||||
- f:process(kotlin.jvm.functions.Function0):java.lang.Object
|
||||
- a:scrollToLine(I,kotlin.coroutines.Continuation):java.lang.Object
|
||||
- a:scrollToLine(I,androidx.compose.animation.core.AnimationSpec,kotlin.coroutines.Continuation):java.lang.Object
|
||||
- bs:scrollToLine$default(org.jetbrains.jewel.markdown.scrolling.ScrollingSynchronizer,I,androidx.compose.animation.core.AnimationSpec,kotlin.coroutines.Continuation,I,java.lang.Object):java.lang.Object
|
||||
f:org.jetbrains.jewel.markdown.scrolling.ScrollingSynchronizer$Companion
|
||||
- f:create(androidx.compose.foundation.gestures.ScrollableState):org.jetbrains.jewel.markdown.scrolling.ScrollingSynchronizer
|
||||
|
||||
+5
-3
@@ -2,6 +2,8 @@
|
||||
// Apache 2.0 license.
|
||||
package org.jetbrains.jewel.markdown.scrolling
|
||||
|
||||
import androidx.compose.animation.core.AnimationSpec
|
||||
import androidx.compose.animation.core.SpringSpec
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.gestures.ScrollableState
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
@@ -69,7 +71,7 @@ import org.jetbrains.jewel.markdown.processing.MarkdownProcessor
|
||||
@ExperimentalJewelApi
|
||||
public abstract class ScrollingSynchronizer {
|
||||
/** Scroll the preview to the position that match the given [sourceLine] the best. */
|
||||
public abstract suspend fun scrollToLine(sourceLine: Int)
|
||||
public abstract suspend fun scrollToLine(sourceLine: Int, animationSpec: AnimationSpec<Float> = SpringSpec())
|
||||
|
||||
/**
|
||||
* Called when [MarkdownProcessor] processes the raw markdown text. The processing itself is passed as an [action].
|
||||
@@ -146,7 +148,7 @@ public abstract class ScrollingSynchronizer {
|
||||
// so this map always keeps relevant information.
|
||||
private val blocks2TextOffsets = mutableMapOf<MarkdownBlock, List<Int>>()
|
||||
|
||||
override suspend fun scrollToLine(sourceLine: Int) {
|
||||
override suspend fun scrollToLine(sourceLine: Int, animationSpec: AnimationSpec<Float>) {
|
||||
val block = findBestBlockForLine(sourceLine) ?: return
|
||||
val y = blocks2Top[block] ?: return
|
||||
if (y < 0) return
|
||||
@@ -156,7 +158,7 @@ public abstract class ScrollingSynchronizer {
|
||||
// in this case scroll to the first line of the first block positioned after the line
|
||||
val lineIndexInBlock = maxOf(0, sourceLine - lineRange.start)
|
||||
val lineOffset = textOffsets?.get(lineIndexInBlock) ?: 0
|
||||
scrollState.animateScrollTo(y + lineOffset)
|
||||
scrollState.animateScrollTo(y + lineOffset, animationSpec)
|
||||
}
|
||||
|
||||
private fun findBestBlockForLine(line: Int): MarkdownBlock? {
|
||||
|
||||
+1
-1
@@ -21,6 +21,7 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import java.util.Arrays
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -59,7 +60,6 @@ import org.jetbrains.jewel.ui.component.styling.TrackClickBehavior
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import java.util.Arrays
|
||||
|
||||
@Suppress("LargeClass")
|
||||
class ScrollingSynchronizerTest {
|
||||
|
||||
+9
-2
@@ -1,6 +1,9 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.markdown.compose.preview
|
||||
|
||||
import androidx.compose.animation.core.AnimationSpec
|
||||
import androidx.compose.animation.core.LinearEasing
|
||||
import androidx.compose.animation.core.TweenSpec
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
@@ -95,7 +98,11 @@ internal class MarkdownComposePanel(
|
||||
@OptIn(FlowPreview::class)
|
||||
@Suppress("FunctionName")
|
||||
@Composable
|
||||
private fun MarkdownPreviewPanel(scrollState: ScrollState, scrollingSynchronizer: ScrollingSynchronizer?, blockRenderer: ScrollSyncMarkdownBlockRenderer) {
|
||||
private fun MarkdownPreviewPanel(scrollState: ScrollState,
|
||||
scrollingSynchronizer: ScrollingSynchronizer?,
|
||||
blockRenderer: ScrollSyncMarkdownBlockRenderer,
|
||||
animationSpec: AnimationSpec<Float> = TweenSpec(easing = LinearEasing)
|
||||
) {
|
||||
val request by updateHandler.requests.collectAsState(null)
|
||||
(request as? PreviewRequest.Update)?.let {
|
||||
if (scrollingSynchronizer != null) {
|
||||
@@ -103,7 +110,7 @@ internal class MarkdownComposePanel(
|
||||
LaunchedEffect(Unit) {
|
||||
coroutineScope.launch {
|
||||
scrollToLineFlow.debounce(16.milliseconds).collect { scrollToLine ->
|
||||
scrollingSynchronizer.scrollToLine(scrollToLine)
|
||||
scrollingSynchronizer.scrollToLine(scrollToLine, animationSpec)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user