source: trunk/MESOSCALE/PLOT/MINIMAL/fsc/fsc_field.pro @ 205

Last change on this file since 205 was 85, checked in by aslmd, 14 years ago

LMD_MM_MARS et LMD_LES_MARS: ajout des routines IDL pour tracer les sorties --> voir mesoscale/PLOT

File size: 70.6 KB
Line 
1;+
2; NAME:
3;   FSC_FIELD
4;
5; PURPOSE:
6;
7;   The purpose of this compound widget is to provide an alternative
8;   to the CW_FIELD widget offered in the IDL distribution. One weakness
9;   of the CW_FIELD compound widget is that the text widgets do not
10;   look editable to the users on Windows platforms. This program
11;   corrects that deficiency and adds some features that I think
12;   will be helpful. For example, you can now assign an event handler
13;   to the compound widget, ask for positive numbers only, and limit
14;   the number of digits in a number, or the number of digits to the
15;   right of a decimal point. The program is written as a widget object,
16;   which allows the user to call object methods directly, affording
17;   even more flexibility in use. This program replaces the earlier
18;   programs FSC_INPUTFIELD and COYOTE_FIELD.
19;
20;   The program consists of a label widget next to a one-line text widget.
21;   The "value" of the compound widget is shown in the text widget. If the
22;   value is a number, it will not be possible (generally) to type
23;   alphanumeric values in the text widget. String values behave like
24;   strings in any one-line text widget.
25;
26; AUTHOR:
27;
28;   FANNING SOFTWARE CONSULTING
29;   David Fanning, Ph.D.
30;   1645 Sheely Drive
31;   Fort Collins, CO 80526 USA
32;   Phone: 970-221-0438
33;   E-mail: davidf@dfanning.com
34;   Coyote's Guide to IDL Programming: http://www.dfanning.com/
35;
36; CATEGORY:
37;
38;   General programming.
39;
40; TYPICAL CALLING SEQUENCE:
41;
42;   fieldID = FSC_FIELD(parent, Title="X Size:", Value=256, Object=fieldObject, Digits=3)
43;
44; INPUT PARAMETERS:
45;
46;   parent -- The parent widget ID of the compound widget. Required.
47;
48; INPUT KEYWORDS:
49;
50;   COLUMN        Set this keyword to have the Label widget above the Text widget.
51;                 The default is to have the Label widget in a row with the Text widget.
52;
53;   CR_ONLY       Set this keyword if you only want Carriage Return events returned to
54;                 your event handler. If this keyword is not set, all events are returned.
55;                 Setting this keyword has no effect unless either the EVENT_PRO or
56;                 EVENT_FUNC keyword is used.
57;
58;   DECIMAL       Set this keyword to the number of digits to the right of the decimal
59;                 point in floating point or double precision numbers. Ignored for STRING values.
60;
61;   DIGITS        Set this keyword to the number of digits permitted in integer numbers.
62;
63;   EVENT_FUNC    Set this keyword to the name of an event handler function. If this
64;                 keyword is undefined and the Event_Pro keyword is undefined,
65;                 all compound widget events are handled internally and not
66;                 passed on to the parent widget.
67;
68;   EVENT_PRO     Set this keyword to the name of an event handler procedure. If this
69;                 keyword is undefined and the Event_Func keyword is undefined,
70;                 all compound widget events are handled internally and not
71;                 passed on to the parent widget.
72;
73;   FIELDFONT     The font name for the text in the text widget.
74;
75;   FRAME         Set this keyword to put a frame around the compound widget.
76;
77;   FOCUS_EVENTS  Set this keyword to enable event generation for keyboard focus
78;                 events. Ignored unless EVENT_FUNC or EVENT_PRO keywords are specified.
79;
80;   HIGHLIGHT     Set this keyword to highlight the existing text if the widget gain
81;                 the keyboard focus. This keyword MUST be set for tabbing to work naturally
82;                 in IDL 6.2 and higher.
83;
84;   LABEL_LEFT    Set this keyword to align the text on the label to the left.
85;
86;   LABEL_RIGHT   Set this keyword to align the text on the label to the right.
87;
88;   LABELFONT     The font name for the text in the label widget.
89;
90;   LABELSIZE     The X screen size of the label widget.
91;
92;   NAME          A string containing the name of the object. The default is ''.
93;
94;   NOEDIT        Set this keyword to allow no user editing of the input text widget.
95;
96;   NONSENSITIVE  Set this keyword to make the input text widget non-sensitive.
97;
98;   POSITIVE      Set this keyword if you want only positive numbers allowed.
99;
100;   SCR_XSIZE     The X screen size of the compound widget.
101;
102;   SCR_YSIZE     The Y screen size of the compound widget.
103;
104;   TITLE         The string text placed on the label widget.
105;
106;   UNDEFINED     Set this keyword to the value to use for "undefined" values. If
107;                 not set, then !Value.F_NAN is used for numerical fields and a
108;                 NULL string is used for string fields. This applies to values
109;                 obtained with the GET_VALUE method or the GET_VALUE function.
110;
111;   UVALUE        A user value for any purpose.
112;
113;   VALUE         The "value" of the compound widget. Any type of integer, floating, or string
114;                 variable is allowed. The data "type" is determined automatically from the
115;                 value supplied with this keyword. Be sure you set the type appropriately for
116;                 your intended use of the value.
117;
118;   XSIZE         The X size of the text widget in the usual character units.
119;
120; OUTPUT KEYWORDS:
121;
122;   OBJECT        Set this keyword to a named variable to receive the compound widget's
123;                 object reference. This is required if you wish to call methods on the object.
124;                 Note that the object reference is also available in the event structure
125;                 generated by the widget object. Note that the object reference will be
126;                 necessary if you want to get or set values in the compound widget.
127;
128; COMMON BLOCKS:
129;
130;   None.
131;
132; RESTRICTIONS:
133;
134;   Requires DBLTOSTR from the Coyote Library:
135;      http://www.dfanning.com/programs/dbltostr.pro
136;
137; EVENT STRUCTURE:
138;
139;   All events are handled internally unless either the Event_Pro or Event_Func
140;   keywords are used to assign an event handler to the compound widget. By
141;   default all events generated by the text widget are passed to the assigned
142;   event handler. If you wish to receive only Carriage Return events, set the
143;   CR_Only keyword.
144;
145;   event = { FSC_FIELD_EVENT, $   ; The name of the event structure.
146;             ID: 0L, $            ; The ID of the compound widget's top-level base.
147;             TOP: 0L, $           ; The widget ID of the top-level base of the hierarchy.
148;             HANDLER: 0L, $       ; The event handler ID. Filled out by IDL.
149;             OBJECT: Obj_New(), $ ; The "self" object reference. Provided so you can call methods.
150;             VALUE: Ptr_New(), $  ; A pointer to the widget value.
151;             TYPE:""              ; A string indicating the type of data in the VALUE field.
152;           }
153;
154;   Note that if the field is "empty", the VALUE will be a pointer
155;   to an undefined variable. You should check this value before you
156;   use it. You code will look something like this:
157;
158;     IF N_Elements(*event.value) EQ 0 THEN $
159;         Print, 'Current Value UNDEFINED.' ELSE $
160;         Print, 'Current Value: ', *event.value
161;
162; GETTING and SETTING VALUES:
163;
164;   Almost all the properties of the widget can be obtained or set via
165;   the object's GetProperty and SetProperty methods (described below).
166;   Traditional compound widgets have the ability to get and set the "value"
167;   of the compound widget identifier (e.g., fieldID in the calling
168;   sequence above). Unfortunately, it is impossible to retreive a variable
169;   in this way when the variable is undefined. In practical terms, this
170;   means that the undefined variable must be set to *something*. You can
171;   determine what that something is with the UNDEFINED keyword, or I will set
172;   it to !VALUES.F_NAN for numerical fields and to the null string for string
173;   fields. In any case, you will have to check for undefined variables before
174;   you try to do something with the value. For a numerical field, the code
175;   might look something like this:
176;
177;      fieldID = FSC_FIELD(parent, Title="X Size:", Value=256, Object=fieldObject, Digits=3)
178;      currentValue = fieldObject->Get_Value()
179;      IF Finite(currentValue) EQ 0 THEN Print, 'Value is Undefined' ELSE Print, currentValue
180;
181;   Additional examples are provided in the numerical example fields in Example Program below.
182;
183;   Setting the value of the compound widget is the same as calling the Set_Value
184;   method on the object reference. In other words, these two statements are equivalent.
185;
186;        fieldObject->Set_Value, 45.4
187;        Widget_Control, fieldID, Set_Value=45.4
188;
189;   The data type of the value is determined from the value itself. Be sure you set it appropriately.
190;
191; OBJECT PROCEDURE METHODS:
192;
193;   GetProperty -- This method allows various properties of the widget to be
194;       returned via output keywords. The keywords that are available are:
195;
196;       CR_Only -- A flag, if set, means only report carriage return events.
197;       DataType -- The data type of the field variable.
198;       Decimal -- Set this keyword to the number of digits to the right of the decimal
199;              point in FLOATVALUE and DOUBLEVALUE numbers.
200;       Digits -- Set this keyword to the number of digits permitted in INTERGERVALUE and LONGVALUE numbers.
201;       Event_Func -- The name of the event handler function.
202;       Event_Pro -- The name of the event handler function.
203;       Has_Focus -- Set to 1 if the text widget currently has the keyboard focus.
204;       Highlight -- The highlight flag.
205;       NoEdit -- The NoEdit flag.
206;       NonSensitive -- The NonSensitive flag.
207;       Undefined -- The "value" of any undefined value.
208;       UValue -- The user value assigned to the compound widget.
209;       Value -- The "value" of the compound widget.
210;     Name -- A scalar string name of the object.
211;
212;   Resize -- This method allows you to resize the compound widget's text field.
213;        The value parameter is an X screen size for the entire widget. The text
214;        widget is sized by using the value obtained from this value minus the
215;        X screen size of the label widget.
216;
217;          objectRef->Resize, screen_xsize_value
218;
219;   Set_Value -- This method allows you to set the "value" of the field. It takes
220;       one positional parameter, which is the value.
221;
222;          objectRef->Set_Value, 5
223;
224;   SetProperty -- This method allows various properties of the widget to be
225;       set via input keywords. The keywords that are available are:
226;
227;       CR_Only -- Set this keyword if you only want Carriage Return events.
228;       Decimal -- Set this keyword to the number of digits to the right of the decimal
229;              point in FLOAT and DOUBLE numbers.
230;       Digits -- Set this keyword to the number of digits permitted in INTERGER and LONG numbers.
231;       Event_Func -- Set this keyword to the name of an Event Function.
232;       Event_Pro -- Set this keyword to the name of an Event Procedure.
233;       Highlight -- Set this keyword to highlight the existing text
234;                    when the widget gets the keyboard focus
235;       LabelSize --  The X screen size of the Label Widget.
236;       Name -- A scalar string name of the object. (default = '')
237;       NoEdit -- Set this keyword to make the text widget uneditable
238;       NonSensitive -- Set this keyword to make the widget nonsensitive
239;       Scr_XSize -- The X screen size of the text widget.
240;       Scr_YSize -- The Y screen size of the text widget.
241;       Title -- The text to go on the Label Widget.
242;       UValue -- A user value for any purpose.
243;       Value -- The "value" of the compound widget.
244;       XSize -- The X size of the Text Widget.
245;
246;   SetTabNext -- This method allows you to specify which field to go to when a TAB character
247;      is typed in the text widget. See the Example program below for an example of how to
248;      use this method.
249;
250; OBJECT FUNCTIONS METHODS:
251;
252;      Get_Value -- Returns the "value" of the field. No parameters. Will be undefined
253;          if a "number" field is blank. Should be checked before using:
254;
255;          IF N_Elements(objectRef->Get_Value()) NE 0 THEN Print, Value is: ', objectRef->Get_Value()
256;
257;      GetID -- Returns the widget identifier of the compound widget's top-level base.
258;         (The first child of the parent widget.) No parameters.
259;
260;      GetLabelSize -- Returns the X screen size of the label widget. No parameters.
261;
262;      GetTextID -- Returns the widget identifier of the compound widget's text widget.
263;         No parameters.
264;
265;      GetTextSize -- Returns the X screen size of the text widget. No parameters.
266;
267; PRIVATE OBJECT METHODS:
268;
269;   Although there is really no such thing as a "private" method in IDL's
270;   object implementation, some methods are used internally and not meant to
271;   be acessed publicly. Here are a few of those methods. I list them because
272;   it may be these private methods are ones you wish to override in subclassed
273;   objects.
274;
275;      MoveTab -- This method moves the focus to the widget identified in the "next" field,
276;        which must be set with the SetTabNext method. No parameters. Called automatically
277;        when a TAB character is typed in the text widget.
278;
279;      Text_Events -- The main event handler method for the compound widget. All
280;        text widget events are processed here.
281;
282;      ReturnValue -- This function method accepts a string input value and converts
283;        it to the type of data requested by the user.
284;
285;      Validate -- This function method examines all text input and removes unwanted
286;        characters, depending upon the requested data type for the field. It makes it
287;        impossible, for example, to type alphanumeric characters in an INTEGER field.
288;
289; EXAMPLE:
290;
291;   An example program is provided at the end of the FSC_FIELD code. To run it,
292;   type these commands:
293;
294;      IDL> .Compile FSC_Field
295;      IDL> Example
296;
297; MODIFICATION HISTORY:
298;
299;   Written by: David W. Fanning, 18 October 2000. Based heavily on an earlier
300;      FSC_INPUTFIELD program and new ideas about the best way to write
301;      widget objects.
302;   Added LABEL_LEFT, LABEL_RIGHT, and UNDEFINED keywords. 29 Dec 2000. DWF.
303;   Modified the way the value is returned in the GET_VALUE method and the
304;      GET_VALUE function. Modified Example program to demonstrate. 30 Dec 2000. DWF.
305;   Added NOEDIT and NONSENSITIVE keywords, with corresponding SETEDIT and SETSENNSITIVE
306;      methods. 19 Jan 2001. DWF.
307;   Actually followed through with the changes I _said_" I made 29 Dec 2000. (Don't ask....) 13 June 2001. DWF.
308;   Added GetTextSize and GetLabelSize methods for obtaining the X screen
309;      size of the text and label widgets, respectively. 21 July 2001. DWF.
310;   Fixed a problem in SetProperty method where I was setting self.xsize, which doesn't exist. 24 April 2002. DWF.
311;   Small modification to the SetEdit method. 6 August 2003. DWF.
312;   Added Highlight keyword. Ported Focus_Events keyword from
313;      fsc_inputfield.pro. Updated documentation. 17 November
314;      2004. DWF and Benjamin Hornberger
315;   Added Has_Focus keyword to the GetProperty method. 18 November
316;      2004. Benjamin Hornberger
317;   Fixed bug in GetProperty method (set value to *self.undefined if
318;      *self.value is undefined. 24 Feb 2004. Benjamin Hornberger
319;   Modified FOCUS_EVENTS keyword handling so that *all* focus events are now
320;      passed to specified event handlers. Check event.select to see if the
321;      widget is gaining or losing focus. 10 August 2005. DWF.
322;   Added new tabbing functionality, introduced in IDL 6.2. To use tabbing
323;      functionality natually, the HIGHTLIGHT keywords must be set.
324;      See included EXAMPLE program for details. 10 August 2005. DWF.
325;   Added functionality to covert double precision values to strings properly. 30 Nov 2005. DWF.
326;-
327;###########################################################################
328;
329; LICENSE
330;
331; This software is OSI Certified Open Source Software.
332; OSI Certified is a certification mark of the Open Source Initiative.
333;
334; Copyright © 1999-2005 Fanning Software Consulting
335;
336; This software is provided "as-is", without any express or
337; implied warranty. In no event will the authors be held liable
338; for any damages arising from the use of this software.
339;
340; Permission is granted to anyone to use this software for any
341; purpose, including commercial applications, and to alter it and
342; redistribute it freely, subject to the following restrictions:
343;
344; 1. The origin of this software must not be misrepresented; you must
345;    not claim you wrote the original software. If you use this software
346;    in a product, an acknowledgment in the product documentation
347;    would be appreciated, but is not required.
348;
349; 2. Altered source versions must be plainly marked as such, and must
350;    not be misrepresented as being the original software.
351;
352; 3. This notice may not be removed or altered from any source distribution.
353;
354; For more information on Open Source Software, visit the Open Source
355; web site: http://www.opensource.org.
356;
357;###########################################################################
358;
359
360
361
362FUNCTION FSC_Field_Error_Message, theMessage, Traceback=traceback, NoName=noName, _Extra=extra
363
364On_Error, 2
365
366   ; Check for presence and type of message.
367
368IF N_Elements(theMessage) EQ 0 THEN theMessage = !Error_State.Msg
369s = Size(theMessage)
370messageType = s[s[0]+1]
371IF messageType NE 7 THEN BEGIN
372   Message, "The message parameter must be a string.", _Extra=extra
373ENDIF
374
375   ; Get the call stack and the calling routine's name.
376
377Help, Calls=callStack
378callingRoutine = (StrSplit(StrCompress(callStack[1])," ", /Extract))[0]
379
380   ; Are widgets supported? Doesn't matter in IDL 5.3 and higher.
381
382widgetsSupported = ((!D.Flags AND 65536L) NE 0) OR Float(!Version.Release) GE 5.3
383IF widgetsSupported THEN BEGIN
384   IF Keyword_Set(noName) THEN answer = Dialog_Message(theMessage, _Extra=extra) ELSE BEGIN
385      IF StrUpCase(callingRoutine) EQ "$MAIN$" THEN answer = Dialog_Message(theMessage, _Extra=extra) ELSE $
386         answer = Dialog_Message(StrUpCase(callingRoutine) + ": " + theMessage, _Extra=extra)
387   ENDELSE
388ENDIF ELSE BEGIN
389      Message, theMessage, /Continue, /NoPrint, /NoName, /NoPrefix, _Extra=extra
390      Print, '%' + callingRoutine + ': ' + theMessage
391      answer = 'OK'
392ENDELSE
393
394   ; Provide traceback information if requested.
395
396IF Keyword_Set(traceback) THEN BEGIN
397   Help, /Last_Message, Output=traceback
398   Print,''
399   Print, 'Traceback Report from ' + StrUpCase(callingRoutine) + ':'
400   Print, ''
401   FOR j=0,N_Elements(traceback)-1 DO Print, "     " + traceback[j]
402ENDIF
403
404RETURN, answer
405END ;-----------------------------------------------------------------------------------------------------------------------------
406
407
408
409FUNCTION FSC_Field::GetLabelSize
410
411; This method returns the X screen size of the label widget.
412
413geom = Widget_Info(self.labelID, /Geometry)
414RETURN, geom.scr_xsize
415END ;-----------------------------------------------------------------------------------------------------------------------------
416
417
418
419FUNCTION FSC_Field::GetTextSize
420
421; This method returns the X screen size of the text widget.
422
423geom = Widget_Info(self.textID, /Geometry)
424RETURN, geom.scr_xsize
425END ;-----------------------------------------------------------------------------------------------------------------------------
426
427
428
429PRO FSC_Field::MoveTab
430
431   ; If the TABNEXT field has a valid widget, will set the
432   ; focus to this widget when a TAB event occurs in the widget.
433
434IF  NOT Widget_Info(self.tabnext, /Valid_ID) THEN RETURN
435Widget_Control, self.tabnext, /Input_Focus
436Widget_Control, self.tabnext, Get_Value=theText
437theText = theText[0]
438Widget_Control, self.tabnext, Set_Text_Select=[0,StrLen(theText)]
439END ;-----------------------------------------------------------------------------------------------------------------------------
440
441
442
443PRO FSC_Field::SetTabNext, nextID
444
445; This method assigns a text id the TABNEXT field of
446; the object. This is required for the MOVETAB method.
447
448self.tabnext = nextID
449END ;-----------------------------------------------------------------------------------------------------------------------------
450
451
452
453FUNCTION FSC_Field::GetTextID
454
455; This method returns the ID of the text widget of the compound widget.
456
457RETURN, self.textID
458END ;-----------------------------------------------------------------------------------------------------------------------------
459
460
461
462PRO FSC_Field::Resize, newsize
463
464; This method resizes the widget by making the text widget fit the new size.
465
466l = Widget_Info(self.labelID, /Geometry)
467Widget_Control, self.textID, Scr_XSize = (newsize - l.scr_xsize)
468
469   ; Set the text widget sensitivitiy.
470
471
472Widget_Control, self.textID, Sensitive=1-Keyword_Set(self.nonsensitive)
473
474END ;-----------------------------------------------------------------------------------------------------------------------------
475
476
477
478FUNCTION FSC_Field::GetID
479
480; This method returns the ID of the top-level base of the compound widget.
481
482RETURN, self.tlb
483END ;-----------------------------------------------------------------------------------------------------------------------------
484
485
486
487FUNCTION FSC_Field::Geometry
488
489; This method returns the geometry of the compound widget.
490
491RETURN, Widget_Info(self.tlb,/Geometry)
492END ;-----------------------------------------------------------------------------------------------------------------------------
493
494
495
496FUNCTION FSC_Field::Get_Value
497
498; This method returns the actual value of the compound widget.
499
500IF N_Elements(*self.theValue) EQ 0 THEN RETURN, *self.undefined ELSE RETURN, *self.theValue
501END ;-----------------------------------------------------------------------------------------------------------------------------
502
503
504
505PRO FSC_Field::Set_Value, value
506
507; This method sets the value of the compound widget.
508
509   ; Error Handling.
510
511Catch, theError
512IF theError NE 0 THEN BEGIN
513   Catch, /Cancel
514   ok = FSC_Field_Error_Message(/Traceback)
515   RETURN
516ENDIF
517
518dataType = Size(value, /TNAME)
519CASE dataType OF
520   'BYTE'   : BEGIN
521      genType = 'INTEGER'
522      dataType = 'INT'
523      positive = 1
524      value = Fix(value)
525      Message, 'BYTE data not supported. Value will be converted to INT.', /Informational
526      END
527   'INT'    : genType = 'INTEGER'
528   'LONG'   : genType = 'INTEGER'
529   'LONG64' : genType = 'INTEGER'
530   'UINT'   : genType = 'UNSIGNED'
531   'ULONG'  : genType = 'UNSIGNED'
532   'ULONG64': genType = 'UNSIGNED'
533   'FLOAT'  : genType = 'FLOAT'
534   'DOUBLE' : genType = 'DOUBLE'
535   'STRING' : genType = 'STRING'
536   ELSE     : Message, 'Data type ' + dataType + ' is not supported. Returning.'
537ENDCASE
538self.dataType = dataType
539self.gentype = genType
540
541IF self.gentype EQ 'DOUBLE' THEN theText = DblToStr(value) ELSE theText = StrTrim(value,2)
542theText = self->Validate(theText)
543
544   ; Load the value in the widget.
545
546Widget_Control, self.textID, Set_Value=theText, Set_Text_Select=[StrLen(theText),0]
547self.theText = theText
548
549   ; Set the actual value of the compound widget.
550
551*self.theValue = self->ReturnValue(theText)
552END ;-----------------------------------------------------------------------------------------------------------------------------
553
554
555
556FUNCTION FSC_Field::Validate, value
557
558; This function eliminates illegal characters from a string that represents
559; a number. The return value is a properly formatted string that can be turned into
560; an INT, LONG, FLOAT, or DOUBLE value. This is a "private" method.
561;
562; + 43B
563; - 45B
564; . 46B
565; 0 - 9 48B -57B
566; 'eEdD' [101B, 69B, 100B, 68B]
567
568   ; Error Handling.
569
570Catch, theError
571IF theError NE 0 THEN BEGIN
572   Catch, /Cancel
573   ok = FSC_Field_Error_Message(/Traceback)
574   testValue = self->ReturnValue(value)
575   IF String(testValue) NE 'NULLVALUE' THEN numCheck = Finite(testValue) ELSE numCheck = 1
576   IF numCheck THEN BEGIN
577      RETURN, retValue
578   ENDIF ELSE BEGIN
579      ok = Dialog_Message('The requested number is not representable.')
580      RETURN, ""
581   ENDELSE
582ENDIF
583
584   ; A null string should be returned at once.
585
586IF N_Elements(value) EQ 0 THEN value = ""
587value = value[0]
588IF value EQ "" THEN RETURN, String(value)
589
590   ; No leading or trailing blank characters to evaluate.
591
592value = StrTrim(value, 2)
593
594   ; A string value should be returned at once. Nothing to check.
595
596IF StrUpCase(self.gentype) EQ 'STRING' THEN RETURN, String(value)
597
598   ; Check integers and longs. A "-" or "+" in the first character is allowed. Otherwise,
599   ; only number between 0 and 9, or 43B to 57B.
600
601IF self.gentype EQ 'INTEGER' THEN BEGIN
602
603   returnValue = Ptr_New(/Allocate_Heap)
604   asBytes = Byte(value)
605
606   IF self.positive THEN BEGIN
607      IF (asBytes[0] EQ 43B) OR $
608         (asBytes[0] GE 48B AND asBytes[0] LE 57B) THEN *returnValue = [asBytes[0]]
609   ENDIF ELSE BEGIN
610      IF (asBytes[0] EQ 45B) OR (asBytes[0] EQ 43B) OR $
611         (asBytes[0] GE 48B AND asBytes[0] LE 57B) THEN *returnValue = [asBytes[0]]
612   ENDELSE
613   length = StrLen(asBytes)
614   IF length EQ 1 THEN BEGIN
615      IF N_Elements(*returnValue) EQ 0 THEN  *returnValue = [32B] ELSE $
616            *returnValue = [asBytes[0]]
617   ENDIF ELSE BEGIN
618      FOR j=1,length-1 DO BEGIN
619         IF (asBytes[j] GE 48B AND asBytes[j] LE 57B) THEN BEGIN
620            IF N_Elements(*returnValue) EQ 0 THEN  *returnValue = [asBytes[j]] ELSE $
621               *returnValue = [*returnValue, asBytes[j]]
622         ENDIF
623      ENDFOR
624  ENDELSE
625  IF N_Elements(*returnValue) NE 0 THEN retValue = String(*returnValue) ELSE retValue = ""
626  Ptr_Free, returnValue
627
628      ; Check for digit restrictions.
629
630  IF self.digits GT 0 THEN BEGIN
631      retValue = StrTrim(retValue, 2)
632      IF StrMid(retValue, 0, 1) EQ "-" THEN digits = self.digits + 1 ELSE digits = self.digits
633      retValue = StrMid(retValue, 0, digits)
634  ENDIF
635
636  RETURN, retValue
637
638ENDIF
639
640   ; Check unsigned data types.
641
642IF self.gentype EQ 'UNSIGNED' THEN BEGIN
643
644   returnValue = Ptr_New(/Allocate_Heap)
645   asBytes = Byte(value)
646
647   IF self.positive THEN BEGIN
648      IF (asBytes[0] GE 48B AND asBytes[0] LE 57B) THEN *returnValue = [asBytes[0]]
649   ENDIF ELSE BEGIN
650      IF (asBytes[0] GE 48B AND asBytes[0] LE 57B) THEN *returnValue = [asBytes[0]]
651   ENDELSE
652   length = StrLen(asBytes)
653   IF length EQ 1 THEN BEGIN
654      IF N_Elements(*returnValue) EQ 0 THEN  *returnValue = [32B] ELSE $
655            *returnValue = [asBytes[0]]
656   ENDIF ELSE BEGIN
657      FOR j=1,length-1 DO BEGIN
658         IF (asBytes[j] GE 48B AND asBytes[j] LE 57B) THEN BEGIN
659            IF N_Elements(*returnValue) EQ 0 THEN  *returnValue = [asBytes[j]] ELSE $
660               *returnValue = [*returnValue, asBytes[j]]
661         ENDIF
662      ENDFOR
663  ENDELSE
664  IF N_Elements(*returnValue) NE 0 THEN retValue = String(*returnValue) ELSE retValue = ""
665  Ptr_Free, returnValue
666
667      ; Check for digit restrictions.
668
669  IF self.digits GT 0 THEN BEGIN
670      retValue = StrTrim(retValue, 2)
671      digits = self.digits
672      retValue = StrMid(retValue, 0, digits)
673  ENDIF
674
675  RETURN, retValue
676
677ENDIF
678
679   ; Check floating values. (+,-) in first character or after 'eEdD'.
680   ; Only numbers, signs, decimal points, and 'eEdD' allowed.
681
682IF (self.gentype EQ 'FLOAT') OR (self.gentype EQ 'DOUBLE') THEN BEGIN
683   returnValue = Ptr_New(/Allocate_Heap)
684   asBytes = Byte(value)
685   IF self.positive THEN BEGIN
686      IF (asBytes[0] EQ 43B) OR $
687         (asBytes[0] GE 48B AND asBytes[0] LE 57B) OR $
688         (asBytes[0] EQ 46B) THEN *returnValue = [asBytes[0]]
689      IF (asBytes[0] EQ 46B) THEN haveDecimal = 1 ELSE haveDecimal = 0
690   ENDIF ELSE BEGIN
691      IF (asBytes[0] EQ 45B) OR (asBytes[0] EQ 43B) OR $
692         (asBytes[0] GE 48B AND asBytes[0] LE 57B) OR $
693         (asBytes[0] EQ 46B) THEN *returnValue = [asBytes[0]]
694      IF (asBytes[0] EQ 46B) THEN haveDecimal = 1 ELSE haveDecimal = 0
695   ENDELSE
696   haveExponent = 0
697   length = StrLen(asBytes)
698   prevByte = asBytes[0]
699   exponents = Byte('eEdD')
700   IF length EQ 1 THEN BEGIN
701      IF N_Elements(*returnValue) EQ 0 THEN  *returnValue = [32B] ELSE $
702            *returnValue = [asBytes[0]]
703   ENDIF ELSE BEGIN
704      FOR j=1,length-1 DO BEGIN
705         IF (asBytes[j] GE 48B AND asBytes[j] LE 57B) THEN BEGIN
706            IF N_Elements(*returnValue) EQ 0 THEN  *returnValue = [asBytes[j]] ELSE $
707               *returnValue = [*returnValue, asBytes[j]]
708            prevByte = asBytes[j]
709         ENDIF ELSE BEGIN
710
711            ; What kind of thing is it?
712
713            IF (asBytes[j] EQ 46B) THEN BEGIN ; A decimal point.
714               IF haveDecimal EQ 0 THEN BEGIN
715                  *returnValue = [*returnValue, asBytes[j]]
716                  haveDecimal = 1
717                  prevByte = asBytes[j]
718               ENDIF
719            ENDIF
720
721            IF (asBytes[j] EQ 45B) OR (asBytes[j] EQ 43B) THEN BEGIN ; A + or - sign.
722               index = Where(exponents EQ prevByte, count)
723               IF count EQ 1 AND haveExponent THEN BEGIN
724                  *returnValue = [*returnValue, asBytes[j]]
725                  haveDecimal = 1
726                  prevByte = asBytes[j]
727               ENDIF
728            ENDIF
729
730            index = Where(exponents EQ asBytes[j], count)
731            IF count EQ 1 AND haveExponent EQ 0 THEN BEGIN ; An exponent
732               *returnValue = [*returnValue, asBytes[j]]
733               haveExponent = 1
734               prevByte = asBytes[j]
735            ENDIF
736         ENDELSE
737      ENDFOR
738   ENDELSE
739      IF N_Elements(*returnValue) NE 0 THEN BEGIN
740
741      retValue = String(*returnValue)
742      retValue = StrTrim(retValue, 2)
743
744               ; Check for decimal restrictions
745
746      IF self.decimal GE 0 THEN BEGIN
747         theDecimalPt = StrPos(retValue, '.')
748         IF theDecimalPt NE -1 THEN retValue = StrMid(retValue, 0, theDecimalPt + self.decimal + 1)
749      ENDIF
750
751   ENDIF ELSE retValue = ""
752   Ptr_Free, returnValue
753
754      ; Is this a representable number?
755
756   testValue = self->ReturnValue(retValue)
757   IF String(testValue) NE 'NULLVALUE' THEN numCheck = Finite(testValue) ELSE numCheck = 1
758   IF numCheck THEN BEGIN
759      RETURN, retValue
760   ENDIF ELSE BEGIN
761      ok = Dialog_Message('The requested number is not representable.')
762      RETURN, ""
763   ENDELSE
764ENDIF
765
766
767END ;-----------------------------------------------------------------------------------------------------------------------------
768
769
770
771FUNCTION FSC_Field::ReturnValue, inputValue
772
773; This method takes a string and turns it into a number,
774; depending upon the current data type of the compound widget.
775; This is a "private" method. For numbers, if the input value
776; is a null string, then an undefined variable is returned.
777
778   ; Error Handling.
779
780ON_IOERROR, CatchIt
781
782CASE self.datatype OF
783   'BYTE': IF inputValue EQ "" OR inputValue EQ "-" OR inputValue EQ "+" THEN $
784      retValue = 'NULLVALUE' ELSE retValue = Fix(inputValue)
785   'INT': IF inputValue EQ "" OR inputValue EQ "-" OR inputValue EQ "+" THEN $
786      retValue = 'NULLVALUE' ELSE retValue = Fix(inputValue)
787   'LONG': IF inputValue EQ "" OR inputValue EQ "-" OR inputValue EQ "+" THEN $
788      retValue = 'NULLVALUE' ELSE retValue = Long(inputValue)
789   'LONG64': IF inputValue EQ "" OR inputValue EQ "-" OR inputValue EQ "+" THEN $
790      retValue = 'NULLVALUE' ELSE retValue = Long64(inputValue)
791   'UINT': IF inputValue EQ "" OR inputValue EQ "-" OR inputValue EQ "+" THEN $
792      retValue = 'NULLVALUE' ELSE retValue = UInt(inputValue)
793   'ULONG': IF inputValue EQ "" OR inputValue EQ "-" OR inputValue EQ "+" THEN $
794      retValue = 'NULLVALUE' ELSE retValue = ULong(inputValue)
795   'ULONG64': IF inputValue EQ "" OR inputValue EQ "-" OR inputValue EQ "+" THEN $
796      retValue = 'NULLVALUE' ELSE retValue = ULong64(inputValue)
797   'FLOAT' : IF inputValue EQ "" OR inputValue EQ "-" OR inputValue EQ "+" THEN $
798      retValue = 'NULLVALUE' ELSE retValue = Float(inputValue)
799   'DOUBLE': IF inputValue EQ "" OR inputValue EQ "-" OR inputValue EQ "+" THEN $
800      retValue = 'NULLVALUE' ELSE retValue = Double(inputValue)
801   'STRING' : retValue = inputValue
802ENDCASE
803
804RETURN, retValue
805
806CatchIt:
807   retValue = 'NULLVALUE'
808   RETURN, retValue
809END ;-----------------------------------------------------------------------------------------------------------------------------
810
811
812
813FUNCTION FSC_Field::TextEvents, event
814
815; The event handler method for the text widget of the compound widget.
816
817   ; Error Handling.
818
819Catch, theError
820IF theError NE 0 THEN BEGIN
821   Catch, /Cancel
822   ok = FSC_Field_Error_Message(/Traceback)
823   RETURN, 0
824ENDIF
825
826   ; Get the previous text, the current cursor location in the text widget,
827   ; and indicate this is not a Carriage Return event.
828
829previousText = self.theText
830textLocation = Widget_Info(event.id, /Text_Select)
831cr_event = 0
832
833; Handle keyboard focus events.
834IF Tag_Names(event, /structure_name) EQ 'WIDGET_KBRD_FOCUS' THEN BEGIN
835    IF event.enter THEN BEGIN
836        self.has_focus = 1L
837        IF self.highlight THEN BEGIN
838            Widget_Control, self.textID, get_value=text
839            text = text[0]
840            Widget_Control, self.textID, set_text_select=[0, Strlen(text)]
841        ENDIF
842
843        IF self.focus THEN BEGIN
844
845              ; Get the current contents of text widget. Validate it.
846
847            Widget_Control, self.textID, Get_Value=newText
848            newText = newText[0]
849            validText = self->Validate(newText)
850
851               ; Load the valid text.
852
853           self.theText = validText
854           testValue  = self->ReturnValue(validText)
855           IF String(testValue) EQ "NULLVALUE" THEN BEGIN
856               Ptr_Free, self.theValue
857               self.theValue = Ptr_New(/Allocate_Heap)
858           ENDIF ELSE *self.theValue = testValue
859
860           ; Send the keyboard focus events if there is an event handler to accept them.
861           IF self.event_func NE "" THEN BEGIN
862              thisEvent = {FSC_Field_Event, self.tlb, event.top, 0L, self.theValue, self.dataType, self}
863              RETURN, thisEvent
864           ENDIF
865
866           IF self.event_pro NE "" THEN BEGIN
867              thisEvent = {FSC_Field_Event, self.tlb, event.top, 0L, self.theValue, self.dataType, self}
868              RETURN, thisEvent
869           ENDIF
870
871       ENDIF
872
873       RETURN, 0
874
875    ENDIF ELSE BEGIN
876
877        self.has_focus = 0L
878        Widget_Control, self.textID, set_text_select=[0]
879
880        IF self.focus THEN BEGIN
881
882              ; Get the current contents of text widget. Validate it.
883
884            Widget_Control, self.textID, Get_Value=newText
885            newText = newText[0]
886            validText = self->Validate(newText)
887
888               ; Load the valid text.
889
890           self.theText = validText
891           testValue  = self->ReturnValue(validText)
892           IF String(testValue) EQ "NULLVALUE" THEN BEGIN
893               Ptr_Free, self.theValue
894               self.theValue = Ptr_New(/Allocate_Heap)
895           ENDIF ELSE *self.theValue = testValue
896
897           ; Send the keyboard focus events if there is an event handler to accept them.
898           IF self.event_func NE "" THEN BEGIN
899              thisEvent = {FSC_Field_Event, self.tlb, event.top, 0L, self.theValue, self.dataType, self}
900              RETURN, thisEvent
901           ENDIF
902
903           IF self.event_pro NE "" THEN BEGIN
904              thisEvent = {FSC_Field_Event, self.tlb, event.top, 0L, self.theValue, self.dataType, self}
905              RETURN, thisEvent
906           ENDIF
907
908       ENDIF
909
910    ENDELSE
911
912   RETURN, 0
913
914ENDIF
915
916   ; What kind of event is this?
917
918possibleTypes = ['INSERT SINGLE CHARACTER', 'INSERT MULTIPLE CHARACTERS', 'DELETE TEXT', 'SELECT TEXT']
919thisType = possibleTypes[event.type]
920
921   ; Branch on event type.
922
923CASE thisType OF
924
925   'INSERT SINGLE CHARACTER': BEGIN
926
927            ; If the character is a TAB see if there is something to do.
928
929         IF event.ch EQ 9B THEN BEGIN
930            self->MoveTab
931            RETURN, 0
932         ENDIF
933
934            ; Get the current contents of text widget. Validate it.
935
936         Widget_Control, self.textID, Get_Value=newText
937         newText = newText[0]
938         validText = self->Validate(newText)
939
940            ; If it is valid, leave it alone. If not, go back to previous text.
941
942         IF validText NE newText THEN BEGIN
943
944            Widget_Control, self.textID, Set_Value=previousText, Set_Text_Select=[textLocation[0]-1,0]
945
946         ENDIF ELSE BEGIN
947
948            self.theText = validText
949            testValue  = self->ReturnValue(validText)
950            IF String(testValue) EQ "NULLVALUE" THEN BEGIN
951               Ptr_Free, self.theValue
952               self.theValue = Ptr_New(/Allocate_Heap)
953            ENDIF ELSE *self.theValue = testValue
954
955         ENDELSE
956
957            ; Is this a Carriage Return event?
958
959         IF event.ch EQ 10B then cr_event = 1
960      ENDCASE
961
962   'INSERT MULTIPLE CHARACTERS': BEGIN
963
964            ; Same as above, but for all the characters you are inserting.
965
966         Widget_Control, self.textID, Get_Value=newText
967         newText = newText[0]
968         validText = self->Validate(newText)
969         IF validText NE newText THEN BEGIN
970            Widget_Control, self.textID, Set_Value=previousText, Set_Text_Select=[textLocation[0]-1,0]
971         ENDIF ELSE BEGIN
972            self.theText = validText
973            testValue  = self->ReturnValue(validText)
974            IF String(testValue) EQ "NULLVALUE" THEN BEGIN
975               Ptr_Free, self.theValue
976               self.theValue = Ptr_New(/Allocate_Heap)
977            ENDIF ELSE *self.theValue = testValue
978         ENDELSE
979      ENDCASE
980
981   'DELETE TEXT': BEGIN
982
983            ; Get the current contents of text widget. Validate it.
984
985         Widget_Control, self.textID, Get_Value=newText
986         newText = newText[0]
987         validText = self->Validate(newText)
988
989            ; Load the valid text.
990
991        Widget_Control, self.textID, Set_Value=validText, Set_Text_Select=[textLocation[0],0]
992        self.theText = validText
993        testValue  = self->ReturnValue(validText)
994        IF String(testValue) EQ "NULLVALUE" THEN BEGIN
995            Ptr_Free, self.theValue
996            self.theValue = Ptr_New(/Allocate_Heap)
997        ENDIF ELSE *self.theValue = testValue
998
999      ENDCASE
1000
1001   'SELECT TEXT': ; Nothing to do.
1002
1003ENDCASE
1004
1005   ; Do you report all events, or only Carriage Return events?
1006
1007IF self.cr_only THEN BEGIN
1008
1009   IF self.event_func NE "" THEN BEGIN
1010      thisEvent = {FSC_Field_Event, self.tlb, event.top, 0L, self.theValue, self.dataType, self}
1011      IF cr_event THEN RETURN, thisEvent
1012   ENDIF
1013
1014   IF self.event_pro NE "" THEN BEGIN
1015      thisEvent = {FSC_Field_Event, self.tlb, event.top, 0L, self.theValue, self.dataType, self}
1016      IF cr_event THEN RETURN, thisEvent
1017   ENDIF
1018
1019ENDIF ELSE BEGIN
1020
1021   IF self.event_func NE "" THEN BEGIN
1022      thisEvent = {FSC_Field_Event, self.tlb, event.top, 0L, self.theValue, self.dataType, self}
1023      RETURN, thisEvent
1024   ENDIF
1025
1026   IF self.event_pro NE "" THEN BEGIN
1027      thisEvent = {FSC_Field_Event, self.tlb, event.top, 0L, self.theValue, self.dataType, self}
1028      RETURN, thisEvent
1029   ENDIF
1030
1031ENDELSE
1032
1033RETURN, 0
1034END ;-----------------------------------------------------------------------------------------------------------------------------
1035
1036
1037
1038PRO FSC_Field::GetProperty, $
1039;
1040; This method allows you to obtain various properties of the compound widget via output keywords.
1041;
1042   CR_Only=cr_only, $               ; Set this keyword if you only want Carriage Return events.
1043   DataType=datatype, $             ; The datatype of the compound widget.
1044   Decimal=decimal, $               ; The number of digits to the right of the decimal point in FLOAT numbers.
1045   Digits=digits, $                 ; The number of digits permitted in INTERGERVALUE and LONGVALUE numbers.
1046   Event_Func=event_func, $         ; Set this keyword to the name of an Event Function.
1047   Event_Pro=event_pro, $           ; Set this keyword to the name of an Event Procedure.
1048   Focus_Events=focus_events, $     ; Set this keyword to inquire whether or not events are reported when the keyboard focus is lost.
1049   Has_Focus=has_focus, $           ; Set this keyword to inquire whether of not the widget has the keyboard focus currently.
1050   Highlight=highlight, $           ; The highlight flag.
1051   Name=Name, $                     ; The name of the object.
1052   NoEdit=noedit, $                 ; Setting this keywords makes the text widget non-editable.
1053   NonSensitive=nonsensitive, $     ; Setting this keywords makes the text widget non-sensitive.
1054   Undefined=undefined, $           ; The "value" of any undefined value.
1055   UValue=uvalue, $                 ; A user value for any purpose.
1056   Value=value                      ; The "value" of the compound widget.
1057
1058   ; Error Handling.
1059
1060Catch, theError
1061IF theError NE 0 THEN BEGIN
1062   Catch, /Cancel
1063   ok = FSC_Field_Error_Message(/Traceback)
1064   RETURN
1065ENDIF
1066
1067   ; Get the properties.
1068
1069cr_only = self.cr_only
1070datatype = self.datatype
1071decimal = self.decimal
1072digits = self.digits
1073event_func = self.event_func
1074event_pro = self.event_pro
1075focus_events = self.focus
1076has_focus = self.has_focus
1077highlight = self.highlight
1078name = self.name
1079noedit = self.noedit
1080nonsensitive = self.nonsensitive
1081Widget_Control, self.tlb, Get_UValue=uvalue
1082IF N_Elements(*self.theValue) EQ 0 THEN value = *self.undefined ELSE value = *self.thevalue
1083undefined = *self.undefined
1084
1085END ;--------------------------------------------------------------------------------------------------------------
1086
1087
1088
1089PRO FSC_Field::SetProperty, $
1090;
1091; This method allows you to set various properties of the compound widget.
1092;
1093   CR_Only=cr_only, $               ; Set this keyword if you only want Carriage Return events.
1094   Decimal=decimal, $               ; Set this keyword to the number of digits to the right of the decimal point in FLOAT values..
1095   Digits=digits, $                 ; Set this keyword to the number of digits permitted in INTEGER values.
1096   Event_Func=event_func, $         ; Set this keyword to the name of an Event Function.
1097   Event_Pro=event_pro, $           ; Set this keyword to the name of an Event Procedure.
1098   Focus_Events=focus_events, $     ; Set this keyword to turn on or off event reporting when the keyboard focus is lost.
1099   Highlight=highlight, $           ; Set this keyword to highlight the text when it gets keyboard focus.
1100   LabelSize=labelsize, $           ; The X screen size of the Label Widget.
1101   Name=name, $                     ; A scalar string name for the object.
1102   NoEdit=noedit, $                 ; Setting this keywords makes the text widget non-editable.
1103   NonSensitive=nonsensitive, $     ; Setting this keywords makes the text widget non-sensitive.
1104   Scr_XSize=scr_xsize, $           ; The X screen size of the text widget.
1105   Scr_YSize=scr_ysize, $           ; The Y screen size of the text widget.
1106   Title=title, $                   ; The text to go on the Label Widget.
1107   Undefined=undefinded, $          ; Set to "value" of undefined value.
1108   UValue=uvalue, $                 ; A user value for any purpose.
1109   Value=value, $                   ; The "value" of the compound widget.
1110   XSize=xsize                      ; The X size of the Text Widget.
1111
1112   ; Error Handling.
1113
1114Catch, theError
1115IF theError NE 0 THEN BEGIN
1116   Catch, /Cancel
1117   ok = FSC_Field_Error_Message(/Traceback)
1118   RETURN
1119ENDIF
1120
1121   ; Set the properties, if needed.
1122
1123IF N_Elements(cr_only) NE 0 THEN self.cr_only = cr_only
1124IF Keyword_Set(decimal)THEN self.decimal = decimal
1125IF Keyword_Set(digits)THEN self.digits = digits
1126IF N_Elements(event_func) NE 0 THEN self.event_func = event_func
1127IF N_Elements(event_pro) NE 0 THEN self.event_pro = event_pro
1128IF N_Elements(focus_events) NE 0 THEN self.focus = keyword_set(focus)
1129IF N_Elements(highlight) NE 0 THEN self.highlight = Keyword_Set(highlight)
1130IF N_Elements(labelsize) NE 0 THEN BEGIN
1131   Widget_Control, self.labelID, XSize=labelsize
1132ENDIF
1133IF N_Elements(scr_xsize) NE 0 THEN BEGIN
1134   Widget_Control, self.textID, Scr_XSize=scr_xsize
1135ENDIF
1136IF N_Elements(scr_ysize) NE 0 THEN BEGIN
1137   Widget_Control, self.textID, Scr_YSize=scr_ysize
1138ENDIF
1139IF N_Elements(title) NE 0 THEN Widget_Control, self.labelID, Set_Value=title
1140IF N_Elements(uvalue) NE 0 THEN Widget_Control, self.tlb, Set_UValue=uvalue
1141If N_Elements(name) NE 0 Then self.name = String(name[0])
1142IF N_Elements(xsize) NE 0 THEN BEGIN
1143   Widget_Control, self.textID, XSize=xsize
1144ENDIF
1145IF N_Elements(noedit) THEN BEGIN
1146   self.noedit = Keyword_Set(noedit)
1147   Widget_Control, self.textID, Editable=1-self.noedit
1148ENDIF
1149IF N_Elements(nonsensitive) THEN BEGIN
1150   self.nonsensitive = Keyword_Set(nonsensitive)
1151   Widget_Control, self.textID, Sensitive=1-self.nonsensitive
1152ENDIF
1153
1154   ; Set up the value.
1155
1156IF N_Elements(value) NE 0 THEN BEGIN
1157
1158   ; Set up data type and general type.
1159
1160   dataType = Size(value, /TNAME)
1161   CASE dataType OF
1162      'BYTE'   : BEGIN
1163         genType = 'INTEGER'
1164         dataType = 'INT'
1165         positive = 1
1166         *self.theValue = Fix(*self.theValue)
1167         Message, 'BYTE data not supported. Value will be converted to INT.', /Informational
1168         END
1169      'INT'    : genType = 'INTEGER'
1170      'LONG'   : genType = 'INTEGER'
1171      'LONG64' : genType = 'INTEGER'
1172      'UINT'   : genType = 'UNSIGNED'
1173      'ULONG'  : genType = 'UNSIGNED'
1174      'ULONG64': genType = 'UNSIGNED'
1175      'FLOAT'  : genType = 'FLOAT'
1176      'DOUBLE' : genType = 'DOUBLE'
1177      'STRING' : genType = 'STRING'
1178      ELSE     : BEGIN
1179         Ptr_Free, self.theValue
1180         self.theValue = Ptr_New(/Allocate_Heap)
1181         Message, 'Data type ' + dataType + ' is not supported. Returning.', /NoName
1182         END
1183   ENDCASE
1184   self.theText = StrTrim(value, 2)
1185   *self.theValue = self->ReturnValue(self.theText)
1186   Widget_Control, self.textID, Set_Value=self.theText
1187   self.dataType = datatype
1188   self.genType = genType
1189   IF N_Elements(undefined) EQ 0 THEN BEGIN
1190   IF genType EQ 'STRING' THEN undefined = "" ELSE undefined = !VALUES.F_NAN
1191ENDIF
1192
1193ENDIF
1194
1195END ;--------------------------------------------------------------------------------------------------------------
1196
1197
1198
1199PRO FSC_Field::SetEdit, editvalue
1200
1201   ; Error Handling.
1202
1203Catch, theError
1204IF theError NE 0 THEN BEGIN
1205   Catch, /Cancel
1206   ok = FSC_Field_Error_Message(/Traceback)
1207   RETURN
1208ENDIF
1209
1210IF N_Elements(editvalue) NE 0 THEN $
1211   Widget_Control, self.textID, Editable=Keyword_Set(editvalue)
1212END ;--------------------------------------------------------------------------------------------------------------
1213
1214
1215PRO FSC_Field::SetSensitive, value
1216
1217   ; Error Handling.
1218
1219Catch, theError
1220IF theError NE 0 THEN BEGIN
1221   Catch, /Cancel
1222   ok = FSC_Field_Error_Message(/Traceback)
1223   RETURN
1224ENDIF
1225
1226IF N_Elements(value) EQ 0 THEN value = 1
1227self.nonsensitive = 1-value
1228Widget_Control, self.textID, Sensitive=value
1229END ;--------------------------------------------------------------------------------------------------------------
1230
1231
1232
1233FUNCTION FSC_Field::INIT, $         ; The compound widget FSC_Field INIT method..
1234   parent, $                        ; The parent widget. Required for all compound widgets.
1235   Column=column, $                 ; Set this keyword to have Label above Text Widget.
1236   CR_Only=cr_only, $               ; Set this keyword if you only want Carriage Return events.
1237   Decimal=decimal, $               ; Set this keyword to the number of digits to the right of the decimal point in FLOAT.
1238   Digits=digits, $                 ; Set this keyword to the number of digits permitted in INTEGER values.
1239   Event_Func=event_func, $         ; Set this keyword to the name of an Event Function.
1240   Event_Pro=event_pro, $           ; Set this keyword to the name of an Event Procedure.
1241   _Extra=extra, $                  ; Passes along extra keywords to the text widget.
1242   FieldFont=fieldfont, $           ; The font name for the text in the Text Widget.
1243   Focus_Events=focus_events, $     ; Set this keyword to enable event reporting when the keyboard focus is lost or gained.
1244   Frame=frame, $                   ; Set this keyword to put a frame around the compound widget.
1245   Highlight=highlight, $           ; If this keyword is set, the text is highlighted.
1246   Label_Left=label_left, $         ; Set this keyword to align the label to the left of the label.
1247   Label_Right=label_right, $       ; Set this keyword to align the labe to the right of the label.
1248   LabelFont=labelfont, $           ; The font name for the text in the Label Widget.
1249   LabelSize=labelsize, $           ; The X screen size of the Label Widget.
1250   Name=name, $                     ; A scalar string name for the object.
1251   NoEdit=noedit, $                 ; Setting this keywords makes the text widget non-editable.
1252   NonSensitive=nonsensitive, $     ; Setting this keywords makes the text widget non-sensitive.
1253   Positive=positive, $             ; Set this keyword to indicate only positive numbers allowed in the field.
1254   Scr_XSize=scr_xsize, $           ; The X screen size of the text widget.
1255   Scr_YSize=scr_ysize, $           ; The Y screen size of the text widget.
1256   Title=title, $                   ; The text to go on the Label Widget.
1257   Undefined=undefined, $           ; Set to the value for "undefined" field values.
1258   UValue=uvalue, $                 ; A user value for any purpose.
1259   Value=value, $                   ; The "value" of the compound widget.
1260   XSize=xsize                      ; The X size of the Text Widget.
1261
1262   ; Error Handling.
1263
1264Catch, theError
1265IF theError NE 0 THEN BEGIN
1266   Catch, /Cancel
1267   ok = FSC_Field_Error_Message(/Traceback)
1268   RETURN, 0
1269ENDIF
1270
1271   ; A parent is required.
1272
1273IF N_Elements(parent) EQ 0 THEN BEGIN
1274   Message, 'A PARENT argument is required. Returning...', /NoName
1275ENDIF
1276
1277   ; Check keyword values.
1278
1279IF N_Elements(column) EQ 0 THEN column = 0
1280IF N_Elements(digits) EQ 0 THEN digits = 0 ELSE digits = Fix(digits)
1281IF N_Elements(decimal) EQ 0 THEN decimal = -1 ELSE decimal = Fix(decimal)
1282IF N_Elements(event_func) EQ 0 THEN event_func = ""
1283IF N_Elements(event_pro) EQ 0 THEN event_pro = ""
1284IF N_Elements(fieldfont) EQ 0 THEN fieldfont = ""
1285IF N_Elements(frame) EQ 0 THEN frame = 0
1286IF N_Elements(labelfont) EQ 0 THEN labelfont = ""
1287IF N_Elements(labelsize) EQ 0 THEN labelsize = 0
1288IF N_Elements(name) EQ 0 THEN name = ""
1289noedit = Keyword_Set(noedit)
1290nonsensitive = Keyword_Set(nonsensitive)
1291positive = Keyword_Set(positive)
1292IF N_Elements(scr_xsize) EQ 0 THEN scr_xsize = 0
1293IF N_Elements(scr_ysize) EQ 0 THEN scr_ysize = 0
1294IF N_Elements(title) EQ 0 THEN title = "Input Value: "
1295IF N_Elements(uvalue) EQ 0 THEN uvalue = ""
1296IF N_Elements(value) EQ 0 THEN value = ""
1297IF N_Elements(xsize) EQ 0 THEN xsize = 0
1298
1299   ; What data type are we looking for?
1300
1301dataType = Size(value, /TNAME)
1302CASE dataType OF
1303   'BYTE'   : BEGIN
1304      genType = 'INTEGER'
1305      dataType = 'INT'
1306      positive = 1
1307      value = Fix(value)
1308      Message, 'BYTE data not supported. Value will be converted to INT.', /Informational
1309      END
1310   'INT'    : genType = 'INTEGER'
1311   'LONG'   : genType = 'INTEGER'
1312   'LONG64' : genType = 'INTEGER'
1313   'UINT'   : genType = 'UNSIGNED'
1314   'ULONG'  : genType = 'UNSIGNED'
1315   'ULONG64': genType = 'UNSIGNED'
1316   'FLOAT'  : genType = 'FLOAT'
1317   'DOUBLE' : genType = 'DOUBLE'
1318   'STRING' : genType = 'STRING'
1319   ELSE     : Message, 'Data type ' + dataType + ' is not supported. Returning.', /NoName
1320ENDCASE
1321
1322IF N_Elements(undefined) EQ 0 THEN BEGIN
1323   IF genType EQ 'STRING' THEN undefined = "" ELSE undefined = !VALUES.F_NAN
1324ENDIF
1325
1326   ; Populate the object.
1327
1328self.cr_only = Keyword_Set(cr_only)
1329self.datatype = datatype
1330self.decimal = decimal
1331self.digits = digits
1332self.focus = Keyword_Set(focus_events)
1333self.highlight = Keyword_Set(highlight)
1334self.gentype = genType
1335self.parent = parent
1336self.event_pro = event_pro
1337self.event_func = event_func
1338self.positive = positive
1339self.undefined = Ptr_New(undefined)
1340self.noedit = noedit
1341self.nonsensitive = nonsensitive
1342If N_Elements(name) NE 0 Then self.name = String(name[0])
1343IF Keyword_Set(column) THEN row = 0 ELSE row = 1
1344
1345   ; Validate the input value.
1346
1347IF self.gentype EQ 'DOUBLE' THEN value = DblToStr(value) ELSE value = StrTrim(value,2)
1348value = self->Validate(value)
1349self.theText = value
1350
1351   ; Create the widgets.
1352
1353self.tlb = Widget_Base( parent, $  ; The top-level base of the compound widget.
1354   Frame=frame, $
1355   Row=row, $
1356   Column=Keyword_Set(column), $
1357   Base_Align_Center=1, $
1358   UName=name, $
1359   UValue=uvalue, $
1360   Event_Pro=event_pro, $
1361   Func_Get_Value='FSC_Field_Get_Compound_Widget_Value', $
1362   Pro_Set_Value='FSC_Field_Set_Compound_Widget_Value', $
1363   Event_Func=event_func )
1364
1365; Update for tabbing in IDL 6.2.
1366IF Float(!Version.Release) GT 6.1 THEN BEGIN
1367   Widget_Control, self.tlb, TAB_MODE=1
1368ENDIF
1369
1370self.labelID = Widget_Label( self.tlb, Value=title, Font=labelfont, $ ; The Label Widget.
1371  Scr_XSize=labelsize, UValue=self, Align_Left=Keyword_Set(label_left), Align_Right=Keyword_Set(label_right))
1372
1373self.textID = Widget_Text( self.tlb, $  ; The Text Widget.
1374   Value=value, $
1375   XSize=xsize, $
1376   YSize=1, $
1377   Scr_XSize=scr_xsize, $
1378   Scr_YSize=scr_ysize, $
1379   sensitive=1-self.nonsensitive, $
1380   Font=fieldfont, $
1381   All_Events=1, $
1382   _Extra=extra, $
1383   kbrd_focus_events=1, $
1384   Event_Func='FSC_Field_Event_Handler', $
1385   UValue={Method:"TextEvents", Object:self}, $
1386   Kill_Notify='FSC_Field_Kill_Notify', $
1387   Editable=1-noedit )
1388
1389self.theValue = Ptr_New(self->ReturnValue(value))
1390
1391   ; If CR_ONLY or FOCUS_EVENTS are turned on and EVENT_PRO and EVENT_FUNC keywords are
1392   ; unspecified, issue a warning message to the command log.
1393
1394IF self.cr_only AND (self.event_pro EQ "" AND self.event_func EQ "") THEN $
1395   Message, /Information, 'WARNING: There is no specified event handler for carriage return events for this widget. Events will be swallowed.'
1396IF self.focus AND (self.event_pro EQ "" AND self.event_func EQ "") THEN $
1397   Message, /Information, 'WARNING: There is no specified event handler for keyboard focus events for this widget. Events will be swallowed.'
1398
1399RETURN, 1
1400END ;--------------------------------------------------------------------------------------------------------------
1401
1402
1403
1404PRO FSC_Field::CLEANUP
1405
1406; This method makes sure there are not pointers left on the heap.
1407
1408Ptr_Free, self.theValue
1409Ptr_Free, self.undefined
1410END ;--------------------------------------------------------------------------------------------------------------
1411
1412
1413
1414FUNCTION FSC_Field_Event_Handler, event
1415
1416; The main event handler for the compound widget. It reacts
1417; to "messages" in the UValue of the text widget.
1418; The message indicates which object method to call. A message
1419; consists of an object method and the self object reference.
1420
1421Widget_Control, event.ID, Get_UValue=theMessage
1422event = Call_Method(theMessage.method, theMessage.object, event)
1423
1424RETURN, event
1425END ;-----------------------------------------------------------------------------------------------------------------------------
1426
1427
1428
1429PRO FSC_Field_Event__Define
1430
1431; The FSC_Field Event Structure. Sent only if EVENT_PRO or EVENT_FUNC keywords
1432; have defined an event handler for the top-level base of the compound widget.
1433
1434   event = { FSC_Field_Event, $   ; The name of the event structure.
1435             ID: 0L, $            ; The ID of the compound widget's top-level base.
1436             TOP: 0L, $           ; The widget ID of the top-level base of the hierarchy.
1437             HANDLER: 0L, $       ; The event handler ID. Filled out by IDL.
1438             Value: Ptr_New(), $  ; A pointer to the widget value.
1439             Type: "", $          ; A string indicating the type of data in the VALUE field.
1440             Object: Obj_New()}   ; The "self" object.
1441
1442
1443END ;-----------------------------------------------------------------------------------------------------------------------------
1444
1445
1446
1447PRO FSC_Field_Set_Compound_Widget_Value, tlb, value
1448
1449; This utilty routine is invoked when the user tries to set
1450; the value of the compound widget using the base widget
1451; identifier of the top-level base of the compound widget.
1452; The self object is located, and the Set_Value method is called
1453; on the object.
1454
1455firstChildID = Widget_Info(tlb, /Child)
1456Widget_Control, firstChildID, Get_UValue=self
1457self->Set_Value, value
1458END ;--------------------------------------------------------------------------------------------------------------
1459
1460
1461
1462FUNCTION FSC_Field_Get_Compound_Widget_Value, tlb
1463
1464; This utilty routine is invoked when the user tries to get
1465; the value of the compound widget using the base widget
1466; identifier of the top-level base of the compound widget.
1467; The self object is located, and the Get_Value method is called
1468; on the object.
1469
1470firstChildID = Widget_Info(tlb, /Child)
1471Widget_Control, firstChildID, Get_UValue=self
1472IF N_Elements(self->Get_Value()) EQ 0 THEN RETURN, *self.undefined ELSE RETURN, self->Get_Value()
1473END ;--------------------------------------------------------------------------------------------------------------
1474
1475
1476
1477PRO FSC_Field_Kill_Notify, textID
1478
1479; This widget call-back procedure makes sure the self object is
1480; destroyed when the widget is destroyed.
1481
1482Widget_Control, textID, Get_UValue=message
1483Obj_Destroy, message.object
1484END ;--------------------------------------------------------------------------------------------------------------
1485
1486
1487
1488PRO FSC_Field__Define
1489
1490   objectClass = { FSC_FIELD, $             ; The object class name.
1491                   parent: 0L, $            ; The parent widget ID.
1492                   tlb: 0L, $               ; The top-level base of the compound widget.
1493                   labelID: 0L, $           ; The label widget ID.
1494                   textID: 0L, $            ; The text widget ID.
1495                   theText: "", $           ; The actual text in the text widget.
1496                   theValue: Ptr_New(), $   ; The actual "value" of the text in the text widget. :-)
1497                   event_func: "", $        ; The name of the specified event handler function.
1498                   event_pro: "", $         ; The name of the specified event handler procedrue
1499                   cr_only: 0L, $           ; A flag meaning send only carriage return events.
1500                   focus: 0L, $             ; A flag to indicate that events should be reported if the keyboard focus is lost
1501                   has_focus: 0L, $         ; A flag to indicate that the widget has the keyboard focus currently.
1502                   highlight: 0L, $         ; A flag for highlighting.
1503                   tabnext: 0L, $           ; The identifier of a widget to receive the cursor focus if a TAB character is detected.
1504                   decimal: 0, $            ; The number of decimals points in FLOAT and DOUBLE numbers.
1505                   digits: 0, $             ; The number of digits in INT and LONG numbers.
1506                   positive: 0, $           ; A flag meaning only positive numbers allowed.
1507                   datatype: "",$           ; The type of data to be returned from the text widget.
1508                   gentype: "", $           ; The "general" type of data: INTEGER, UNSIGNED, FLOAT, or STRING.
1509                   undefined: Ptr_New(), $  ; The "undefined" value. Used in Get_Value methods, etc.
1510                   noedit: 0L, $            ; A flag indicating whether text widget is editable (0) or not (1).
1511                   nonsensitive: 0L, $      ; A flag indicating whether text widget is sensitive (0) or not (1).
1512                   name:"" $                ; a scalar string name for the object
1513                  }
1514
1515END ;--------------------------------------------------------------------------------------------------------------
1516
1517
1518
1519FUNCTION FSC_FIELD, $               ; The compound widget FSC_Field.
1520   parent, $                        ; The parent widget. Required for all compound widgets.
1521   Column=column, $                 ; Set this keyword to have Label above Text Widget.
1522   CR_Only=cr_only, $               ; Set this keyword if you only want Carriage Return events.
1523   Decimal=decimal, $               ; Set this keyword to the number of digits to the right of the decimal point in FLOAT numbers.
1524   Digits=digits, $                 ; Set this keyword to the number of digits permitted in INTEGER numbers.
1525   Event_Func=event_func, $         ; Set this keyword to the name of an Event Function.
1526   Event_Pro=event_pro, $           ; Set this keyword to the name of an Event Procedure.
1527   _Extra=extra, $                  ; Passes along extra keywords to the text widget.
1528   FieldFont=fieldfont, $           ; The font name for the text in the Text Widget.
1529   Focus_Events=focus_events, $     ; Set this keyword to enable event reporting when the keyboard focus is lost.
1530   Frame=frame, $                   ; Set this keyword to put a frame around the compound widget.
1531   Highlight=highlight, $           ; If this keyword is set, the text is highlighted.
1532   Label_Left=label_left, $         ; Set this keyword to align the label to the left of the label.
1533   Label_Right=label_right, $       ; Set this keyword to align the labe to the right of the label.
1534   LabelFont=labelfont, $           ; The font name for the text in the Label Widget.
1535   LabelSize=labelsize, $           ; The X screen size of the Label Widget.
1536   Name=name, $                     ; The name of the object.
1537   NoEdit=noedit, $                 ; Setting this keywords makes the text widget non-editable.
1538   NonSensitive=nonsensitive, $     ; Setting this keywords makes the text widget non-sensitive.
1539   Object = obj, $                  ; An output keyword that contains the object reference.
1540   Positive=positive, $             ; Set this keyword to indicate only positive numbers allowed in the field.
1541   Scr_XSize=scr_xsize, $           ; The X screen size of the text widget.
1542   Scr_YSize=scr_ysize, $           ; The Y screen size of the text widget.
1543   Title=title, $                   ; The text to go on the Label Widget.
1544   Undefined=undefined, $           ; Set to the value for "undefined" field values.
1545   UValue=uvalue, $                 ; A user value for any purpose.
1546   Value=value, $                   ; The "value" of the compound widget.
1547   XSize=xsize                      ; The X size of the Text Widget.
1548
1549obj = Obj_New("FSC_FIELD", $
1550   parent, $                        ; The parent widget. Required for all compound widgets.
1551   Column=column, $                 ; Set this keyword to have Label above Text Widget.
1552   CR_Only=cr_only, $               ; Set this keyword if you only want Carriage Return events.
1553   Decimal=decimal, $               ; Set this keyword to the number of digits to the right of the decimal point in FLOAT numbers.
1554   Digits=digits, $                 ; Set this keyword to the number of digits permitted in INTEGER numbers.
1555   Event_Func=event_func, $         ; Set this keyword to the name of an Event Function.
1556   Event_Pro=event_pro, $           ; Set this keyword to the name of an Event Procedure.
1557   _Extra=extra, $                  ; Passes along extra keywords to the text widget.
1558   FieldFont=fieldfont, $           ; The font name for the text in the Text Widget.
1559   Focus_events=focus_events, $     ; Set this keyword to enable event reporting when the keyboard focus is lost.
1560   Frame=frame, $                   ; Set this keyword to put a frame around the compound widget.
1561   Highlight=highlight, $           ; If this keyword is set, the text is highlighted.
1562   Label_Left=label_left, $         ; Set this keyword to align the label to the left of the label.
1563   Label_Right=label_right, $       ; Set this keyword to align the labe to the right of the label.
1564   LabelFont=labelfont, $           ; The font name for the text in the Label Widget.
1565   LabelSize=labelsize, $           ; The X screen size of the Label Widget.
1566   Name=name, $                     ; The name of the object.
1567   NoEdit=noedit, $                 ; Setting this keywords makes the text widget non-editable.
1568   NonSensitive=nonsensitive, $     ; Setting this keywords makes the text widget non-sensitive.
1569   Positive=positive, $             ; Set this keyword to indicate only positive numbers allowed in the field.
1570   Scr_XSize=scr_xsize, $           ; The X screen size of the text widget.
1571   Scr_YSize=scr_ysize, $           ; The Y screen size of the text widget.
1572   Title=title, $                   ; The text to go on the Label Widget.
1573   Undefined=undefined, $           ; Set to the value for "undefined" field values.
1574   UValue=uvalue, $                 ; A user value for any purpose.
1575   Value=value, $                   ; The "value" of the compound widget.
1576   XSize=xsize)                     ; The X size of the Text Widget.
1577
1578IF Obj_Valid(obj) THEN RETURN, obj->GetID() ELSE RETURN, -1L
1579END ;--------------------------------------------------------------------------------------------------------------
1580
1581
1582
1583PRO Example_Event, event
1584
1585
1586; An example event handler for FSC_Field.
1587
1588Widget_Control, event.top, Get_UValue=info
1589Widget_Control, event.id, Get_UValue=thisEvent
1590
1591
1592; Not interested in losing keyboard focus events.
1593theName = Tag_Names(event, /Structure_Name)
1594IF theName EQ 'WIDGET_KBRD_EVENT' THEN BEGIN
1595   IF event.type EQ 0 THEN RETURN
1596ENDIF
1597
1598; What kind of event is this?
1599CASE thisEvent OF
1600   'Field 1 Event': BEGIN
1601
1602      ; Demonstate various ways to test if the value from this field is undefined.
1603
1604      Print, ''
1605      IF N_Elements(*event.value) EQ 0 THEN Print, 'Field 1 Value is Undefined from Event Structure' ELSE $
1606         Print, 'Field 1 Value from Event Structure: ', *event.value
1607
1608      Widget_Control, info.field1id, Get_Value=theValue
1609      IF Finite(theValue) EQ 0 THEN Print, 'Field 1 Value is Undefined and Assigned Value: ', theValue ELSE $
1610         Print, 'Field 1 Value via Widget Get_Value Function: ', theValue
1611
1612
1613      IF Finite(info.field1->Get_Value()) EQ 0 THEN Print, 'Field 1 Value is Undefined from Object Get_Value Function' ELSE $
1614         Print, 'Field 1 Value via Object Get_Value Function: ', info.field1->Get_Value()
1615
1616      END
1617   'Field 2 Event': BEGIN
1618      Print, ''
1619      IF N_Elements(*event.value) EQ 0 THEN Print, 'Field 2 Value is Undefined' ELSE $
1620         Print, 'Field 2 Value: ', *event.value
1621
1622      theValue = info.field2->Get_Value()
1623      IF theValue EQ -9999.0 THEN Print, 'Field 2 Value is Undefined and Assigned Value: ', theValue ELSE $
1624         Print, 'Field 2 Value via Object Get_Value Function: ', theValue
1625
1626      END
1627
1628   'Print It': BEGIN
1629      theValue =info.field3->Get_Value()
1630      Print, ''
1631      Print, 'Field 3 Value: ', theValue
1632      END
1633   'Set It': BEGIN
1634      info.field3->Set_Value, 'Coyote Rules!'
1635      END
1636   'Quit': Widget_Control, event.top, /Destroy
1637   'ChangeToUInt': BEGIN
1638      info.field1->SetProperty, Title='Unsigned:', Value=UINT(RandomU(seed, 1)*100)
1639      END
1640   'ChangeToFloat': BEGIN
1641      info.field1->SetProperty, Title='Float:', Value=RandomU(seed, 1)*100
1642      END
1643   'ChangeToString': BEGIN
1644      info.field1->SetProperty, Title='String:', Value='Coyote Jules'
1645      END
1646   'PrintFloat': BEGIN
1647      IF N_Elements(info.field2->Get_Value()) EQ 0 THEN Print, 'Field 2 Value is Undefined' ELSE $
1648         Print, 'Field 2 Value: ', info.field2->Get_Value()
1649      END
1650   'LabelSize': BEGIN
1651      Widget_Control, event.top, Update=0
1652      currentSize = info.labelsize
1653      info.field1->SetProperty, LabelSize=info.labelsize
1654      info.field2->SetProperty, LabelSize=info.labelsize
1655      info.field3->SetProperty, LabelSize=info.labelsize
1656      IF currentsize EQ 75 THEN info.labelsize = 50 ELSE info.labelsize = 75
1657      Widget_Control, event.top, Update=1
1658      END
1659   'MakeEditable': BEGIN
1660      Widget_Control, event.id, Get_Value=buttonValue
1661      CASE buttonValue OF
1662         'Make String Field Editable': BEGIN
1663            info.field3->SetEdit, 1
1664            Widget_Control, event.id, Set_Value='Make String Field Non-Editable'
1665            END
1666         'Make String Field Non-Editable': BEGIN
1667            info.field3->SetEdit, 0
1668            Widget_Control, event.id, Set_Value='Make String Field Editable'
1669            END
1670      ENDCASE
1671      END
1672   'MakeSensitive': BEGIN
1673      Widget_Control, event.id, Get_Value=buttonValue
1674      CASE buttonValue OF
1675         'Make String Field Sensitive': BEGIN
1676            info.field3->SetSensitive, 1
1677            Widget_Control, event.id, Set_Value='Make String Field Non-Sensitive'
1678            END
1679         'Make String Field Non-Sensitive': BEGIN
1680            info.field3->SetSensitive, 0
1681            Widget_Control, event.id, Set_Value='Make String Field Sensitive'
1682            END
1683      ENDCASE
1684      END
1685ENDCASE
1686
1687IF Widget_Info(event.top, /Valid_ID) THEN Widget_Control, event.top, Set_UValue=info
1688END ;--------------------------------------------------------------------------------------------------------------
1689
1690
1691
1692PRO Example, field1, field2, field3
1693
1694; An example program to exercise some of the features of FSC_FIELD.
1695
1696tlb = Widget_Base(Column=1)
1697button = Widget_Button(tlb, Value='Change First Field to Float', $
1698   UValue='ChangeToFloat')
1699button = Widget_Button(tlb, Value='Change First Field to String', $
1700   UValue='ChangeToString')
1701button = Widget_Button(tlb, Value='Change First Field to Unsigned Integer', $
1702   UValue='ChangeToUInt')
1703
1704   ; Create an integer field, no more than 4 digits in the value.
1705
1706field1id = FSC_FIELD(tlb, Title='Integer:', LabelSize=50, Digits=4, Object=field1, $
1707   Value=5, UValue='Field 1 Event', Event_Pro='Example_Event', /CR_Only, /Highlight)
1708
1709   ; Create a floating point field. Only two decimal points to the right of the decimal.
1710   ; Set the Undefined value to -9999.0.
1711
1712field = FSC_FIELD(tlb, Title='Double:', LabelSize=50, Value=-123456789.1234567891234D, Object=field2, Undefined=-9999.0, $
1713   /CR_Only, UValue='Field 2 Event', Event_Pro='Example_Event', Decimal=8, /Highlight)
1714
1715   ; Create a string field.
1716
1717field = FSC_FIELD(tlb, Title='String:', LabelSize=50, Value='Coyote Rules!', Object=field3, /Nonsensitive, /Highlight)
1718
1719   ; Set up TABing between fields.
1720
1721;field1->SetTabNext, field2->GetTextID()
1722;field2->SetTabNext, field3->GetTextID()
1723;field3->SetTabNext, field1->GetTextID()
1724
1725button = Widget_Button(tlb, Value='Print Value of String', UValue="Print It")
1726button = Widget_Button(tlb, Value='Set Value of String', UValue='Set It')
1727button = Widget_Button(tlb, Value='Change Size of Labels', UValue='LabelSize')
1728button = Widget_Button(tlb, Value='Print Floating Value', UValue='PrintFloat')
1729button = Widget_Button(tlb, Value='Make String Field Editable', UValue='MakeEditable')
1730button = Widget_Button(tlb, Value='Make String Field Sensitive', UValue='MakeSensitive')
1731button = Widget_Button(tlb, Value='Quit', UValue='Quit')
1732Widget_Control, tlb, /Realize, Set_UValue={field1:field1, field2:field2, field3:field3, field1id:field1id, labelsize:75}
1733XManager, 'example', tlb, /No_Block
1734END
Note: See TracBrowser for help on using the repository browser.