Repository: ajalt/mordant (kotlin)

Issue:
Disable glow for progress animation
Is there a way to disable the white glow in the animation? 

![image](https://github.com/ajalt/mordant/assets/33688601/6cf82800-1c9c-47d0-b191-58604399eca7)

Essentially I want something which looks like your example with static color which does advance without this animation.

![image](https://github.com/ajalt/mordant/assets/33688601/e027dd2a-abdb-457a-a583-71abd15a8bde)

Pull request description:
Fixes #122

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 54ef7a1c1..a77cc74e0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,9 @@
 # Changelog
 
 ## Unreleased
+### Added
+- Added `showPulse` parameter to `ProgressLayout.progressBar`, allowing you to disable the pulse animation for a bar.
+
 ### Fixed
 - Fixed exception thrown in environments that are missing required shared native libraries.
 - Fixed animations clearing too much space when the animation changes size while running. [(#110)](https://github.com/ajalt/mordant/issues/110)
diff --git a/mordant/src/commonMain/kotlin/com/github/ajalt/mordant/widgets/ProgressLayout.kt b/mordant/src/commonMain/kotlin/com/github/ajalt/mordant/widgets/ProgressLayout.kt
index c987d4f26..08dff4733 100644
--- a/mordant/src/commonMain/kotlin/com/github/ajalt/mordant/widgets/ProgressLayout.kt
+++ b/mordant/src/commonMain/kotlin/com/github/ajalt/mordant/widgets/ProgressLayout.kt
@@ -10,14 +10,34 @@ import com.github.ajalt.mordant.table.horizontalLayout
 open class ProgressBuilder internal constructor() {
     var padding: Int = 2
 
+    /**
+     * Add fixed text cell to this layout.
+     */
     fun text(text: String) {
         cells += TextProgressCell(Text(text))
     }
 
+    /**
+     * Add a percentage cell to this layout.
+     */
     fun percentage() {
         cells += PercentageProgressCell()
     }
 
+    /**
+     * Add a progress bar cell to this layout.
+     *
+     * @param width The width in characters for this widget
+     * @param pendingChar (theme string: "progressbar.pending") The character to use to draw the pending portion of the bar in the active state.
+     * @param separatorChar (theme string: "progressbar.separator") The character to draw in between the competed and pending bar in the active state.
+     * @param completeChar (theme string: "progressbar.complete") The character to use to draw the completed portion of the bar in the active state.
+     * @param pendingStyle(theme style: "progressbar.pending") The style to use for the [pendingChar]s
+     * @param separatorStyle (theme style: "progressbar.separator") The style to use for the [separatorChar]
+     * @param completeStyle (theme style: "progressbar.complete") The style to use for the [completeChar] when completed < total
+     * @param finishedStyle (theme style: "progressbar.complete") The style to use for the [completeChar] when total <= completed
+     * @param indeterminateStyle e (theme style: "progressbar.separator") The style to use when the state us indeterminate
+     * @param showPulse (theme flag: "progressbar.pulse") If false, never draw the pulse animation in the indeterminate state.
+     */
     fun progressBar(
         width: Int? = null,
         pendingChar: String? = null,
@@ -28,6 +48,7 @@ open class ProgressBuilder internal constructor() {
         completeStyle: TextStyle? = null,
         finishedStyle: TextStyle? = null,
         indeterminateStyle: TextStyle? = null,
+        showPulse: Boolean? = null,
     ) {
         cells += BarProgressCell(
             width,
@@ -38,18 +59,28 @@ open class ProgressBuilder internal constructor() {
             separatorStyle,
             completeStyle,
             finishedStyle,
-            indeterminateStyle
+            indeterminateStyle,
+            showPulse,
         )
     }
 
+    /**
+     * Add a cell that displays the current completed count to this layout.
+     */
     fun completed(suffix: String = "", includeTotal: Boolean = true, style: TextStyle = DEFAULT_STYLE) {
         cells += CompletedProgressCell(suffix, includeTotal, style)
     }
 
+    /**
+     * Add a cell that displays the current speed to this layout.
+     */
     fun speed(suffix: String = "it/s", style: TextStyle = DEFAULT_STYLE) {
         cells += SpeedProgressCell(suffix, style)
     }
 
+    /**
+     * Add a cell that displays the time remaining to this layout.
+     */
     fun timeRemaining(prefix: String = "eta ", style: TextStyle = DEFAULT_STYLE) {
         cells += EtaProgressCell(prefix, style)
     }
@@ -71,6 +102,9 @@ open class ProgressBuilder internal constructor() {
     internal val cells = mutableListOf<ProgressCell>()
 }
 
+/**
+ * A builder for creating an animated progress bar widget.
+ */
 class ProgressLayout internal constructor(
     internal val cells: List<ProgressCell>,
     private val paddingSize: Int,
@@ -108,6 +142,9 @@ class ProgressLayout internal constructor(
     }
 }
 
+/**
+ * Build a [ProgressLayout]
+ */
 fun progressLayout(init: ProgressBuilder.() -> Unit): ProgressLayout {
     return ProgressBuilder().apply(init).build()
 }


Test patch:
diff --git a/mordant/src/commonTest/kotlin/com/github/ajalt/mordant/widgets/ProgressLayoutTest.kt b/mordant/src/commonTest/kotlin/com/github/ajalt/mordant/widgets/ProgressLayoutTest.kt
index 2d5ef014d..ef1337754 100644
--- a/mordant/src/commonTest/kotlin/com/github/ajalt/mordant/widgets/ProgressLayoutTest.kt
+++ b/mordant/src/commonTest/kotlin/com/github/ajalt/mordant/widgets/ProgressLayoutTest.kt
@@ -1,11 +1,14 @@
 package com.github.ajalt.mordant.widgets
 
+import com.github.ajalt.mordant.rendering.TextColors
 import com.github.ajalt.mordant.rendering.Theme
 import com.github.ajalt.mordant.test.RenderingTest
 import kotlin.js.JsName
 import kotlin.test.Test
 
 class ProgressLayoutTest : RenderingTest() {
+    private val indetermStyle = Theme.Default.style("progressbar.indeterminate")
+
     @Test
     fun indeterminate() = doTest(
         0,
@@ -52,6 +55,27 @@ class ProgressLayoutTest : RenderingTest() {
         "1    0%  2   ---.-it/s  3",
     )
 
+    @Test
+    fun pulse() = checkRender(
+        progressLayout {
+            progressBar()
+        }.build(0, null, 1.0, 0.0),
+        indetermStyle("━${TextColors.rgb(1, 1, 1)("━")}━"),
+        width = 3,
+    )
+
+    @Test
+    @JsName("no_pulse")
+    fun `no pulse`() {
+        checkRender(
+            progressLayout {
+                progressBar(showPulse = false)
+            }.build(0, null, 1.0, 0.0),
+            indetermStyle("━━━"),
+            width = 3,
+        )
+    }
+
     private fun doTest(
         completed: Long,
         total: Long? = null,