File: dialog_font.tcl

package info (click to toggle)
puredata 0.55.2%2Bds-1~bpo12%2B1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-backports
  • size: 20,336 kB
  • sloc: ansic: 118,788; tcl: 10,221; cpp: 9,327; makefile: 1,632; sh: 1,476; python: 152; xml: 98; awk: 13
file content (231 lines) | stat: -rw-r--r-- 8,994 bytes parent folder | download | duplicates (2)
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

package provide dialog_font 0.1

namespace eval ::dialog_font:: {
    # fontsize is for detecting whether the user actually requested a change
    variable fontsize 0
    variable stretchval 100
    variable whichstretch 1
    variable canvaswindow
    variable sizes {8 10 12 16 24 36}

    namespace export pdtk_canvas_dofont
}

# TODO this should use the pd_font_$size fonts created in pd-gui.tcl
# TODO change pdtk_canvas_dofont to pdtk_font_dialog here and g_editor.c

# TODO this should really be changed on the C side so that it doesn't have to
# work around gfxstub/x_gui.c.  The gfxstub stuff assumes that there are
# multiple panels, for properties panels like this, its much easier to use if
# there is a single properties panel that adjusts based on which PatchWindow
# has focus

# this could probably just be apply, but keep the old one for tcl plugins that
# might use apply for "stretch"
proc ::dialog_font::do_apply {mytoplevel myfontsize stretchval whichstretch} {
    if {$mytoplevel eq ".pdwindow"} {
        foreach font [font names] {
            font configure $font -size $myfontsize
        }
        if {[winfo exists ${mytoplevel}.text]} {
            set font [lindex [${mytoplevel}.text.internal cget -font] 0]
            if { ${font} eq {} } {
                set font $::font_family
            }
            ${mytoplevel}.text.internal configure -font [list $font $myfontsize]

            # try to adjust the width of the Pd-console to 80 chars
            catch {
                set str80 "This string is exactly 80 characters long...ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
                set fnt [${mytoplevel}.text.internal cget -font]
                # how much space do we need for 80 chars (need an extra char for whatever reasons...)?
                set w [expr [winfo width ${mytoplevel}] - \
                           [winfo width ${mytoplevel}.text] + \
                           [font measure $fnt -displayof ${mytoplevel} "${str80} "] \
                          ]
                # make sure it's within reasonable bounds
                foreach {maxw maxh} [wm maxsize .] {break}
                if { $w < 400 } {set w 400}
                if { $w > $maxw } {set w $maxw}
                # get the current geometry of the .pdwindow
                scan [wm geometry $mytoplevel] {%dx%d%[+]%d%[+]%d} width height - x - y
                if { "+$x+$y" eq "+0+0" } {
                    scan [winfo geometry $mytoplevel] {%dx%d%[+]%d%[+]%d} width height - x - y
                }
                # and fix it
                if { $w > $width } {
                    wm geometry $mytoplevel "${w}x${height}+$x+$y"
                }
                # scroll down
                ${mytoplevel}.text.internal yview moveto 1.0
            }
            #::pdwindow::post "This string is exactly 80 characters long...ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n"
        }
        catch {
            ttk::style configure Treeview -rowheight [expr {[font metrics TkDefaultFont -linespace] + 2}]
        }

        # repeat a "pack" command so the font dialog can resize itself
        if {[winfo exists .font]} {
            pack .font.buttonframe -side bottom -fill x -pady 2m
        }

        ::pd_guiprefs::write menu-fontsize "$myfontsize"
        set ::pdwindow::font_size $myfontsize

    } else {
        pdsend "$mytoplevel font $myfontsize $stretchval $whichstretch"
        pdsend "$mytoplevel dirty 1"
    }
}

proc ::dialog_font::radio_apply {mytoplevel myfontsize} {
    variable fontsize
    if {$myfontsize != $fontsize} {
        set fontsize $myfontsize
        ::dialog_font::do_apply $mytoplevel $myfontsize 0 2
    }
}

proc ::dialog_font::stretch_apply {gfxstub} {
    if {$gfxstub ne ".pdwindow"} {
        variable fontsize
        variable stretchval
        variable whichstretch
        if {$stretchval == ""} {
            set stretchval 100
        }
        if {$stretchval == 100} {
            return
        }
        pdsend "$gfxstub font $fontsize $stretchval $whichstretch"
        pdsend "$gfxstub dirty 1"
    }
}

proc ::dialog_font::apply {mytoplevel myfontsize} {
    variable stretchval
    variable whichstretch
    ::dialog_font::do_apply $mytoplevel $myfontsize $stretchval $whichstretch
}

proc ::dialog_font::cancel {gfxstub} {
    if {$gfxstub ne ".pdwindow"} {
        pdsend "$gfxstub cancel"
    }
    destroy .font
}

proc ::dialog_font::update_font_dialog {mytoplevel} {
    variable canvaswindow $mytoplevel
    if {[winfo exists .font]} {
        wm title .font [_ "%s Font" [lookup_windowname $mytoplevel]]
    }
}

proc ::dialog_font::arrow_fontchange {change} {
    variable sizes
    variable fontsize
    variable canvaswindow
    set position [expr [lsearch $sizes $fontsize] + $change]
    if {$position < 0} {set position 0}
    set max [llength $sizes]
    if {$position >= $max} {set position [expr $max-1]}
    set fontsize [lindex $sizes $position]
    ::dialog_font::radio_apply $canvaswindow $fontsize
}

# this should be called pdtk_font_dialog like the rest of the panels, but it
# is called from the C side, so we'll leave it be
proc ::dialog_font::pdtk_canvas_dofont {gfxstub initsize} {
    variable fontsize $initsize
    variable whichstretch 1
    variable stretchval 100
    if {$fontsize < 0} {set fontsize [expr -$fontsize]}
    if {$fontsize < 8} {set fontsize 12}
    if {[winfo exists .font]} {
        wm deiconify .font
        raise .font
        focus .font
        # the gfxstub stuff expects multiple font windows, we only have one,
        # so kill the new gfxstub requests as the come in.  We'll save the
        # original gfxstub for when the font panel gets closed
        pdsend "$gfxstub cancel"
    } else {
        create_dialog $gfxstub
    }
    .font.fontsize.radio$fontsize select
}

proc ::dialog_font::create_dialog {gfxstub} {
    toplevel .font -class DialogWindow
    .font configure -menu $::dialog_menubar
    .font configure -padx 10 -pady 5
    wm group .font .
    wm title .font [_ "Font"]
    wm transient .font $::focused_window
    ::pd_bindings::dialog_bindings .font "font"
    # replace standard bindings to work around the gfxstub stuff and use
    # break to prevent the close window command from going to other bindings.
    # .font won't exist anymore, so it'll cause errors down the line...
    bind .font <KeyPress-Return> "::dialog_font::cancel $gfxstub; break"
    bind .font <KeyPress-Escape> "::dialog_font::cancel $gfxstub; break"
    bind .font <$::modifier-Key-w> "::dialog_font::cancel $gfxstub; break"
    wm protocol .font WM_DELETE_WINDOW "dialog_font::cancel $gfxstub"
    bind .font <Up> "::dialog_font::arrow_fontchange -1"
    bind .font <Down> "::dialog_font::arrow_fontchange 1"

    frame .font.buttonframe
    pack .font.buttonframe -side bottom -pady 2m
    button .font.buttonframe.ok -text [_ "Close"] \
        -command "::dialog_font::cancel $gfxstub" -default active
    pack .font.buttonframe.ok -side left -expand 1 -fill x -ipadx 10

    labelframe .font.fontsize -text [_ "Font Size"] -padx 5 -pady 4 -borderwidth 1 \
        -width [::msgcat::mcmax "Font Size"] -labelanchor n
    pack .font.fontsize -side left -padx 5

    # this is whacky Tcl at its finest, but I couldn't resist...
    foreach size $::dialog_font::sizes {
        radiobutton .font.fontsize.radio$size -value $size -text $size \
            -command [format {::dialog_font::radio_apply \
                $::dialog_font::canvaswindow %s} $size]
        pack .font.fontsize.radio$size -side top -anchor w
    }

    labelframe .font.stretch -text [_ "Stretch"] -padx 5 -pady 5 -borderwidth 1 \
        -width [::msgcat::mcmax "Stretch"] -labelanchor n
    pack .font.stretch -side left -padx 5 -fill y

    entry .font.stretch.entry -textvariable ::dialog_font::stretchval -width 5 \
        -validate key -vcmd {string is int %P}
    pack .font.stretch.entry -side top -pady 5

    radiobutton .font.stretch.radio1 -text [_ "X and Y"] \
        -value 1 -variable ::dialog_font::whichstretch
    radiobutton .font.stretch.radio2 -text [_ "X only"] \
        -value 2 -variable ::dialog_font::whichstretch
    radiobutton .font.stretch.radio3 -text [_ "Y only"] \
        -value 3 -variable ::dialog_font::whichstretch

    pack .font.stretch.radio1 -side top -anchor w
    pack .font.stretch.radio2 -side top -anchor w
    pack .font.stretch.radio3 -side top -anchor w

    button .font.stretch.apply -text [_ "Apply"] \
        -command "::dialog_font::stretch_apply $gfxstub" -default active
    pack .font.stretch.apply -side left -expand 1 -fill x -ipadx 10 \
        -anchor s

    # for focus handling on OSX
    if {$::windowingsystem eq "aqua"} {
        # since we show the active focus, disable the highlight outline
        .font.buttonframe.ok config -highlightthickness 0
    }

    position_over_window .font $::focused_window

    # wait a little for creation, then raise so it's on top
    after 100 raise .font
}