aboutsummaryrefslogtreecommitdiff
path: root/pd/tcl/pdtk_array.tcl
blob: 107a722c9176aae68456c7738ad5baf2d9d24a52 (plain)
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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
package provide pdtk_array 0.1

#### jsarlo #####
proc pdtk_array_listview_setpage {arrayName page} {
    global pd_array_listview_page
    set pd_array_listview_page($arrayName) $page
}

proc pdtk_array_listview_changepage {arrayName np} {
    global pd_array_listview_page
    pdtk_array_listview_setpage \
        $arrayName [expr $pd_array_listview_page($arrayName) + $np]
    pdtk_array_listview_fillpage $arrayName
}

proc pdtk_array_listview_fillpage {arrayName} {
    global pd_array_listview_page
    global pd_array_listview_id
    set windowName [format ".%sArrayWindow" $arrayName]
    set topItem [expr [lindex [$windowName.lb yview] 0] * \
                     [$windowName.lb size]]
    
    if {[winfo exists $windowName]} {
        set cmd "$pd_array_listview_id($arrayName) \
               arrayviewlistfillpage \
               $pd_array_listview_page($arrayName) \
               $topItem"
        
        pdsend $cmd
    }
}

proc pdtk_array_listview_new {id arrayName page} {
    global pd_array_listview_page
    global pd_array_listview_id
    global fontname fontweight
    set pd_array_listview_page($arrayName) $page
    set pd_array_listview_id($arrayName) $id
    set windowName [format ".%sArrayWindow" $arrayName]
    if [winfo exists $windowName] then [destroy $windowName]
    toplevel $windowName
    wm protocol $windowName WM_DELETE_WINDOW \
        "pdtk_array_listview_close $id $arrayName"
    wm title $windowName [concat $arrayName "(list view)"]
    # FIXME
    set font 12
    set $windowName.lb [listbox $windowName.lb -height 20 -width 25\
                            -selectmode extended \
                            -relief solid -background white -borderwidth 1 \
                            -font [format {{%s} %d %s} $fontname $font $fontweight]\
                            -yscrollcommand "$windowName.lb.sb set"]
    set $windowName.lb.sb [scrollbar $windowName.lb.sb \
                               -command "$windowName.lb yview" -orient vertical]
    place configure $windowName.lb.sb -relheight 1 -relx 0.9 -relwidth 0.1
    pack $windowName.lb -expand 1 -fill both
    bind $windowName.lb <Double-ButtonPress-1> \
        "pdtk_array_listview_edit $arrayName $page $font"
    # handle copy/paste
    if {[tk windowingsystem] eq "x11"} {
        selection handle $windowName.lb \
            "pdtk_array_listview_lbselection $arrayName"
    } else {
        if {[tk windowingsystem] eq "win32"} {
            bind $windowName.lb <ButtonPress-3> \
                "pdtk_array_listview_popup $arrayName"
        } 
    }
    set $windowName.prevBtn [button $windowName.prevBtn -text "<-" \
                                 -command "pdtk_array_listview_changepage $arrayName -1"]
    set $windowName.nextBtn [button $windowName.nextBtn -text "->" \
                                 -command "pdtk_array_listview_changepage $arrayName 1"]
    pack $windowName.prevBtn -side left -ipadx 20 -pady 10 -anchor s
    pack $windowName.nextBtn -side right -ipadx 20 -pady 10 -anchor s
    focus $windowName
}

proc pdtk_array_listview_lbselection {arrayName off size} {
    set windowName [format ".%sArrayWindow" $arrayName]
    set itemNums [$windowName.lb curselection]
    set cbString ""
    for {set i 0} {$i < [expr [llength $itemNums] - 1]} {incr i} {
        set listItem [$windowName.lb get [lindex $itemNums $i]]
        append cbString [string range $listItem \
                             [expr [string first ") " $listItem] + 2] \
                             end]
        append cbString "\n"
    }
    set listItem [$windowName.lb get [lindex $itemNums $i]]
    append cbString [string range $listItem \
                         [expr [string first ") " $listItem] + 2] \
                         end]
    set last $cbString
}

# Win32 uses a popup menu for copy/paste
proc pdtk_array_listview_popup {arrayName} {
    set windowName [format ".%sArrayWindow" $arrayName]
    if [winfo exists $windowName.popup] then [destroy $windowName.popup]
    menu $windowName.popup -tearoff false
    $windowName.popup add command -label {Copy} \
        -command "pdtk_array_listview_copy $arrayName; \
                  destroy $windowName.popup"
    $windowName.popup add command -label {Paste} \
        -command "pdtk_array_listview_paste $arrayName; \
                  destroy $windowName.popup"
    tk_popup $windowName.popup [winfo pointerx $windowName] \
        [winfo pointery $windowName] 0
}

proc pdtk_array_listview_copy {arrayName} {
    set windowName [format ".%sArrayWindow" $arrayName]
    set itemNums [$windowName.lb curselection]
    set cbString ""
    for {set i 0} {$i < [expr [llength $itemNums] - 1]} {incr i} {
        set listItem [$windowName.lb get [lindex $itemNums $i]]
        append cbString [string range $listItem \
                             [expr [string first ") " $listItem] + 2] \
                             end]
        append cbString "\n"
    }
    set listItem [$windowName.lb get [lindex $itemNums $i]]
    append cbString [string range $listItem \
                         [expr [string first ") " $listItem] + 2] \
                         end]
    clipboard clear
    clipboard append $cbString
}

proc pdtk_array_listview_paste {arrayName} {
    global pd_array_listview_page
    global pd_array_listview_pagesize
    set cbString [selection get -selection CLIPBOARD]
    set lbName [format ".%sArrayWindow.lb" $arrayName]
    set itemNum [lindex [$lbName curselection] 0]
    set splitChars ", \n"
    set itemString [split $cbString $splitChars]
    set flag 1
    for {set i 0; set counter 0} {$i < [llength $itemString]} {incr i} {
        if {[lindex $itemString $i] != {}} {
            pdsend "$arrayName [expr $itemNum + \
                                       [expr $counter + \
                                            [expr $pd_array_listview_pagesize \
                                                 * $pd_array_listview_page($arrayName)]]] \
                    [lindex $itemString $i]"
            incr counter
            set flag 0
        }
    }
}

proc pdtk_array_listview_edit {arrayName page font} {
    global pd_array_listview_entry
    global fontname fontweight
    set lbName [format ".%sArrayWindow.lb" $arrayName]
    if {[winfo exists $lbName.entry]} {
        pdtk_array_listview_update_entry \
            $arrayName $pd_array_listview_entry($arrayName)
        unset pd_array_listview_entry($arrayName)
    }
    set itemNum [$lbName index active]
    set pd_array_listview_entry($arrayName) $itemNum
    set bbox [$lbName bbox $itemNum]
    set y [expr [lindex $bbox 1] - 4]
    set $lbName.entry [entry $lbName.entry \
                           -font [format {{%s} %d %s} $fontname $font $fontweight]]
    $lbName.entry insert 0 []
    place configure $lbName.entry -relx 0 -y $y -relwidth 1
    lower $lbName.entry
    focus $lbName.entry
    bind $lbName.entry <Return> \
        "pdtk_array_listview_update_entry $arrayName $itemNum;"
}

proc pdtk_array_listview_update_entry {arrayName itemNum} {
    global pd_array_listview_page
    global pd_array_listview_pagesize
    set lbName [format ".%sArrayWindow.lb" $arrayName]
    set splitChars ", \n"
    set itemString [split [$lbName.entry get] $splitChars]
    set flag 1
    for {set i 0; set counter 0} {$i < [llength $itemString]} {incr i} {
        if {[lindex $itemString $i] != {}} {
            pdsend [concat $arrayName [expr $itemNum + \
                                       [expr $counter + \
                                            [expr $pd_array_listview_pagesize \
                                                 * $pd_array_listview_page($arrayName)]]] \
                    [lindex $itemString $i] \;]
            incr counter
            set flag 0
        }
    }
    pdtk_array_listview_fillpage $arrayName
    destroy $lbName.entry
}

proc pdtk_array_listview_closeWindow {arrayName} {
    set windowName [format ".%sArrayWindow" $arrayName]
    destroy $windowName
}

proc pdtk_array_listview_close {id arrayName} {
    pdtk_array_listview_closeWindow $arrayName
    pdsend "$id arrayviewclose"
}
##### end jsarlo #####

############ pdtk_array_dialog -- dialog window for arrays #########
# see comments above (pdtk_gatom_dialog) about variable name handling 

proc array_apply {id} {
    # strip "." from the TK id to make a variable name suffix 
    set vid [string trimleft $id .]
    # for each variable, make a local variable to hold its name...
    set var_array_name [concat array_name_$vid]
    global $var_array_name
    set var_array_n [concat array_n_$vid]
    global $var_array_n
    set var_array_saveit [concat array_saveit_$vid]
    global $var_array_saveit
    set var_array_drawasrects [concat array_drawasrects_$vid]
    global $var_array_drawasrects
    set var_array_otherflag [concat array_otherflag_$vid]
    global $var_array_otherflag
    set mofo [eval concat $$var_array_name]
    if {[string index $mofo 0] == "$"} {
        set mofo [string replace $mofo 0 0 #] }

    set saveit [eval concat $$var_array_saveit]
    set drawasrects [eval concat $$var_array_drawasrects]

    pdsend "$id arraydialog $mofo [eval concat $$var_array_n] \
            [expr $saveit + 2 * $drawasrects] [eval concat $$var_array_otherflag]"
}

# jsarlo
proc array_viewlist {id} {
    pdsend "$id arrayviewlistnew"
}
# end jsarlo

proc array_cancel {id} {
    pdsend "$id cancel"
}

proc array_ok {id} {
    array_apply $id
    array_cancel $id
}

proc pdtk_array_dialog {id name n flags newone} {
    set vid [string trimleft $id .]

    set var_array_name [concat array_name_$vid]
    global $var_array_name
    set var_array_n [concat array_n_$vid]
    global $var_array_n
    set var_array_saveit [concat array_saveit_$vid]
    global $var_array_saveit
    set var_array_drawasrects [concat array_drawasrects_$vid]
    global $var_array_drawasrects
    set var_array_otherflag [concat array_otherflag_$vid]
    global $var_array_otherflag

    set $var_array_name $name
    set $var_array_n $n
    set $var_array_saveit [expr ( $flags & 1 ) != 0]
    set $var_array_drawasrects [expr ( $flags & 2 ) != 0]
    set $var_array_otherflag 0

    toplevel $id
    wm title $id {array}
    wm resizable $id 0 0
    wm protocol $id WM_DELETE_WINDOW [concat array_cancel $id]

    ::pd_bindings::panel_bindings $id "array"

    frame $id.name
    pack $id.name -side top
    label $id.name.label -text "name"
    entry $id.name.entry -textvariable $var_array_name
    pack $id.name.label $id.name.entry -side left

    frame $id.n
    pack $id.n -side top
    label $id.n.label -text "size"
    entry $id.n.entry -textvariable $var_array_n
    pack $id.n.label $id.n.entry -side left

    checkbutton $id.saveme -text {save contents} -variable $var_array_saveit \
        -anchor w
    pack $id.saveme -side top

    frame $id.drawasrects
    pack $id.drawasrects -side top
    radiobutton $id.drawasrects.drawasrects0 -value 0 \
        -variable $var_array_drawasrects \
        -text "draw as points"
    radiobutton $id.drawasrects.drawasrects1 -value 1 \
        -variable $var_array_drawasrects \
        -text "polygon"
    radiobutton $id.drawasrects.drawasrects2 -value 2 \
        -variable $var_array_drawasrects \
        -text "bezier curve"
    pack $id.drawasrects.drawasrects0 -side top -anchor w
    pack $id.drawasrects.drawasrects1 -side top -anchor w
    pack $id.drawasrects.drawasrects2 -side top -anchor w

    if {$newone != 0} {
        frame $id.radio
        pack $id.radio -side top
        radiobutton $id.radio.radio0 -value 0 \
            -variable $var_array_otherflag \
            -text "in new graph"
        radiobutton $id.radio.radio1 -value 1 \
            -variable $var_array_otherflag \
            -text "in last graph"
        pack $id.radio.radio0 -side top -anchor w
        pack $id.radio.radio1 -side top -anchor w
    } else {    
        checkbutton $id.deleteme -text {delete me} \
            -variable $var_array_otherflag -anchor w
        pack $id.deleteme -side top
    }
    # jsarlo
    if {$newone == 0} {
        button $id.listview -text {View list}\
            -command "array_viewlist $id $name 0"
        pack $id.listview -side left
    }
    # end jsarlo
    frame $id.buttonframe
    pack $id.buttonframe -side bottom -fill x -pady 2m
    button $id.buttonframe.cancel -text {Cancel}\
        -command "array_cancel $id"
    if {$newone == 0} {button $id.buttonframe.apply -text {Apply}\
                           -command "array_apply $id"}
    button $id.buttonframe.ok -text {OK}\
        -command "array_ok $id"
    pack $id.buttonframe.cancel -side left -expand 1
    if {$newone == 0} {pack $id.buttonframe.apply -side left -expand 1}
    pack $id.buttonframe.ok -side left -expand 1
    
    $id.name.entry select from 0
    $id.name.entry select adjust end
    focus $id.name.entry
}