1 | ;+ |
---|
2 | ; |
---|
3 | ; @file_comments |
---|
4 | ; |
---|
5 | ; @categories |
---|
6 | ; Compound widget |
---|
7 | ; |
---|
8 | ; @param ID |
---|
9 | ; |
---|
10 | ; @param VALUE |
---|
11 | ; It is the default tick mark value (a floating-point number). |
---|
12 | ; |
---|
13 | ; @returns |
---|
14 | ; |
---|
15 | ; @uses |
---|
16 | ; |
---|
17 | ; @restrictions |
---|
18 | ; |
---|
19 | ; @examples |
---|
20 | ; |
---|
21 | ; @history |
---|
22 | ; |
---|
23 | ; @version |
---|
24 | ; $Id$ |
---|
25 | ; |
---|
26 | ;- |
---|
27 | PRO cw_bgroup_setv, id, value |
---|
28 | ; |
---|
29 | compile_opt hidden, idl2, strictarrsubs |
---|
30 | ; |
---|
31 | ON_ERROR, 2 ;return to caller |
---|
32 | |
---|
33 | stash = WIDGET_INFO(id, /CHILD) |
---|
34 | WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY |
---|
35 | |
---|
36 | case state.type of |
---|
37 | 0: message,'unable to set plain button group value' |
---|
38 | 1: begin |
---|
39 | WIDGET_CONTROL, SET_BUTTON=0, state.ids[state.excl_pos] |
---|
40 | state.excl_pos = value |
---|
41 | WIDGET_CONTROL, /SET_BUTTON, state.ids[value] |
---|
42 | end |
---|
43 | 2: begin |
---|
44 | n = n_elements(value)-1 |
---|
45 | for i = 0, n do begin |
---|
46 | state.nonexcl_curpos[i] = value[i] |
---|
47 | WIDGET_CONTROL, state.ids[i], SET_BUTTON=value[i] |
---|
48 | endfor |
---|
49 | end |
---|
50 | endcase |
---|
51 | |
---|
52 | WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY |
---|
53 | end |
---|
54 | |
---|
55 | ;+ |
---|
56 | ; @file_comments |
---|
57 | ; Compound widget |
---|
58 | ; |
---|
59 | ; @categories |
---|
60 | ; |
---|
61 | ; @param ID |
---|
62 | ; |
---|
63 | ; @param VALUE |
---|
64 | ; It is the default tick mark value (a floating-point number). |
---|
65 | ; |
---|
66 | ; @returns |
---|
67 | ; |
---|
68 | ; @uses |
---|
69 | ; |
---|
70 | ; @restrictions |
---|
71 | ; |
---|
72 | ; @examples |
---|
73 | ; |
---|
74 | ; @history |
---|
75 | ; |
---|
76 | ; @version |
---|
77 | ; $Id$ |
---|
78 | ; |
---|
79 | ;- |
---|
80 | FUNCTION cw_bgroup_getv, id, value |
---|
81 | ; |
---|
82 | compile_opt hidden, idl2, strictarrsubs |
---|
83 | ; |
---|
84 | ON_ERROR, 2 ;return to caller |
---|
85 | |
---|
86 | stash = WIDGET_INFO(id, /CHILD) |
---|
87 | WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY |
---|
88 | |
---|
89 | case state.type of |
---|
90 | 0: message, 'unable to get plain button group value' |
---|
91 | ; 1: ret = state.excl_pos |
---|
92 | 1: ret = state.ret_arr[state.excl_pos] |
---|
93 | ; 2: ret = state.nonexcl_curpos |
---|
94 | 2: BEGIN |
---|
95 | index = where(state.nonexcl_curpos NE 0) |
---|
96 | if index[0] EQ -1 then begin |
---|
97 | if size(state.ret_arr, /type) EQ 7 then ret = '' ELSE ret = -1 |
---|
98 | ENDIF ELSE ret = state.ret_arr[index] |
---|
99 | END |
---|
100 | endcase |
---|
101 | |
---|
102 | WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY |
---|
103 | |
---|
104 | return, ret |
---|
105 | |
---|
106 | end |
---|
107 | ; |
---|
108 | ;+ |
---|
109 | ; |
---|
110 | ; @file_comments |
---|
111 | ; Compound widget |
---|
112 | ; |
---|
113 | ; @categories |
---|
114 | ; |
---|
115 | ; @param EV |
---|
116 | ; |
---|
117 | ; @returns |
---|
118 | ; |
---|
119 | ; @uses |
---|
120 | ; |
---|
121 | ; @restrictions |
---|
122 | ; |
---|
123 | ; @examples |
---|
124 | ; |
---|
125 | ; @history |
---|
126 | ; |
---|
127 | ; @version |
---|
128 | ; $Id$ |
---|
129 | ; |
---|
130 | ;- |
---|
131 | FUNCTION cw_bgroup_event, ev |
---|
132 | ; |
---|
133 | compile_opt hidden, idl2, strictarrsubs |
---|
134 | ; |
---|
135 | WIDGET_CONTROL, ev.handler, GET_UVALUE=stash |
---|
136 | WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY |
---|
137 | WIDGET_CONTROL, ev.id, get_uvalue=uvalue |
---|
138 | |
---|
139 | ret = 1 ;Assume we return a struct |
---|
140 | case state.type of |
---|
141 | 0: |
---|
142 | 1: if (ev.select eq 1) then begin |
---|
143 | state.excl_pos = uvalue |
---|
144 | ENDIF else begin |
---|
145 | if (state.no_release ne 0) then ret = 0 |
---|
146 | ENDELSE |
---|
147 | 2: begin |
---|
148 | ; Keep track of the current state |
---|
149 | state.nonexcl_curpos[uvalue] = ev.select |
---|
150 | if (state.no_release ne 0) and (ev.select eq 0) then ret = 0 |
---|
151 | end |
---|
152 | endcase |
---|
153 | |
---|
154 | if ret then begin ;Return a struct? |
---|
155 | ret = { ID:state.base, TOP:ev.top, HANDLER:0L, SELECT:ev.select, $ |
---|
156 | VALUE:state.ret_arr[uvalue] } |
---|
157 | efun = state.efun |
---|
158 | WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY |
---|
159 | if efun ne '' then return, CALL_FUNCTION(efun, ret) $ |
---|
160 | else return, ret |
---|
161 | endif else begin ;Trash the event |
---|
162 | WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY |
---|
163 | return, 0 |
---|
164 | endelse |
---|
165 | end |
---|
166 | ; |
---|
167 | ;+ |
---|
168 | ; @file_comments |
---|
169 | ; CW_BGROUP is a compound widget that simplifies creating |
---|
170 | ; a base of buttons. It handles the details of creating the |
---|
171 | ; proper base (standard, exclusive, or non-exclusive) and filling |
---|
172 | ; in the desired buttons. Events for the individual buttons are |
---|
173 | ; handled transparently, and a CW_BGROUP event returned. This |
---|
174 | ; event can return any one of the following: |
---|
175 | ; - The Index of the button within the base. |
---|
176 | ; - The widget ID of the button. |
---|
177 | ; - The name of the button. |
---|
178 | ; - An arbitrary value taken from an array of User values. |
---|
179 | ; |
---|
180 | ; @categories |
---|
181 | ; Compound widget |
---|
182 | ; |
---|
183 | ; @param PARENT {in}{required} |
---|
184 | ; The ID of the parent widget. |
---|
185 | ; |
---|
186 | ; @param NAMES {type=string array} |
---|
187 | ; A string array, containing one string per button, |
---|
188 | ; giving the name of each button. |
---|
189 | ; |
---|
190 | ; @keyword BUTTON_UVALUE {type=array} |
---|
191 | ; An array of user values to be associated with |
---|
192 | ; each button and returned in the event structure. |
---|
193 | ; |
---|
194 | ; @keyword COLUMN |
---|
195 | ; Buttons will be arranged in the number of columns |
---|
196 | ; specified by this keyword. |
---|
197 | ; |
---|
198 | ; @keyword EVENT_FUNCT |
---|
199 | ; The name of an optional user-supplied event function |
---|
200 | ; for buttons. This function is called with the return |
---|
201 | ; value structure whenever a button is pressed, and |
---|
202 | ; follows the conventions for user-written event functions. |
---|
203 | ; |
---|
204 | ; @keyword EXCLUSIVE |
---|
205 | ; Buttons will be placed in an exclusive base, with |
---|
206 | ; only one button allowed to be selected at a time. |
---|
207 | ; |
---|
208 | ; @keyword FONT |
---|
209 | ; The name of the font to be used for the button |
---|
210 | ; titles. If this keyword is not specified, the default |
---|
211 | ; font is used. |
---|
212 | ; |
---|
213 | ; @keyword FRAME |
---|
214 | ; Specifies the width of the frame to be drawn around the base. |
---|
215 | ; |
---|
216 | ; @keyword IDS |
---|
217 | ; A named variable into which the button IDs will be |
---|
218 | ; stored, as a longword vector. |
---|
219 | ; |
---|
220 | ; @keyword LABEL_LEFT |
---|
221 | ; Creates a text label to the left of the buttons. |
---|
222 | ; |
---|
223 | ; @keyword LABEL_TOP |
---|
224 | ; Creates a text label above the buttons. |
---|
225 | ; |
---|
226 | ; @keyword MAP |
---|
227 | ; If set, the base will be mapped when the widget |
---|
228 | ; is realized (the default). |
---|
229 | ; |
---|
230 | ; @keyword NONEXCLUSIVE |
---|
231 | ; Buttons will be placed in an non-exclusive base. |
---|
232 | ; The buttons will be independent. |
---|
233 | ; |
---|
234 | ; @keyword NO_RELEASE |
---|
235 | ; If set, button release events will not be returned. |
---|
236 | ; |
---|
237 | ; @keyword RETURN_ID |
---|
238 | ; If set, the VALUE field of returned events will be |
---|
239 | ; the widget ID of the button. |
---|
240 | ; |
---|
241 | ; @keyword RETURN_INDEX |
---|
242 | ; If set, the VALUE field of returned events will be |
---|
243 | ; the zero-based index of the button within the base. |
---|
244 | ; THIS IS THE DEFAULT. |
---|
245 | ; |
---|
246 | ; @keyword RETURN_NAME |
---|
247 | ; If set, the VALUE field of returned events will be |
---|
248 | ; the name of the button within the base. |
---|
249 | ; |
---|
250 | ; @keyword ROW |
---|
251 | ; Buttons will be arranged in the number of rows |
---|
252 | ; specified by this keyword. |
---|
253 | ; |
---|
254 | ; @keyword SCROLL |
---|
255 | ; If set, the base will include scroll bars to allow |
---|
256 | ; viewing a large base through a smaller viewport. |
---|
257 | ; |
---|
258 | ; @keyword SET_VALUE |
---|
259 | ; The initial value of the buttons. This is equivalent |
---|
260 | ; to the later statement: |
---|
261 | ; |
---|
262 | ; WIDGET_CONTROL, widget, set_value=value |
---|
263 | ; |
---|
264 | ; @keyword SPACE |
---|
265 | ; The space, in pixels, to be left around the edges |
---|
266 | ; of a row or column major base. This keyword is |
---|
267 | ; ignored if EXCLUSIVE or NONEXCLUSIVE are specified. |
---|
268 | ; |
---|
269 | ; @keyword UVALUE |
---|
270 | ; The user value to be associated with the widget. |
---|
271 | ; |
---|
272 | ; @keyword UNAME |
---|
273 | ; The user name to be associated with the widget. |
---|
274 | ; |
---|
275 | ; @keyword XOFFSET |
---|
276 | ; The X offset of the widget relative to its parent. |
---|
277 | ; |
---|
278 | ; @keyword XPAD |
---|
279 | ; The horizontal space, in pixels, between children |
---|
280 | ; of a row or column major base. Ignored if EXCLUSIVE |
---|
281 | ; or NONEXCLUSIVE are specified. |
---|
282 | ; |
---|
283 | ; @keyword XSIZE |
---|
284 | ; The width of the base. |
---|
285 | ; @keyword X_SCROLL_SIZE |
---|
286 | ; The width of the viewport if SCROLL is specified. |
---|
287 | ; |
---|
288 | ; @keyword YOFFSET |
---|
289 | ; The Y offset of the widget relative to its parent. |
---|
290 | ; |
---|
291 | ; @keyword YPAD |
---|
292 | ; The vertical space, in pixels, between children of |
---|
293 | ; a row or column major base. Ignored if EXCLUSIVE |
---|
294 | ; or NONEXCLUSIVE are specified. |
---|
295 | ; |
---|
296 | ; @keyword YSIZE |
---|
297 | ; The height of the base. |
---|
298 | ; |
---|
299 | ; @keyword Y_SCROLL_SIZE |
---|
300 | ; The height of the viewport if SCROLL is specified. |
---|
301 | ; |
---|
302 | ; @returns |
---|
303 | ; The ID of the created widget is returned. |
---|
304 | ; |
---|
305 | ; @restrictions |
---|
306 | ; This widget generates event structures with the following definition: |
---|
307 | ; |
---|
308 | ; event = { ID:0L, TOP:0L, HANDLER:0L, SELECT:0, VALUE:0 } |
---|
309 | ; |
---|
310 | ; The SELECT field is passed through from the button event. VALUE is |
---|
311 | ; either the INDEX, ID, NAME, or BUTTON_UVALUE of the button, |
---|
312 | ; depending on how the widget was created. |
---|
313 | ; |
---|
314 | ; @restrictions |
---|
315 | ; Only buttons with textual names are handled by this widget. |
---|
316 | ; Bitmaps are not understood. |
---|
317 | ; |
---|
318 | ; @history |
---|
319 | ; 15 June 1992, AB |
---|
320 | ; 7 April 1993, AB, Removed state caching. |
---|
321 | ; 6 Oct. 1994, KDB, Font keyword is not applied to the label. |
---|
322 | ; 10 FEB 1995, DJC fixed bad bug in event procedure, getting |
---|
323 | ; id of stash widget. |
---|
324 | ; 11 April 1995, AB Removed Motif special cases. |
---|
325 | ; |
---|
326 | ; Copyright (c) 1992-2005, Research Systems, Inc. All rights reserved. |
---|
327 | ; Unauthorized reproduction prohibited. |
---|
328 | ; |
---|
329 | ; @version |
---|
330 | ; $Id$ |
---|
331 | ; |
---|
332 | ;- |
---|
333 | FUNCTION cw_bgroup, parent, names, $ |
---|
334 | BUTTON_UVALUE=button_uvalue, COLUMN=column, EVENT_FUNCT=efun, $ |
---|
335 | EXCLUSIVE=excl, FONT=font, FRAME=frame, IDS=ids, LABEL_TOP=label_top, $ |
---|
336 | LABEL_LEFT=label_left, MAP=map, $ |
---|
337 | NONEXCLUSIVE=nonexcl, NO_RELEASE=no_release, RETURN_ID=return_id, $ |
---|
338 | RETURN_INDEX=return_index, RETURN_NAME=return_name, $ |
---|
339 | ROW=row, SCROLL=scroll, SET_VALUE=sval, SPACE=space, $ |
---|
340 | TAB_MODE=tab_mode, UVALUE=uvalue, $ |
---|
341 | XOFFSET=xoffset, XPAD=xpad, XSIZE=xsize, X_SCROLL_SIZE=x_scroll_size,$ |
---|
342 | YOFFSET=yoffset, YPAD=ypad, YSIZE=ysize, Y_SCROLL_SIZE=y_scroll_size, $ |
---|
343 | UNAME=uname |
---|
344 | ; |
---|
345 | compile_opt hidden, idl2, strictarrsubs |
---|
346 | ; |
---|
347 | IF (N_PARAMS() ne 2) THEN ras = report('Incorrect number of arguments') |
---|
348 | |
---|
349 | ON_ERROR, 2 ;return to caller |
---|
350 | |
---|
351 | ; Set default values for the keywords |
---|
352 | version = WIDGET_INFO(/version) |
---|
353 | if (version.toolkit eq 'OLIT') then def_space_pad = 4 else def_space_pad = 3 |
---|
354 | IF (N_ELEMENTS(column) eq 0) then column = 0 |
---|
355 | IF (N_ELEMENTS(excl) eq 0) then excl = 0 |
---|
356 | IF (N_ELEMENTS(frame) eq 0) then frame = 0 |
---|
357 | IF (N_ELEMENTS(map) eq 0) then map=1 |
---|
358 | IF (N_ELEMENTS(nonexcl) eq 0) then nonexcl = 0 |
---|
359 | IF (N_ELEMENTS(no_release) eq 0) then no_release = 0 |
---|
360 | IF (N_ELEMENTS(row) eq 0) then row = 0 |
---|
361 | IF (N_ELEMENTS(scroll) eq 0) then scroll = 0 |
---|
362 | IF (N_ELEMENTS(space) eq 0) then space = def_space_pad |
---|
363 | IF (N_ELEMENTS(uname) eq 0) then uname = 'CW_BGROUP_UNAME' |
---|
364 | IF (N_ELEMENTS(uvalue) eq 0) then uvalue = 0 |
---|
365 | IF (N_ELEMENTS(xoffset) eq 0) then xoffset=0 |
---|
366 | IF (N_ELEMENTS(xpad) eq 0) then xpad = def_space_pad |
---|
367 | IF (N_ELEMENTS(xsize) eq 0) then xsize = 0 |
---|
368 | IF (N_ELEMENTS(x_scroll_size) eq 0) then x_scroll_size = 0 |
---|
369 | IF (N_ELEMENTS(yoffset) eq 0) then yoffset=0 |
---|
370 | IF (N_ELEMENTS(ypad) eq 0) then ypad = def_space_pad |
---|
371 | IF (N_ELEMENTS(ysize) eq 0) then ysize = 0 |
---|
372 | IF (N_ELEMENTS(y_scroll_size) eq 0) then y_scroll_size = 0 |
---|
373 | |
---|
374 | top_base = 0L |
---|
375 | if (n_elements(label_top) ne 0) then begin |
---|
376 | next_base = WIDGET_BASE(parent, XOFFSET=xoffset, YOFFSET=yoffset, /COLUMN) |
---|
377 | if(keyword_set(font))then $ |
---|
378 | junk = WIDGET_LABEL(next_base, value=label_top,font=font) $ |
---|
379 | else junk = WIDGET_LABEL(next_base, value=label_top) |
---|
380 | top_base = next_base |
---|
381 | endif else next_base = parent |
---|
382 | |
---|
383 | if (n_elements(label_left) ne 0) then begin |
---|
384 | next_base = WIDGET_BASE(next_base, XOFFSET=xoffset, YOFFSET=yoffset, /ROW) |
---|
385 | if(keyword_set(font))then $ |
---|
386 | junk = WIDGET_LABEL(next_base, value=label_left, font=font) $ |
---|
387 | else junk = WIDGET_LABEL(next_base, value=label_left) |
---|
388 | if (top_base eq 0L) then top_base = next_base |
---|
389 | endif |
---|
390 | ; We need some kind of outer base to hold the users UVALUE |
---|
391 | if (top_base eq 0L) then begin |
---|
392 | top_base = WIDGET_BASE(parent, XOFFSET=xoffset, YOFFSET=yoffset) |
---|
393 | next_base = top_base |
---|
394 | endif |
---|
395 | If (top_base EQ next_base) THEN $ |
---|
396 | next_base = WIDGET_BASE(top_base, Xpad=1, Ypad=1, Space=1) |
---|
397 | |
---|
398 | ; Set top level base attributes |
---|
399 | WIDGET_CONTROL, top_base, MAP=map, $ |
---|
400 | FUNC_GET_VALUE='CW_BGROUP_GETV', PRO_SET_VALUE='CW_BGROUP_SETV', $ |
---|
401 | SET_UVALUE=uvalue, SET_UNAME=uname |
---|
402 | |
---|
403 | ; Tabbing |
---|
404 | if (n_elements(tab_mode) ne 0) then begin |
---|
405 | WIDGET_CONTROL, top_base, TAB_MODE=tab_mode |
---|
406 | WIDGET_CONTROL, next_base, TAB_MODE=tab_mode |
---|
407 | end |
---|
408 | |
---|
409 | ; The actual button holding base |
---|
410 | base = WIDGET_BASE(next_base, COLUMN=column, EXCLUSIVE=excl, FRAME=frame, $ |
---|
411 | NONEXCLUSIVE=nonexcl, ROW=row, SCROLL=scroll, SPACE=space, $ |
---|
412 | XPAD=xpad, XSIZE=xsize, X_SCROLL_SIZE=x_scroll_size, $ |
---|
413 | YPAD=ypad, YSIZE=ysize, Y_SCROLL_SIZE=y_scroll_size, $ |
---|
414 | EVENT_FUNC='CW_BGROUP_EVENT', $ |
---|
415 | UVALUE=WIDGET_INFO(top_base, /child)) |
---|
416 | |
---|
417 | n = n_elements(names) |
---|
418 | ids = lonarr(n) |
---|
419 | for i = 0, n-1 do begin |
---|
420 | if (n_elements(font) eq 0) then begin |
---|
421 | ids[i] = WIDGET_BUTTON(base, value=names[i], UVALUE=i, $ |
---|
422 | UNAME=uname+'_BUTTON'+STRTRIM(i,2)) |
---|
423 | endif else begin |
---|
424 | ids[i] = WIDGET_BUTTON(base, value=names[i], FONT=font, $ |
---|
425 | UVALUE=i, UNAME=uname+'_BUTTON'+STRTRIM(i,2)) |
---|
426 | endelse |
---|
427 | endfor |
---|
428 | |
---|
429 | ; Keep the state info in the real (inner) base UVALUE. |
---|
430 | ; Pick an event value type: |
---|
431 | ; 0 - Return ID |
---|
432 | ; 1 - Return INDEX |
---|
433 | ; 2 - Return NAME |
---|
434 | ret_type = 1 |
---|
435 | if KEYWORD_SET(RETURN_ID) then ret_type = 0 |
---|
436 | if KEYWORD_SET(RETURN_NAME) then ret_type = 2 |
---|
437 | if KEYWORD_SET(BUTTON_UVALUE) then ret_type = 3 |
---|
438 | case ret_type of |
---|
439 | 0: ret_arr = ids |
---|
440 | 1: ret_arr = indgen(n) |
---|
441 | 2: ret_arr = names |
---|
442 | 3: ret_arr = button_uvalue |
---|
443 | endcase |
---|
444 | type = 0 |
---|
445 | if (excl ne 0) then type = 1 |
---|
446 | |
---|
447 | if (nonexcl ne 0) then type = 2 |
---|
448 | if n_elements(efun) le 0 then efun = '' |
---|
449 | state = { type:type, $ ; 0-Standard, 1-Exclusive, 2-Non-exclusive |
---|
450 | base: top_base, $ ; cw_bgroup base... |
---|
451 | ret_arr:ret_arr, $ ; Vector of event values |
---|
452 | efun : efun, $ ; Name of event fcn |
---|
453 | nonexcl_curpos:intarr(n), $ ; If non-exclus, tracks state |
---|
454 | excl_pos:0, $ ; If exclusive, current button |
---|
455 | ids:ids, $ ; Ids of buttons |
---|
456 | no_release:no_release } |
---|
457 | WIDGET_CONTROL, WIDGET_INFO(top_base, /CHILD), SET_UVALUE=state, /NO_COPY |
---|
458 | |
---|
459 | if (n_elements(sval) ne 0) then CW_BGROUP_SETV, top_base, sval |
---|
460 | |
---|
461 | return, top_base |
---|
462 | END |
---|