From 28e608be7fbd05b15e48623228aef092073dc373 Mon Sep 17 00:00:00 2001 From: Giorgio Garofalo Date: Thu, 18 Jul 2024 18:20:40 +0200 Subject: [PATCH] Add fragment behaviors --- .../quarkdown/ast/quarkdown/SlidesFragment.kt | 32 +++++++++++++++++++ .../rendering/html/CssRepresentableVisitor.kt | 9 ++++++ .../html/QuarkdownHtmlNodeRenderer.kt | 2 +- .../RenderRepresentableVisitor.kt | 3 ++ .../eu/iamgio/quarkdown/stdlib/Slides.kt | 6 +++- 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/core/src/main/kotlin/eu/iamgio/quarkdown/ast/quarkdown/SlidesFragment.kt b/core/src/main/kotlin/eu/iamgio/quarkdown/ast/quarkdown/SlidesFragment.kt index f28555b1..7d862019 100644 --- a/core/src/main/kotlin/eu/iamgio/quarkdown/ast/quarkdown/SlidesFragment.kt +++ b/core/src/main/kotlin/eu/iamgio/quarkdown/ast/quarkdown/SlidesFragment.kt @@ -2,15 +2,47 @@ package eu.iamgio.quarkdown.ast.quarkdown import eu.iamgio.quarkdown.ast.NestableNode import eu.iamgio.quarkdown.ast.Node +import eu.iamgio.quarkdown.rendering.representable.RenderRepresentable +import eu.iamgio.quarkdown.rendering.representable.RenderRepresentableVisitor import eu.iamgio.quarkdown.visitor.node.NodeVisitor /** * A node that, when rendered in a `Slides` environment, * is displayed when the user attempts to go to the next slide. * Multiple fragments in the same slide are shown in order on distinct user interactions. + * @param behavior visibility type of the fragment and how it reacts to user interactions */ data class SlidesFragment( + val behavior: Behavior, override val children: List, ) : NestableNode { override fun accept(visitor: NodeVisitor): T = visitor.visit(this) + + /** + * Possible visibility types of a [SlidesFragment]. + */ + enum class Behavior : RenderRepresentable { + /** + * Starts invisible, fades in on interaction. + */ + SHOW, + + /** + * Starts visible, fade out on interaction. + */ + HIDE, + + /** + * Starts visible, fade out to 50% on interaction. + */ + SEMI_HIDE, + + /** + * Starts invisible, fades in on interaction, then out on the next interaction. + */ + SHOW_HIDE, + ; + + override fun accept(visitor: RenderRepresentableVisitor): T = visitor.visit(this) + } } diff --git a/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/CssRepresentableVisitor.kt b/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/CssRepresentableVisitor.kt index 608102b7..1fa784cd 100644 --- a/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/CssRepresentableVisitor.kt +++ b/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/CssRepresentableVisitor.kt @@ -1,6 +1,7 @@ package eu.iamgio.quarkdown.rendering.html import eu.iamgio.quarkdown.ast.quarkdown.Clipped +import eu.iamgio.quarkdown.ast.quarkdown.SlidesFragment import eu.iamgio.quarkdown.ast.quarkdown.Stacked import eu.iamgio.quarkdown.ast.quarkdown.TextTransformData import eu.iamgio.quarkdown.document.page.PageMarginPosition @@ -52,6 +53,14 @@ class CssRepresentableVisitor : RenderRepresentableVisitor { override fun visit(speed: Transition.Speed) = speed.kebabCaseName + override fun visit(behavior: SlidesFragment.Behavior) = + when (behavior) { + SlidesFragment.Behavior.SHOW -> "fade-in" + SlidesFragment.Behavior.HIDE -> "fade-out" + SlidesFragment.Behavior.SEMI_HIDE -> "semi-fade-out" + SlidesFragment.Behavior.SHOW_HIDE -> "fade-in-then-out" + } + override fun visit(size: TextTransformData.Size) = when (size) { TextTransformData.Size.TINY -> "0.5em" diff --git a/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/QuarkdownHtmlNodeRenderer.kt b/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/QuarkdownHtmlNodeRenderer.kt index 39172c02..c55b1ff2 100644 --- a/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/QuarkdownHtmlNodeRenderer.kt +++ b/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/QuarkdownHtmlNodeRenderer.kt @@ -131,7 +131,7 @@ class QuarkdownHtmlNodeRenderer(context: Context) : BaseHtmlNodeRenderer(context override fun visit(node: SlidesFragment): CharSequence = tagBuilder("p", node.children) - .attribute("class", "fragment") + .attribute("class", "fragment ${node.behavior.asCSS}") .build() override fun visit(node: TextTransform) = diff --git a/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/representable/RenderRepresentableVisitor.kt b/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/representable/RenderRepresentableVisitor.kt index 2cd22817..d2533176 100644 --- a/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/representable/RenderRepresentableVisitor.kt +++ b/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/representable/RenderRepresentableVisitor.kt @@ -1,6 +1,7 @@ package eu.iamgio.quarkdown.rendering.representable import eu.iamgio.quarkdown.ast.quarkdown.Clipped +import eu.iamgio.quarkdown.ast.quarkdown.SlidesFragment import eu.iamgio.quarkdown.ast.quarkdown.Stacked import eu.iamgio.quarkdown.ast.quarkdown.TextTransformData import eu.iamgio.quarkdown.document.page.PageMarginPosition @@ -35,6 +36,8 @@ interface RenderRepresentableVisitor { fun visit(speed: Transition.Speed): T + fun visit(behavior: SlidesFragment.Behavior): T + fun visit(size: TextTransformData.Size): T fun visit(weight: TextTransformData.Weight): T diff --git a/stdlib/src/main/kotlin/eu/iamgio/quarkdown/stdlib/Slides.kt b/stdlib/src/main/kotlin/eu/iamgio/quarkdown/stdlib/Slides.kt index d26a82db..74502a3d 100644 --- a/stdlib/src/main/kotlin/eu/iamgio/quarkdown/stdlib/Slides.kt +++ b/stdlib/src/main/kotlin/eu/iamgio/quarkdown/stdlib/Slides.kt @@ -43,7 +43,11 @@ fun setSlidesConfiguration( * Creates an element that, when used in a `slides` document, * shows its content when the user attempts to go to the next slide. * Multiple fragments in the same slide are shown in order on distinct user interactions. + * @param behavior visibility type of the fragment and how it reacts to user interactions * @param content content to show * @return the fragment node */ -fun fragment(content: InlineMarkdownContent) = SlidesFragment(content.children).wrappedAsValue() +fun fragment( + behavior: SlidesFragment.Behavior = SlidesFragment.Behavior.SHOW, + content: InlineMarkdownContent, +) = SlidesFragment(behavior, content.children).wrappedAsValue()