summaryrefslogtreecommitdiff
path: root/ipl/gpacks/vib/vibradio.icn
blob: b164594df044ec676adb64f11ddba945c6ef221f (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
############################################################################
#
#  vibradio.icn -- procedures for defining a radio button object
#
############################################################################
#
#   This file is in the public domain.
#
############################################################################

$include "vibdefn.icn"

global RB_starty, RADIO_TALK, RADIO_VIDGET

##########################################################################
# radio_button_obj:
#    v       : vidget used for drawing radio button
#    proc    : name of user callback procedure
#    id      : unique means of identifying instance
#    x,y,w,h : bounding box
#    focus   : should focus lines be drawn around this object?
#    alts    : a list of button labels making up the radio button object
##########################################################################
record radio_button_obj(v, proc, id, x, y, w, h, focus, alts)

##########################################################################
# create_radio_button() creates a radio button instance and draws the
#                       button if it is a first class object.
##########################################################################
procedure create_radio_button(x, y, alts)
   local r, id

   id := next_id("radio_button")
   r := radio_button_obj(, "radio_button_cb" || id, "radio_button" || id,
                          x, y, 0, 0, 0, alts)
   r.v := Vradio_buttons(ROOT, x, y, APPWIN, alts, , id, V_DIAMOND_NO)
   r.w := r.v.aw
   r.h := r.v.ah
   VRemove(ROOT, r.v, 1)
   return r
end

##########################################################################
# update_radio_bb() disallows resizing of a radio button object.
##########################################################################
procedure update_radio_bb(object)
   object.w := object.v.aw
   object.h := object.v.ah
end

##########################################################################
# draw_radio_button() draws the given radio button object.
##########################################################################
procedure draw_radio_button(r)
   VDraw(r.v)
   return r
end

##########################################################################
# load_radio_button() restores a radio button object from session code.
##########################################################################
procedure load_radio_button(r, o)
   r.alts := o.etc
   r.v := Vradio_buttons(ROOT, r.x, r.y, APPWIN, r.alts, , r.id, V_DIAMOND_NO)
   r.w := r.v.aw
   r.h := r.v.ah
   VRemove(ROOT, r.v, 1)
end

##########################################################################
# save_radio_button() augments the record for saving a radio_button object.
##########################################################################
procedure save_radio_button(r, o)
   r.typ := "Choice"
   r.num := *o.alts
   r.etc := copy(o.alts)
   return
end

##########################################################################
# radio_button_atts() defines the attribute sheet template for a radio
#                     button object.
##########################################################################
procedure radio_button_atts()
   local tempy

   RADIO_TALK := Vdialog(&window, PAD, PAD)
   tempy := 0
   VRegister(RADIO_TALK,
      Vtext(&window, "ID:       ",, 1, TEXTCHARS, IDMASK), 0, tempy)
   tempy +:= PAD
   VRegister(RADIO_TALK,
      Vtext(&window, "callback: ",, 3, TEXTCHARS, CBMASK), 0, tempy)
   tempy +:= (3 * PAD)/2
   VRegister(RADIO_TALK, Vtext(&window, "       x: ",, 4, 3, &digits), 0, tempy)
   tempy +:= PAD
   VRegister(RADIO_TALK, Vtext(&window, "       y: ",, 5, 3, &digits), 0, tempy)
   VFormat(RADIO_TALK)
   RB_starty := tempy
end

##########################################################################
# display_radio_button_atts() displays the attribute sheet with the current
#                             attributes for the given radio button instance.
##########################################################################
procedure display_radio_button_atts(object)
   local tempy, i, send_data, data, new, v, ok, nok, reg_list, ins_list, l
   initial radio_button_atts()

   new := copy(object)
   new.y -:= CANVASY
   new.alts := copy(object.alts)

   repeat {
      reg_list := []
      ins_list := []
      tempy := RB_starty

      # construct text fields and "add" and "del" buttons
      every i := 0 to *new.alts do {
         tempy +:= PAD
         v := Vbutton(&window, "add", radio_cb, V_OK, , 28, 17)
         VInsert(RADIO_TALK, v, 0, tempy + PAD / 2)
         put(ins_list, v)
         if i = 0 then
            next
         v := Vbutton(&window, "del", radio_cb, V_OK, , 28, 17)
         VInsert(RADIO_TALK, v, 35 + TEXTWIDTH, tempy + 1)
         put(ins_list, v)
         v := Vtext(&window, "", , 5 + i, TEXTCHARS, LBMASK)
         VRegister(RADIO_TALK, v, 35, tempy)
         put(reg_list, v)
         }

      # add "Okay" and "Cancel"
      tempy +:= 2 * PAD
      ok  := Vbutton(&window, "Okay", , V_OK, , 50, 30)
      nok := Vbutton(&window, "Cancel", , V_CANCEL, , 50, 30)
      VInsert(RADIO_TALK, ok, TEXTWIDTH / 2 - 30, tempy)
      VInsert(RADIO_TALK, nok, TEXTWIDTH / 2 + 40, tempy)
      put(ins_list, ok, nok)

      # post the dialog
      RADIO_VIDGET := &null
      VFormat(RADIO_TALK)
      send_data := [new.id, new.proc, new.x, new.y] ||| new.alts
      data := VOpenDialog(RADIO_TALK, , "radio_dialog", send_data, "Okay")
      every VUnregister(RADIO_TALK, !reg_list)
      every VRemove(RADIO_TALK, !ins_list, 1)

      if data === send_data then
         fail				# cancelled

      # save new values
      new.id    := strip(get(data))
      new.proc  := strip(get(data))
      new.x     := get(data)
      new.y     := get(data)
      every !new.alts := get(data)

      # if "add" or "del" was pressed, process it and loop to re-post dialog
      if \RADIO_VIDGET then {
         l := []
         every v := reg_list[1 to *new.alts] do {
            if v.ay - PAD < RADIO_VIDGET.ay-1 < v.ay then
               put(l, "")
            if v.ay ~= RADIO_VIDGET.ay-1 then
               put(l, v.data)
         }
         if RADIO_VIDGET.ay-1 > reg_list[*new.alts].ay | *l = 0 then
            put(l, "")
         new.alts := l
         next
      }

      # check for legal field values
      if illegal(new.id, "ID", "s") |
         illegal(new.proc, "Callback", "p") |
         illegal(new.x, "X", "i") |
         illegal(new.y, "Y", "i")
      then
         next

      # everything is valid
      object.proc := new.proc
      object.id := new.id
      object.alts := new.alts

      unfocus_object(object)
      EraseArea(object.x, object.y, object.w, object.h)

      object.v := Vradio_buttons(ROOT,
         object.x, object.y, APPWIN, new.alts, , object.v.id, V_DIAMOND_NO)
      object.w := object.v.aw
      object.h := object.v.ah
      VRemove(ROOT, object.v, 1)

      move_object(object, new.x, new.y + CANVASY, object.w, object.h)
      focus_object(object)
      break
   }
end

##########################################################################
# radio_cb is called when an "add" or "del" button is pressed.
##########################################################################
procedure radio_cb(v)
   RADIO_VIDGET := v
end