summaryrefslogtreecommitdiff
path: root/lib/status_bar.tcl
blob: 02111a1742f92eff7efc6b8e54323919029867bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# git-gui status bar mega-widget
# Copyright (C) 2007 Shawn Pearce

class status_bar {

field w         ; # our own window path
field w_l       ; # text widget we draw messages into
field w_c       ; # canvas we draw a progress bar into
field c_pack    ; # script to pack the canvas with
field status  {}; # single line of text we show
field prefix  {}; # text we format into status
field units   {}; # unit of progress
field meter   {}; # current core git progress meter (if active)

constructor new {path} {
	global use_ttk NS
	set w $path
	set w_l $w.l
	set w_c $w.c

	${NS}::frame $w
	if {!$use_ttk} {
		$w configure -borderwidth 1 -relief sunken
	}
	${NS}::label $w_l \
		-textvariable @status \
		-anchor w \
		-justify left
	pack $w_l -side left
	set c_pack [cb _oneline_pack]

	bind $w <Destroy> [cb _delete %W]
	return $this
}

method _oneline_pack {} {
	$w_c conf -width 100
	pack $w_c -side right
}

constructor two_line {path} {
	global NS
	set w $path
	set w_l $w.l
	set w_c $w.c

	${NS}::frame $w
	${NS}::label $w_l \
		-textvariable @status \
		-anchor w \
		-justify left
	pack $w_l -anchor w -fill x
	set c_pack [list pack $w_c -fill x]

	bind $w <Destroy> [cb _delete %W]
	return $this
}

method start {msg uds} {
	if {[winfo exists $w_c]} {
		$w_c coords bar 0 0 0 20
	} else {
		canvas $w_c \
			-height [expr {int([winfo reqheight $w_l] * 0.6)}] \
			-borderwidth 1 \
			-relief groove \
			-highlightt 0
		$w_c create rectangle 0 0 0 20 -tags bar -fill navy
		eval $c_pack
	}

	set status $msg
	set prefix $msg
	set units  $uds
	set meter  {}
}

method update {have total} {
	set pdone 0
	set cdone 0
	if {$total > 0} {
		set pdone [expr {100 * $have / $total}]
		set cdone [expr {[winfo width $w_c] * $have / $total}]
	}

	set prec [string length [format %i $total]]
	set status [mc "%s ... %*i of %*i %s (%3i%%)" \
		$prefix \
		$prec $have \
		$prec $total \
		$units $pdone]
	$w_c coords bar 0 0 $cdone 20
}

method update_meter {buf} {
	append meter $buf
	set r [string last "\r" $meter]
	if {$r == -1} {
		return
	}

	set prior [string range $meter 0 $r]
	set meter [string range $meter [expr {$r + 1}] end]
	set p "\\((\\d+)/(\\d+)\\)"
	if {[regexp ":\\s*\\d+% $p\(?:, done.\\s*\n|\\s*\r)\$" $prior _j a b]} {
		update $this $a $b
	} elseif {[regexp "$p\\s+done\r\$" $prior _j a b]} {
		update $this $a $b
	}
}

method stop {{msg {}}} {
	destroy $w_c
	if {$msg ne {}} {
		set status $msg
	}
}

method show {msg {test {}}} {
	if {$test eq {} || $status eq $test} {
		set status $msg
	}
}

method _delete {current} {
	if {$current eq $w} {
		delete_this
	}
}

}