11module gui
22
33import math
4+ import time
45
56// ProgressBarCfg configures a [progress_bar](#progress_bar)
67@[minify]
2526 text_show bool = gui_theme.progress_bar_style.text_show
2627 disabled bool
2728 invisible bool
28- indefinite bool // TODO: not implemented
29+ indefinite bool // indicates indeterminate progress state
2930 vertical bool // orientation
3031}
3132
@@ -38,7 +39,7 @@ pub fn progress_bar(cfg ProgressBarCfg) View {
3839 radius: cfg.radius
3940 color: cfg.color_bar
4041 )
41- if cfg.text_show {
42+ if cfg.text_show && ! cfg.indefinite {
4243 mut percent := f64_min (f64_max (cfg.percent, f64 (0 )), f64 (1 ))
4344 percent = math.round (percent * 100 )
4445 content << row (
@@ -53,6 +54,8 @@ pub fn progress_bar(cfg ProgressBarCfg) View {
5354 bar_percent := cfg.percent
5455 text_show := cfg.text_show
5556 vertical := cfg.vertical
57+ indefinite := cfg.indefinite
58+ id := cfg.id
5659
5760 size := f32 (gui_theme.progress_bar_style.size)
5861 container_cfg := ContainerCfg{
@@ -72,17 +75,66 @@ pub fn progress_bar(cfg ProgressBarCfg) View {
7275 padding: padding_none
7376 h_align: .center
7477 v_align: .middle
75- amend_layout: fn [bar_percent, text_show, vertical] (mut layout Layout, mut w Window) {
78+ amend_layout: fn [bar_percent, text_show, vertical, indefinite, id ] (mut layout Layout, mut w Window) {
7679 if layout.children.len > = 0 {
77- percent := f32_clamp (bar_percent, 0 , 1 )
80+ mut percent := f32_clamp (bar_percent, 0 , 1 )
81+ mut offset := f32 (0 )
82+
83+ if indefinite {
84+ // 30% width bar for indefinite mode
85+ percent = 0.3
86+
87+ // Register animation if missing
88+ anim_id := '${id} _indefinite'
89+ if anim_id ! in w.animations {
90+ mut anim := KeyframeAnimation{
91+ id: anim_id
92+ repeat: true
93+ duration: 1500 * time.millisecond
94+ keyframes: [
95+ Keyframe{
96+ at: 0.0
97+ value: 0.0
98+ },
99+ Keyframe{
100+ at: 0.5
101+ value: 1.0
102+ easing: ease_in_out_quad
103+ },
104+ Keyframe{
105+ at: 1.0
106+ value: 0.0
107+ easing: ease_in_out_quad
108+ },
109+ ]
110+ on_value: fn [id] (v f32 , mut w Window) {
111+ if w.view_state.progress_state.contains (id) {
112+ w.view_state.progress_state.set (id, v)
113+ } else {
114+ // ensure entry exists
115+ w.view_state.progress_state.set (id, v)
116+ }
117+ }
118+ }
119+ anim.start = time.now ()
120+ w.animation_add (mut anim)
121+ }
122+
123+ // Read current animation progress
124+ if progress := w.view_state.progress_state.get (id) {
125+ // Calculate offset based on available space (1.0 - bar_width_percent) * progress
126+ offset = (1.0 - percent) * progress
127+ }
128+ }
129+
78130 if vertical {
79131 height := f32_min (layout.shape.height * percent, layout.shape.height)
80132 layout.children[0 ].shape.x = layout.shape.x
81- layout.children[0 ].shape.y = layout.shape.y
133+ layout.children[0 ].shape.y = layout.shape.y + (layout.shape.height * offset)
82134 layout.children[0 ].shape.height = height
83135 layout.children[0 ].shape.width = layout.shape.width
84136 // center label on bar. Label is row containing text
85- if text_show {
137+ if text_show && ! indefinite {
86138 center := layout.shape.x + layout.shape.width / 2
87139 half_width := layout.children[1 ].shape.width / 2
88140 old_x := layout.children[1 ].shape.x
@@ -97,12 +149,12 @@ pub fn progress_bar(cfg ProgressBarCfg) View {
97149 }
98150 } else {
99151 width := f32_min (layout.shape.width * percent, layout.shape.width)
100- layout.children[0 ].shape.x = layout.shape.x
152+ layout.children[0 ].shape.x = layout.shape.x + (layout.shape.width * offset)
101153 layout.children[0 ].shape.y = layout.shape.y
102154 layout.children[0 ].shape.width = width
103155 layout.children[0 ].shape.height = layout.shape.height
104156 // center label on bar. Label is row containing text
105- if text_show {
157+ if text_show && ! indefinite {
106158 middle := layout.shape.y + layout.shape.height / 2
107159 half_height := layout.children[1 ].shape.height / 2
108160 old_y := layout.children[1 ].shape.y
0 commit comments