git-gui / lib / status_bar.tclon commit Merge branch 'bs/lock' (922b0e3)
   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}