1# git-gui status bar mega-widget
2# Copyright (C) 2007 Shawn Pearce
3
4class status_bar {
5
6field w ; # our own window path
7field w_l ; # text widget we draw messages into
8field w_c ; # canvas we draw a progress bar into
9field status {}; # single line of text we show
10field prefix {}; # text we format into status
11field units {}; # unit of progress
12field meter {}; # current core git progress meter (if active)
13
14constructor new {path} {
15 set w $path
16 set w_l $w.l
17 set w_c $w.c
18
19 frame $w \
20 -borderwidth 1 \
21 -relief sunken
22 label $w_l \
23 -textvariable @status \
24 -anchor w \
25 -justify left
26 pack $w_l -side left
27
28 bind $w <Destroy> [cb _delete %W]
29 return $this
30}
31
32method start {msg uds} {
33 if {[winfo exists $w_c]} {
34 $w_c coords bar 0 0 0 20
35 } else {
36 canvas $w_c \
37 -width 100 \
38 -height [expr {int([winfo reqheight $w_l] * 0.6)}] \
39 -borderwidth 1 \
40 -relief groove \
41 -highlightt 0
42 $w_c create rectangle 0 0 0 20 -tags bar -fill navy
43 pack $w_c -side right
44 }
45
46 set status $msg
47 set prefix $msg
48 set units $uds
49 set meter {}
50}
51
52method update {have total} {
53 set pdone 0
54 if {$total > 0} {
55 set pdone [expr {100 * $have / $total}]
56 }
57
58 set status [format "%s ... %i of %i %s (%2i%%)" \
59 $prefix $have $total $units $pdone]
60 $w_c coords bar 0 0 $pdone 20
61}
62
63method update_meter {buf} {
64 append meter $buf
65 set r [string last "\r" $meter]
66 if {$r == -1} {
67 return
68 }
69
70 set prior [string range $meter 0 $r]
71 set meter [string range $meter [expr {$r + 1}] end]
72 if {[regexp "\\((\\d+)/(\\d+)\\)\\s+done\r\$" $prior _j a b]} {
73 update $this $a $b
74 }
75}
76
77method stop {{msg {}}} {
78 destroy $w_c
79 if {$msg ne {}} {
80 set status $msg
81 }
82}
83
84method show {msg {test {}}} {
85 if {$test eq {} || $status eq $test} {
86 set status $msg
87 }
88}
89
90method _delete {current} {
91 if {$current eq $w} {
92 delete_this
93 }
94}
95
96}