Viewing contents of file '../idllib/contrib/tappin/graffer/graff_enter.pro'
;+
; GRAFF_ENTER
; A labeled text entry field
;
; Usage:
; id = graff_enter(parent, ...)
;
; Return:
; id long The ID of the compound widget
;
; Argument:
; parent long input The ID of the base in which the widget
; will sit.
;
; Keywords:
; label string input The label to be attached to the entry box
; value ... input The initial value of the widget
; uvalue ... input A user-value for the compound.
; floating input If set then the values are floating point
; integer input If set then the values are short
; integers
; long_int input If set then the values are long
; integers
; text input If set, then the values are text
; strings (default action)
; format string input The format for displaying the value.
; xsize int input The size of the text input box (chars)
; ysize int input The number of rows in the box
; column input If set then put the label above the
; text box (default is to the left)
; frame input If set, then put a box around the
; whole compound
; box input If set, then put a box around the text
; field.
; all_events input If set, then return all events except
; selection events
; no_event input If set, then don't return events at
; all.
; select_events input If set and all_events is set, then
; even return selection events
; tracking_events input If set, then enable cursor tracking
; events in the text window.
; capture_focus input If set, then putting the cursor into
; the text-box gives the focus to the widget.
; array_valued input If set, then the widget can accept &
; return an array of values (normally
; only scalar values are accepted)
; scroll input If set then make the text widget a
; scrolling widget.
; graphics input If set and this is a text input box,
; don't return strings ending in a
; single pling "!" (To avoid hershey
; character errors).
;
; Restrictions:
; If the text window does not contain a valid value for the
; given type, then the null string is returned by a get_value
; call.
;
; History:
; Original: 25/8/95; SJT
; use decoders rather than internal reads: 29/8/95; SJT
; Add tracking_events key: 4/12/95; SJT
; Add array_valued and scroll keys: 9/12/96; SJT
; Modify handler so tracking events can be returned by
; "non-editable" or "non-event" widgets: 14/1/97; SJT
; Add CAPTURE_FOCUS key: 6/2/97; SJT
; Add GRAPHICS key: 12/2/97; SJT
; Put in "event backlog" trapping to prevent the multiple
; updating of the plot when a title is typed rapidly: 3/7/97; SJT
;-
function Grf_cvt_int, txt, long_int=long_int, valid=valid
; Convert a text string to an integer or a long
valid = 0b
text = strtrim(txt, 2)
msp = strpos(text, '-') ; look for - signs
if (msp eq 0) then begin
neg = -1
text = strmid(text, 1, strlen(text))
endif else begin
neg = 1
if (strpos(text, '+') eq 0) then $
text = strmid(text, 1, strlen(text))
endelse
if (strlen(text) eq 0) then return, 0
if (keyword_set(long_int)) then ivals = 0l $
else ivals = 0
zero = (byte('0'))(0)
ba = byte(text)-zero
if (max(ba) ge 10) then return, 0 ; Bad values in string
if (keyword_set(long_int)) then idx = $
10l^reverse(indgen(n_elements(ba))) $
else idx = 10^reverse(indgen(n_elements(ba)))
for j = 0, n_elements(ba)-1 do ivals = ivals + ba(j)*idx(j)
valid = 1b
return, ivals*neg
end
function Grf_cvt_float, txt, valid=valid
; Convert a text string into a floating point value
valid = 0b
text = strlowcase(strtrim(txt, 2)) ; lowercase it as well as trimming
; it to simplify searching for
; exponents.
; Sort out and split off exponents first (E and D forms
; recognized)
sp = strpos(text, 'e')
if (sp eq -1)then sp = strpos(text, 'd')
if (sp ne -1) then begin
ch = strmid(text, sp+1, strlen(text))
text = strmid(text, 0, sp)
ich = grf_cvt_int(ch, valid = ok)
if (not ok) then return, 0. ; A bad exponent give up here & now
endif else ich = 0
msp = strpos(text, '-') ; look for - signs
if (msp eq 0) then begin
neg = -1.
text = strmid(text, 1, strlen(text))
endif else neg = 1.
sp = strpos(text, '.')
if (sp ne -1) then begin
dc = strmid(text, sp+1, strlen(text))
text = strmid(text, 0, sp)
endif else dc = ''
if (sp ne 0) then ifp = grf_cvt_int(text, /long, valid = ok) $
else begin
ifp = 0l
ok = 1b
endelse
if (not ok) then return, 0. ; A bad pre-decimal give up here & now
if (strlen(dc) ne 0) then iap = grf_cvt_int(dc, /long, valid = ok) $
else begin
iap = 0l
ok = 1b
endelse
if (not ok) then return, 0. ; A bad post-decimal give up here & now
valid = 1b
return, neg * (float(ifp) + float(iap)/10.^strlen(dc)) * 10.^ich
end
pro Grf_focus_enter, id
; Set input focus to the text widget
; id.
base = widget_info(id, /child)
widget_control, base, get_uvalue = state, /no_copy
widget_control, state.text, /input_focus
widget_control, base, set_uvalue = state, /no_copy
end
pro Grf_set_enter, id, value
; Set the value of a graff_enter
; widget
base = widget_info(id, /child)
widget_control, base, get_uvalue = state, /no_copy
on_ioerror, no_set
if (not state.array) then v1 = value(0) $
else v1 = value
sv = size(v1)
if (sv(sv(0)+1) ne state.type) then case state.type of
4: vv = float(v1)
2: vv = fix(v1)
3: vv = long(v1)
7: vv = strtrim(string(v1, /print), 2)
Else: message, 'Unknown entry field type'
endcase else vv = v1
vv = string(vv, format = state.format)
widget_control, state.text, set_value = vv, set_text_select = $
strlen(vv(0))
widget_control, base, set_uvalue = state, /no_copy
return
No_set:
widget_control, base, set_uvalue = state, /no_copy
message, /continue, "Could not convert value to appropriate type."
end
function Grf_get_enter, id
; Get the value of a graff_enter
; widget
base = widget_info(id, /child)
widget_control, base, get_uvalue = state, /no_copy
widget_control, state.text, get_value = txt
if (not state.array) then txt = txt(0)
ivv = bytarr((nv0 = n_elements(txt)))
case state.type of
4: begin ; Float
val = fltarr(nv0)
for j = 0, nv0-1 do begin
v0 = grf_cvt_float(txt(j), valid = ok)
if (ok) then begin
val(j) = v0
ivv(j) = 1b
endif
endfor
end
2: begin ; Int
val = intarr(nv0)
for j = 0, nv0-1 do begin
v0 = grf_cvt_int(txt(j), valid = ok)
if (ok) then begin
val(j) = v0
ivv(j) = 1b
endif
endfor
end
3: begin ; Long
val = lonarr(nv0)
for j = 0, nv0-1 do begin
v0 = grf_cvt_int(txt(j), /long, valid = ok)
if (ok) then begin
val(j) = v0
ivv(j) = 1b
endif
endfor
end
7: begin ; Text
val = txt
if (state.graph) then for j = 0, nv0-1 do $
ivv(j) = (strmid(txt(j), strlen(txt(j))-1, 1) ne '!') or $
(strmid(txt(j), strlen(txt(j))-2, 2) eq '!!') $
else ivv(*) = 1b
end
Else: message, 'Unknown entry field type'
endcase
; Only return "valid" values. If there are no valid values then
; return a null string for numeric types and zero for text types
; (this allows a test that the type is right to test if a proper
; value is present!)
locs = where(ivv, nv)
if (nv gt 0) then val = val(locs) $
else if (state.type eq 7) then val = 0 $
else val = ''
if (nv eq 1) then val = val(0) ; Make single value a
; scalar
widget_control, base, set_uvalue = state, /no_copy
return, val
end
function Grf_enter_ev, event
; Process events from a graff_enter
; widget
if (event.id eq 0l) then return, 0l
base = widget_info(event.handler, /child)
widget_control, base, get_uvalue = state, /no_copy
e_type = tag_names(event, /structure_name)
if (e_type eq 'WIDGET_TRACKING') then begin
trkopt = state.track
if ((trkopt and 2b) ne 0 and event.enter) then $
widget_control, state.text, /input_focus
widget_control, base, set_uvalue = state, /no_copy
event.id = event.handler
event.handler = 0l
if (trkopt) then return, event $
else return, 0l
endif
if (state.dead) then begin ; Not returning events
widget_control, base, set_uvalue = state, /no_copy
return, 0l ; Dummy return
endif
if (event.type eq 3 and not state.select) then begin
widget_control, base, set_uvalue = state, /no_copy
return, 0l ; Dummy return
endif
; This piece of code isn't as silly as
; it looks! The UVALUE of base is used
; in the GET_VALUE routine!
widget_control, base, set_uvalue = state, /no_copy
widget_control, event.handler, get_value = val
widget_control, base, get_uvalue = state, /no_copy
sv = size(val)
if (sv(sv(0)+1) ne state.type) then begin
; Value wasn't valid don't return
; anything
widget_control, base, set_uvalue = state, /no_copy
return, 0l ; Dummy return
endif
cr = 0b
if (event.type eq 0) then if (event.ch eq 10b) then cr = 1b $
else begin
widget_control, base, set_uvalue = state, /no_copy
new_event = widget_event(event.handler, /nowait)
widget_control, base, get_uvalue = state, /no_copy
endelse
ev = { $
Id:event.handler, $
Top:event.top, $
Handler:event.handler, $
Value:val, $
cr:cr, $
Type:state.type $
}
widget_control, base, set_uvalue = state, /no_copy
return, ev
end
function Graff_enter, parent, label=label, value=value, uvalue=uvalue, $
floating=floating, integer=integer, text=text, $
long_int=long_int, $
format=format, xsize=xsize, ysize=ysize, $
column=column, frame=frame, box=box, $
all_events=all_events, no_events=no_events, $
select_events=select_events, display=display, $
tracking_events=tracking_events, $
array_valued=array_valued, scroll=scroll, $
capture_focus=capture_focus, graphics=graphics
; First step: check that unset keys
; are set to something if needed.
if (n_elements(label) eq 0) then label = 'Value:'
if (n_elements(ysize) eq 0) then ysize = 1
if (n_elements(xsize) eq 0) then xsize = 0
if (n_elements(uvalue) eq 0) then uvalue = 0
if (n_elements(frame) eq 0) then frame = 0
if (n_elements(box) eq 0) then box = 0
all = keyword_set(all_events) and (not keyword_set(no_events))
if (keyword_set(display)) then edit = 0b $
else edit = 1b
; Set states according to the type
sv = size(value)
if (keyword_set(floating)) then begin
if (not keyword_set(format)) then format = "(g10.3)"
vtype = 4 ; Use the codes from SIZE for
; consistency
if (n_elements(value) eq 0) then value = 0.0
endif else if (keyword_set(integer)) then begin
if (not keyword_set(format)) then format = "(I0)"
vtype = 2
if (n_elements(value) eq 0) then value = 0
endif else if (keyword_set(long_int)) then begin
if (not keyword_set(format)) then format = "(I0)"
vtype = 3
if (n_elements(value) eq 0) then value = 0l
endif else begin ; No key is the same as /text
if (not keyword_set(format)) then format = "(A)"
vtype = 7
if (n_elements(value) eq 0) then value = ''
endelse
; Define the heirarchy
; This is the top-level base which the
; user will see
if (n_elements(parent) eq 0) then tlb = widget_base(uvalue = uvalue) $
else tlb = widget_base(parent, uvalue = uvalue)
; This is the base to contain the
; label and text box
if (keyword_set(column)) then $
base = widget_base(tlb, /column, frame = frame) $
else base = widget_base(tlb, /row, frame = frame)
junk = widget_label(base, value = label)
tbox = widget_text(base, edit = edit, all_events = all, frame = box, $
xsize = xsize, ysize = ysize, tracking_events = $
keyword_set(tracking_events) or $
keyword_set(capture_focus), scroll = $
keyword_set(scroll))
state = { $
Text: tbox, $
Dead: keyword_set(no_events) or keyword_set(display), $
Type: vtype, $
Format: format, $
Track: keyword_set(tracking_events) or $
2b*keyword_set(capture_focus), $
Select: keyword_set(select_events), $
Array: keyword_set(array_valued), $
Graph: keyword_set(graphics) and (vtype eq 7) $
}
widget_control, base, set_uvalue = state, /no_copy
widget_control, tlb, event_func = 'grf_enter_ev', func_get_value = $
'grf_get_enter', pro_set_value = 'grf_set_enter'
widget_control, tlb, set_value = value
return, tlb
end