git-gui: Extract blame viewer status bar into mega-widget
authorShawn O. Pearce <spearce@spearce.org>
Mon, 9 Jul 2007 02:01:47 +0000 (22:01 -0400)
committerShawn O. Pearce <spearce@spearce.org>
Mon, 9 Jul 2007 02:34:53 +0000 (22:34 -0400)
Our blame viewer has had a very fancy progress bar at the bottom of
the window that shows the current status of the blame engine, which
includes the number of lines completed as both a text and a graphical
meter.  I want to reuse this meter system in other places, such as
during a branch switch where read-tree -v can give us a progress
meter for any long-running operation.

This change extracts the code and refactors it as a widget that we
can take advantage of in locations other than in the blame viewer.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
lib/blame.tcl
lib/status_bar.tcl [new file with mode: 0644]

index 76b5168fb32bd93f7824c2b8fb9ceb8ac7e139e4..13bfab3352518af99f87186246d57982a4ac35ad 100644 (file)
@@ -21,7 +21,7 @@ field w_amov     ; # text column: annotations + move tracking
 field w_asim     ; # text column: annotations (simple computation)
 field w_file     ; # text column: actual file data
 field w_cviewer  ; # pane showing commit message
-field status     ; # text variable bound to status bar
+field status     ; # status mega-widget instance
 field old_height ; # last known height of $w.file_pane
 
 # Tk UI colors
@@ -242,14 +242,7 @@ constructor new {i_commit i_path} {
        pack $w.file_pane.cm.sbx -side bottom -fill x
        pack $w_cviewer -expand 1 -fill both
 
-       frame $w.status \
-               -borderwidth 1 \
-               -relief sunken
-       label $w.status.l \
-               -textvariable @status \
-               -anchor w \
-               -justify left
-       pack $w.status.l -side left
+       set status [::status_bar::new $w.status]
 
        menu $w.ctxm -tearoff 0
        $w.ctxm add command \
@@ -360,19 +353,6 @@ method _load {jump} {
                set total_lines 0
        }
 
-       if {[winfo exists $w.status.c]} {
-               $w.status.c coords bar 0 0 0 20
-       } else {
-               canvas $w.status.c \
-                       -width 100 \
-                       -height [expr {int([winfo reqheight $w.status.l] * 0.6)}] \
-                       -borderwidth 1 \
-                       -relief groove \
-                       -highlightt 0
-               $w.status.c create rectangle 0 0 0 20 -tags bar -fill navy
-               pack $w.status.c -side right
-       }
-
        if {$history eq {}} {
                $w_back conf -state disabled
        } else {
@@ -386,7 +366,7 @@ method _load {jump} {
        set amov_data [list [list]]
        set asim_data [list [list]]
 
-       set status "Loading $commit:[escape_path $path]..."
+       $status show "Reading $commit:[escape_path $path]..."
        $w_path conf -text [escape_path $path]
        if {$commit eq {}} {
                set fd [open $path r]
@@ -510,13 +490,16 @@ method _exec_blame {cur_w cur_d options cur_s} {
        lappend cmd -- $path
        set fd [open "| $cmd" r]
        fconfigure $fd -blocking 0 -translation lf -encoding binary
-       fileevent $fd readable [cb _read_blame $fd $cur_w $cur_d $cur_s]
+       fileevent $fd readable [cb _read_blame $fd $cur_w $cur_d]
        set current_fd $fd
        set blame_lines 0
-       _status $this $cur_s
+
+       $status start \
+               "Loading$cur_s annotations..." \
+               {lines annotated}
 }
 
-method _read_blame {fd cur_w cur_d cur_s} {
+method _read_blame {fd cur_w cur_d} {
        upvar #0 $cur_d line_data
        variable group_colors
        variable original_options
@@ -697,26 +680,13 @@ method _read_blame {fd cur_w cur_d cur_s} {
                                { original location}
                } else {
                        set current_fd {}
-                       set status {Annotation complete.}
-                       destroy $w.status.c
+                       $status stop {Annotation complete.}
                }
        } else {
-               _status $this $cur_s
+               $status update $blame_lines $total_lines
        }
 } ifdeleted { catch {close $fd} }
 
-method _status {cur_s} {
-       set have  $blame_lines
-       set total $total_lines
-       set pdone 0
-       if {$total} {set pdone [expr {100 * $have / $total}]}
-
-       set status [format \
-               "Loading%s annotations... %i of %i lines annotated (%2i%%)" \
-               $cur_s $have $total $pdone]
-       $w.status.c coords bar 0 0 $pdone 20
-}
-
 method _click {cur_w pos} {
        set lno [lindex [split [$cur_w index $pos] .] 0]
        _showcommit $this $cur_w $lno
diff --git a/lib/status_bar.tcl b/lib/status_bar.tcl
new file mode 100644 (file)
index 0000000..a6dea29
--- /dev/null
@@ -0,0 +1,76 @@
+# 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 status  {}; # single line of text we show
+field prefix  {}; # text we format into status
+field units   {}; # unit of progress
+
+constructor new {path} {
+       set w $path
+       set w_l $w.l
+       set w_c $w.c
+
+       frame $w \
+               -borderwidth 1 \
+               -relief sunken
+       label $w_l \
+               -textvariable @status \
+               -anchor w \
+               -justify left
+       pack $w_l -side left
+
+       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 \
+                       -width 100 \
+                       -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
+               pack $w_c -side right
+       }
+
+       set status $msg
+       set prefix $msg
+       set units  $uds
+}
+
+method update {have total} {
+       set pdone 0
+       if {$total > 0} {
+               set pdone [expr {100 * $have / $total}]
+       }
+
+       set status [format "%s ... %i of %i %s (%2i%%)" \
+               $prefix $have $total $units $pdone]
+       $w_c coords bar 0 0 $pdone 20
+}
+
+method stop {msg} {
+       destroy $w_c
+       set status $msg
+}
+
+method show {msg} {
+       set status $msg
+}
+
+method _delete {current} {
+       if {$current eq $w} {
+               delete_this
+       }
+}
+
+}