Skip to content

Commit afe2098

Browse files
committed
git-gui: Font chooser to handle a large number of font families
Simon Sasburg noticed that on X11 if there are more fonts than can fit in the height of the screen Tk's native tk_optionMenu does not offer scroll arrows to the user and it is not possible to review all choices or to select those that are off-screen. On Mac OS X the tk_optionMenu works properly but is awkward to navigate if the list is long. This is a rewrite of our font selection by providing a new modal dialog that the user can launch from the git-gui Options panel. The dialog offers the user a scrolling list of fonts in a pane. An example text shows the user what the font looks like at the size they have selected. But I have to admit the example pane is less than ideal. For example in the case of our diff font we really should show the user an example diff complete with our native diff syntax coloring. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Acked-by: Simon Sasburg <simon.sasburg@gmail.com>
1 parent e7034d6 commit afe2098

File tree

2 files changed

+182
-11
lines changed

2 files changed

+182
-11
lines changed

lib/choose_font.tcl

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# git-gui font chooser
2+
# Copyright (C) 2007 Shawn Pearce
3+
4+
class choose_font {
5+
6+
field w
7+
field w_family ; # UI widget of all known family names
8+
field w_example ; # Example to showcase the chosen font
9+
10+
field f_family ; # Currently chosen family name
11+
field f_size ; # Currently chosen point size
12+
13+
field v_family ; # Name of global variable for family
14+
field v_size ; # Name of global variable for size
15+
16+
variable all_families [list] ; # All fonts known to Tk
17+
18+
constructor pick {path title a_family a_size} {
19+
variable all_families
20+
21+
set v_family $a_family
22+
set v_size $a_size
23+
24+
upvar #0 $v_family pv_family
25+
upvar #0 $v_size pv_size
26+
27+
set f_family $pv_family
28+
set f_size $pv_size
29+
30+
make_toplevel top w
31+
wm title $top "[appname] ([reponame]): $title"
32+
wm geometry $top "+[winfo rootx $path]+[winfo rooty $path]"
33+
34+
label $w.header -text $title -font font_uibold
35+
pack $w.header -side top -fill x
36+
37+
frame $w.buttons
38+
button $w.buttons.select \
39+
-text [mc Select] \
40+
-default active \
41+
-command [cb _select]
42+
button $w.buttons.cancel \
43+
-text [mc Cancel] \
44+
-command [list destroy $w]
45+
pack $w.buttons.select -side right
46+
pack $w.buttons.cancel -side right -padx 5
47+
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
48+
49+
frame $w.inner
50+
51+
frame $w.inner.family
52+
label $w.inner.family.l \
53+
-text [mc "Font Family"] \
54+
-anchor w
55+
set w_family $w.inner.family.v
56+
text $w_family \
57+
-background white \
58+
-borderwidth 1 \
59+
-relief sunken \
60+
-cursor $::cursor_ptr \
61+
-wrap none \
62+
-width 30 \
63+
-height 10 \
64+
-yscrollcommand [list $w.inner.family.sby set]
65+
scrollbar $w.inner.family.sby -command [list $w_family yview]
66+
pack $w.inner.family.l -side top -fill x
67+
pack $w.inner.family.sby -side right -fill y
68+
pack $w_family -fill both -expand 1
69+
70+
frame $w.inner.size
71+
label $w.inner.size.l \
72+
-text [mc "Font Size"] \
73+
-anchor w
74+
spinbox $w.inner.size.v \
75+
-textvariable @f_size \
76+
-from 2 -to 80 -increment 1 \
77+
-width 3
78+
bind $w.inner.size.v <FocusIn> {%W selection range 0 end}
79+
pack $w.inner.size.l -fill x -side top
80+
pack $w.inner.size.v -fill x -padx 2
81+
82+
grid configure $w.inner.family $w.inner.size -sticky nsew
83+
grid rowconfigure $w.inner 0 -weight 1
84+
grid columnconfigure $w.inner 0 -weight 1
85+
pack $w.inner -fill both -expand 1 -padx 5 -pady 5
86+
87+
frame $w.example
88+
label $w.example.l \
89+
-text [mc "Font Example"] \
90+
-anchor w
91+
set w_example $w.example.t
92+
text $w_example \
93+
-background white \
94+
-borderwidth 1 \
95+
-relief sunken \
96+
-height 3 \
97+
-width 40
98+
$w_example tag conf example -justify center
99+
$w_example insert end [mc "This is example text.\nIf you like this text, it can be your font."] example
100+
$w_example conf -state disabled
101+
pack $w.example.l -fill x
102+
pack $w_example -fill x
103+
pack $w.example -fill x -padx 5
104+
105+
if {$all_families eq {}} {
106+
set all_families [lsort [font families]]
107+
}
108+
109+
$w_family tag conf pick
110+
$w_family tag bind pick <Button-1> [cb _pick_family %x %y]\;break
111+
$w_family tag conf cpck -background lightgray
112+
foreach f $all_families {
113+
set sel [list pick]
114+
if {$f eq $f_family} {
115+
lappend sel cpck
116+
}
117+
$w_family insert end "$f\n" $sel
118+
}
119+
$w_family conf -state disabled
120+
_update $this
121+
122+
trace add variable @f_size write [cb _update]
123+
bind $w <Key-Escape> [list destroy $w]
124+
bind $w <Key-Return> [cb _select]\;break
125+
bind $w <Visibility> "
126+
grab $w
127+
focus $w
128+
"
129+
tkwait window $w
130+
}
131+
132+
method _select {} {
133+
upvar #0 $v_family pv_family
134+
upvar #0 $v_size pv_size
135+
136+
set pv_family $f_family
137+
set pv_size $f_size
138+
139+
destroy $w
140+
}
141+
142+
method _pick_family {x y} {
143+
variable all_families
144+
145+
set i [lindex [split [$w_family index @$x,$y] .] 0]
146+
set n [lindex $all_families [expr {$i - 1}]]
147+
if {$n ne {}} {
148+
$w_family tag remove cpck 0.0 end
149+
$w_family tag add cpck $i.0 [expr {$i + 1}].0
150+
set f_family $n
151+
_update $this
152+
}
153+
}
154+
155+
method _update {args} {
156+
variable all_families
157+
158+
set i [lsearch -exact $all_families $f_family]
159+
if {$i < 0} return
160+
161+
$w_example tag conf example -font [list $f_family $f_size]
162+
$w_family see [expr {$i + 1}].0
163+
}
164+
165+
}

lib/option.tcl

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -255,17 +255,23 @@ proc do_options {} {
255255

256256
frame $w.global.$name
257257
label $w.global.$name.l -text "$text:"
258-
pack $w.global.$name.l -side left -anchor w -fill x
259-
eval tk_optionMenu $w.global.$name.family \
260-
global_config_new(gui.$font^^family) \
261-
$all_fonts
262-
spinbox $w.global.$name.size \
263-
-textvariable global_config_new(gui.$font^^size) \
264-
-from 2 -to 80 -increment 1 \
265-
-width 3
266-
bind $w.global.$name.size <FocusIn> {%W selection range 0 end}
267-
pack $w.global.$name.size -side right -anchor e
268-
pack $w.global.$name.family -side right -anchor e
258+
button $w.global.$name.b \
259+
-text [mc "Change Font"] \
260+
-command [list \
261+
choose_font::pick \
262+
$w \
263+
[mc "Choose %s" $text] \
264+
global_config_new(gui.$font^^family) \
265+
global_config_new(gui.$font^^size) \
266+
]
267+
label $w.global.$name.f -textvariable global_config_new(gui.$font^^family)
268+
label $w.global.$name.s -textvariable global_config_new(gui.$font^^size)
269+
label $w.global.$name.pt -text [mc "pt."]
270+
pack $w.global.$name.l -side left -anchor w
271+
pack $w.global.$name.b -side right -anchor e
272+
pack $w.global.$name.pt -side right -anchor w
273+
pack $w.global.$name.s -side right -anchor w
274+
pack $w.global.$name.f -side right -anchor w
269275
pack $w.global.$name -side top -anchor w -fill x
270276
}
271277

0 commit comments

Comments
 (0)