diff --git a/git-gui.sh b/git-gui.sh index b097c8c927..5e3fb23300 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -2511,13 +2511,28 @@ proc force_first_diff {after} { } } -proc toggle_or_diff {w x y} { +proc toggle_or_diff {mode w args} { global file_states file_lists current_diff_path ui_index ui_workdir global last_clicked selected_paths - set pos [split [$w index @$x,$y] .] - set lno [lindex $pos 0] - set col [lindex $pos 1] + if {$mode eq "click"} { + foreach {x y} $args break + set pos [split [$w index @$x,$y] .] + foreach {lno col} $pos break + } else { + if {$last_clicked ne {}} { + set lno [lindex $last_clicked 1] + } else { + set lno [expr {int([lindex [$w tag ranges in_diff] 0])}] + } + if {$mode eq "toggle"} { + set col 0; set y 2 + } else { + incr lno [expr {$mode eq "up" ? -1 : 1}] + set col 1 + } + } + set path [lindex $file_lists($w) [expr {$lno - 1}]] if {$path eq {}} { set last_clicked {} @@ -2525,6 +2540,7 @@ proc toggle_or_diff {w x y} { } set last_clicked [list $w $lno] + focus $w array unset selected_paths $ui_index tag remove in_sel 0.0 end $ui_workdir tag remove in_sel 0.0 end @@ -2604,7 +2620,7 @@ proc add_range_to_selection {w x y} { global file_lists last_clicked selected_paths if {[lindex $last_clicked 0] ne $w} { - toggle_or_diff $w $x $y + toggle_or_diff click $w $x $y return } @@ -3184,36 +3200,16 @@ if {$use_ttk} { } pack .vpane -anchor n -side top -fill both -expand 1 -# -- Index File List -# -${NS}::frame .vpane.files.index -height 100 -width 200 -tlabel .vpane.files.index.title \ - -text [mc "Staged Changes (Will Commit)"] \ - -background lightgreen -foreground black -text $ui_index -background white -foreground black \ - -borderwidth 0 \ - -width 20 -height 10 \ - -wrap none \ - -cursor $cursor_ptr \ - -xscrollcommand {.vpane.files.index.sx set} \ - -yscrollcommand {.vpane.files.index.sy set} \ - -state disabled -${NS}::scrollbar .vpane.files.index.sx -orient h -command [list $ui_index xview] -${NS}::scrollbar .vpane.files.index.sy -orient v -command [list $ui_index yview] -pack .vpane.files.index.title -side top -fill x -pack .vpane.files.index.sx -side bottom -fill x -pack .vpane.files.index.sy -side right -fill y -pack $ui_index -side left -fill both -expand 1 - # -- Working Directory File List -# -${NS}::frame .vpane.files.workdir -height 100 -width 200 + +textframe .vpane.files.workdir -height 100 -width 200 tlabel .vpane.files.workdir.title -text [mc "Unstaged Changes"] \ -background lightsalmon -foreground black -text $ui_workdir -background white -foreground black \ +ttext $ui_workdir -background white -foreground black \ -borderwidth 0 \ -width 20 -height 10 \ -wrap none \ + -takefocus 1 -highlightthickness 1\ -cursor $cursor_ptr \ -xscrollcommand {.vpane.files.workdir.sx set} \ -yscrollcommand {.vpane.files.workdir.sy set} \ @@ -3225,6 +3221,30 @@ pack .vpane.files.workdir.sx -side bottom -fill x pack .vpane.files.workdir.sy -side right -fill y pack $ui_workdir -side left -fill both -expand 1 +# -- Index File List +# +textframe .vpane.files.index -height 100 -width 200 +tlabel .vpane.files.index.title \ + -text [mc "Staged Changes (Will Commit)"] \ + -background lightgreen -foreground black +ttext $ui_index -background white -foreground black \ + -borderwidth 0 \ + -width 20 -height 10 \ + -wrap none \ + -takefocus 1 -highlightthickness 1\ + -cursor $cursor_ptr \ + -xscrollcommand {.vpane.files.index.sx set} \ + -yscrollcommand {.vpane.files.index.sy set} \ + -state disabled +${NS}::scrollbar .vpane.files.index.sx -orient h -command [list $ui_index xview] +${NS}::scrollbar .vpane.files.index.sy -orient v -command [list $ui_index yview] +pack .vpane.files.index.title -side top -fill x +pack .vpane.files.index.sx -side bottom -fill x +pack .vpane.files.index.sy -side right -fill y +pack $ui_index -side left -fill both -expand 1 + +# -- Insert the workdir and index into the panes +# .vpane.files add .vpane.files.workdir .vpane.files add .vpane.files.index if {!$use_ttk} { @@ -3307,7 +3327,7 @@ if {![is_enabled nocommit]} { # ${NS}::frame .vpane.lower.commarea.buffer ${NS}::frame .vpane.lower.commarea.buffer.header -set ui_comm .vpane.lower.commarea.buffer.t +set ui_comm .vpane.lower.commarea.buffer.frame.t set ui_coml .vpane.lower.commarea.buffer.header.l if {![is_enabled nocommit]} { @@ -3350,20 +3370,25 @@ if {![is_enabled nocommit]} { pack .vpane.lower.commarea.buffer.header.new -side right } -text $ui_comm -background white -foreground black \ +textframe .vpane.lower.commarea.buffer.frame +ttext $ui_comm -background white -foreground black \ -borderwidth 1 \ -undo true \ -maxundo 20 \ -autoseparators true \ + -takefocus 1 \ + -highlightthickness 1 \ -relief sunken \ -width $repo_config(gui.commitmsgwidth) -height 9 -wrap none \ -font font_diff \ - -yscrollcommand {.vpane.lower.commarea.buffer.sby set} -${NS}::scrollbar .vpane.lower.commarea.buffer.sby \ + -yscrollcommand {.vpane.lower.commarea.buffer.frame.sby set} +${NS}::scrollbar .vpane.lower.commarea.buffer.frame.sby \ -command [list $ui_comm yview] -pack .vpane.lower.commarea.buffer.header -side top -fill x -pack .vpane.lower.commarea.buffer.sby -side right -fill y + +pack .vpane.lower.commarea.buffer.frame.sby -side right -fill y pack $ui_comm -side left -fill y +pack .vpane.lower.commarea.buffer.header -side top -fill x +pack .vpane.lower.commarea.buffer.frame -side left -fill y pack .vpane.lower.commarea.buffer -side left -fill y # -- Commit Message Buffer Context Menu @@ -3461,12 +3486,13 @@ bind_button3 .vpane.lower.diff.header.path "tk_popup $ctxm %X %Y" # -- Diff Body # -${NS}::frame .vpane.lower.diff.body +textframe .vpane.lower.diff.body set ui_diff .vpane.lower.diff.body.t -text $ui_diff -background white -foreground black \ +ttext $ui_diff -background white -foreground black \ -borderwidth 0 \ -width 80 -height 5 -wrap none \ -font font_diff \ + -takefocus 1 -highlightthickness 1 \ -xscrollcommand {.vpane.lower.diff.body.sbx set} \ -yscrollcommand {.vpane.lower.diff.body.sby set} \ -state disabled @@ -3821,10 +3847,10 @@ bind . <$M1B-Key-r> ui_do_rescan bind . <$M1B-Key-R> ui_do_rescan bind . <$M1B-Key-s> do_signoff bind . <$M1B-Key-S> do_signoff -bind . <$M1B-Key-t> do_add_selection -bind . <$M1B-Key-T> do_add_selection -bind . <$M1B-Key-u> do_unstage_selection -bind . <$M1B-Key-U> do_unstage_selection +bind . <$M1B-Key-t> { toggle_or_diff toggle %W } +bind . <$M1B-Key-T> { toggle_or_diff toggle %W } +bind . <$M1B-Key-u> { toggle_or_diff toggle %W } +bind . <$M1B-Key-U> { toggle_or_diff toggle %W } bind . <$M1B-Key-j> do_revert_selection bind . <$M1B-Key-J> do_revert_selection bind . <$M1B-Key-i> do_add_all @@ -3836,9 +3862,11 @@ bind . <$M1B-Key-plus> {show_more_context;break} bind . <$M1B-Key-KP_Add> {show_more_context;break} bind . <$M1B-Key-Return> do_commit foreach i [list $ui_index $ui_workdir] { - bind $i "toggle_or_diff $i %x %y; break" - bind $i <$M1B-Button-1> "add_one_to_selection $i %x %y; break" - bind $i "add_range_to_selection $i %x %y; break" + bind $i { toggle_or_diff click %W %x %y; break } + bind $i <$M1B-Button-1> { add_one_to_selection %W %x %y; break } + bind $i { add_range_to_selection %W %x %y; break } + bind $i { toggle_or_diff up %W; break } + bind $i { toggle_or_diff down %W; break } } unset i diff --git a/lib/themed.tcl b/lib/themed.tcl index 8b88d3678b..351a712c8c 100644 --- a/lib/themed.tcl +++ b/lib/themed.tcl @@ -78,6 +78,57 @@ proc InitTheme {} { } } +# Define a style used for the surround of text widgets. +proc InitEntryFrame {} { + ttk::style theme settings default { + ttk::style layout EntryFrame { + EntryFrame.field -sticky nswe -border 0 -children { + EntryFrame.fill -sticky nswe -children { + EntryFrame.padding -sticky nswe + } + } + } + ttk::style configure EntryFrame -padding 1 -relief sunken + ttk::style map EntryFrame -background {} + } + ttk::style theme settings classic { + ttk::style configure EntryFrame -padding 2 -relief sunken + ttk::style map EntryFrame -background {} + } + ttk::style theme settings alt { + ttk::style configure EntryFrame -padding 2 + ttk::style map EntryFrame -background {} + } + ttk::style theme settings clam { + ttk::style configure EntryFrame -padding 2 + ttk::style map EntryFrame -background {} + } + + # Ignore errors for missing native themes + catch { + ttk::style theme settings winnative { + ttk::style configure EntryFrame -padding 2 + } + ttk::style theme settings xpnative { + ttk::style configure EntryFrame -padding 1 + ttk::style element create EntryFrame.field vsapi \ + EDIT 1 {disabled 4 focus 3 active 2 {} 1} -padding 1 + } + ttk::style theme settings vista { + ttk::style configure EntryFrame -padding 2 + ttk::style element create EntryFrame.field vsapi \ + EDIT 6 {disabled 4 focus 3 active 2 {} 1} -padding 2 + } + } + + bind EntryFrame {%W instate !disabled {%W state active}} + bind EntryFrame {%W state !active} + bind EntryFrame <> { + set pad [ttk::style lookup EntryFrame -padding] + %W configure -padding [expr {$pad eq {} ? 1 : $pad}] + } +} + proc gold_frame {w args} { global use_ttk if {$use_ttk} { @@ -123,7 +174,7 @@ proc paddedlabel {w args} { # place a themed frame over the surface. proc Dialog {w args} { eval [linsert $args 0 toplevel $w -class Dialog] - catch {wm attributes $w -type dialog} + catch {wm attributes $w -type dialog} pave_toplevel $w return $w } @@ -193,6 +244,40 @@ proc tspinbox {w args} { } } +# Create a text widget with any theme specific properties. +proc ttext {w args} { + global use_ttk + if {$use_ttk} { + switch -- [ttk::style theme use] { + "vista" - "xpnative" { + lappend args -highlightthickness 0 -borderwidth 0 + } + } + } + set w [eval [linsert $args 0 text $w]] + if {$use_ttk} { + if {[winfo class [winfo parent $w]] eq "EntryFrame"} { + bind $w {[winfo parent %W] state focus} + bind $w {[winfo parent %W] state !focus} + } + } + return $w +} + +# themed frame suitable for surrounding a text field. +proc textframe {w args} { + global use_ttk + if {$use_ttk} { + if {[catch {ttk::style layout EntryFrame}]} { + InitEntryFrame + } + eval [linsert $args 0 ttk::frame $w -class EntryFrame -style EntryFrame] + } else { + eval [linsert $args 0 frame $w] + } + return $w +} + proc tentry {w args} { global use_ttk if {$use_ttk} {