Skip to content

ProgressBar

The ProgressBar widget displays the progress of long-running operations, providing a visual cue to the user. It supports two modes: percentage mode and activity mode.

Percentage Mode

Use percentage mode when the total work can be measured (e.g., reading a set number of bytes from a file). This mode shows a growing bar indicating progress. To update the bar, call ProgressBar.fraction periodically, passing a float value between 0 and 1 to represent the percentage completed.

Activity Mode

For operations where the total work is unknown, use activity mode. This mode shows a block moving back and forth to indicate activity. To update, call ProgressBar.pulse periodically. You can also set the step size using ProgressBar.pulseStep.

Customizing the ProgressBar

By default, the ProgressBar is horizontal and moves left to right, but you can customize it:

  • Orientation: Set ProgressBar.orientation to switch between horizontal and vertical orientations.
  • Direction: Use ProgressBar.inverted to change the direction the bar fills.
  • Text: Display text inside the progress bar with ProgressBar.setText and control its visibility with ProgressBar.showText.

Example

samples/gtk/widgets/src/nativeMain/kotlin/org/gtkkn/samples/gtk/widgets/ProgressBar.kt
private var activityMode: Boolean = false

fun progressBar(): Box {
    val vbox = Box(orientation = Orientation.VERTICAL, spacing = 6).apply {
        setMargins(16)
    }

    val progressBar = ProgressBar().apply {
        vexpand = true
        hexpand = true
    }
    vbox.append(progressBar)

    val showTextButton = CheckButton(label = "Show text")
    showTextButton.connectToggled { onShowTextToggled(showTextButton, progressBar) }
    vbox.append(showTextButton)

    val activityModeButton = CheckButton(label = "Activity mode")
    activityModeButton.connectToggled { onActivityModeToggled(activityModeButton, progressBar) }
    vbox.append(activityModeButton)

    val rightToLeftButton = CheckButton(label = "Right to Left")
    rightToLeftButton.connectToggled { onRightToLeftToggled(rightToLeftButton, progressBar) }
    vbox.append(rightToLeftButton)

    Glib.timeoutAdd(0, 50.toUInt()) {
        onTimeout(progressBar)
    }

    return vbox
}

private fun onShowTextToggled(button: CheckButton, progressBar: ProgressBar) {
    val showText = button.active
    val text = if (showText) "some text" else null
    progressBar.text = text
    progressBar.showText = showText
}

private fun onActivityModeToggled(button: CheckButton, progressBar: ProgressBar) {
    activityMode = button.active
    if (activityMode) {
        progressBar.pulse()
    } else {
        progressBar.fraction = 0.0
    }
}

private fun onRightToLeftToggled(button: CheckButton, progressBar: ProgressBar) {
    progressBar.inverted = button.active
}

private fun onTimeout(progressBar: ProgressBar): Boolean {
    if (activityMode) {
        progressBar.pulse()
    } else {
        var newValue = progressBar.fraction + 0.01
        if (newValue > 1) {
            newValue = 0.0
        }
        progressBar.fraction = newValue
    }
    return true
}