# coyote: FSC_FIELD

- coyote/General Programming
- [Source code]

NAME

      FSC_FIELD

PURPOSE

      The purpose of this compound widget is to provide an alternative
      to the CW_FIELD widget offered in the IDL distribution. One weakness
      of the CW_FIELD compound widget is that the text widgets do not
      look editable to the users on Windows platforms. This program
      corrects that deficiency and adds some features that I think
      will be helpful. For example, you can now assign an event handler
      to the compound widget, ask for positive numbers only, and limit
      the number of digits in a number, or the number of digits to the
      right of a decimal point. The program is written as a widget object,
      which allows the user to call object methods directly, affording
      even more flexibility in use. This program replaces the earlier
      programs FSC_INPUTFIELD and COYOTE_FIELD.
      The program consists of a label widget next to a one-line text widget.
      The "value" of the compound widget is shown in the text widget. If the
      value is a number, it will not be possible (generally) to type
      alphanumeric values in the text widget. String values behave like
      strings in any one-line text widget.

AUTHOR

      FANNING SOFTWARE CONSULTING
      David Fanning, Ph.D.
      1645 Sheely Drive
      Fort Collins, CO 80526 USA
      Phone: 970-221-0438
      E-mail: david@idlcoyote.com
      Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

CATEGORY

      General programming.

TYPICAL CALLING SEQUENCE

      fieldID = FSC_FIELD(parent, Title="X Size:", Value=256, Object=fieldObject, Digits=3)

INPUT PARAMETERS

      parent -- The parent widget ID of the compound widget. Required.

INPUT KEYWORDS

      COLUMN        Set this keyword to have the Label widget above the Text widget.
                    The default is to have the Label widget in a row with the Text widget.
      CR_ONLY       Set this keyword if you only want Carriage Return events returned to
                    your event handler. If this keyword is not set, all events are returned.
                    Setting this keyword has no effect unless either the EVENT_PRO or
                    EVENT_FUNC keyword is used.
      DECIMAL       Set this keyword to the number of digits to the right of the decimal
                    point in floating point or double precision numbers. Ignored for STRING values.
      DIGITS        Set this keyword to the number of digits permitted in integer numbers.
      EVENT_FUNC    Set this keyword to the name of an event handler function. If this
                    keyword is undefined and the Event_Pro keyword is undefined,
                    all compound widget events are handled internally and not
                    passed on to the parent widget.
      EVENT_PRO     Set this keyword to the name of an event handler procedure. If this
                    keyword is undefined and the Event_Func keyword is undefined,
                    all compound widget events are handled internally and not
                    passed on to the parent widget.
      FIELDFONT     The font name for the text in the text widget.
      FRAME         Set this keyword to put a frame around the compound widget.
      FOCUS_EVENTS  Set this keyword to enable event generation for keyboard focus
                    events. Ignored unless EVENT_FUNC or EVENT_PRO keywords are specified.
      HIGHLIGHT     Set this keyword to highlight the existing text if the widget gain
                    the keyboard focus. This keyword MUST be set for tabbing to work naturally
                    in IDL 6.2 and higher.
      LABEL_LEFT    Set this keyword to align the text on the label to the left.
      LABEL_RIGHT   Set this keyword to align the text on the label to the right.
      LABELFONT     The font name for the text in the label widget.
      LABELSIZE     The X screen size of the label widget.
      NAME          A string containing the name of the object. The default is ''.
      NOEDIT        Set this keyword to allow no user editing of the input text widget.
      NONSENSITIVE  Set this keyword to make the input text widget non-sensitive.
      POSITIVE      Set this keyword if you want only positive numbers allowed.
      SCR_XSIZE     The X screen size of the compound widget.
      SCR_YSIZE     The Y screen size of the compound widget.
      TITLE         The string text placed on the label widget.
      UNDEFINED     Set this keyword to the value to use for "undefined" values. If
                    not set, then !Value.F_NAN is used for numerical fields and a
                    NULL string is used for string fields. This applies to values
                    obtained with the GET_VALUE method or the GET_VALUE function.
      UVALUE        A user value for any purpose.
      VALUE         The "value" of the compound widget. Any type of integer, floating, or string
                    variable is allowed. The data "type" is determined automatically from the
                    value supplied with this keyword. Be sure you set the type appropriately for
                    your intended use of the value.
      XSIZE         The X size of the text widget in the usual character units.

OUTPUT KEYWORDS

      OBJECT        Set this keyword to a named variable to receive the compound widget's
                    object reference. This is required if you wish to call methods on the object.
                    Note that the object reference is also available in the event structure
                    generated by the widget object. Note that the object reference will be
                    necessary if you want to get or set values in the compound widget.

COMMON BLOCKS

      None.

RESTRICTIONS

      Requires cgDblToStr from the Coyote Library:
         http://www.idlcoyote.com/programs/cgdbltostr.pro

EVENT STRUCTURE

      All events are handled internally unless either the Event_Pro or Event_Func
      keywords are used to assign an event handler to the compound widget. By
      default all events generated by the text widget are passed to the assigned
      event handler. If you wish to receive only Carriage Return events, set the
      CR_Only keyword.
      event = { FSC_FIELD_EVENT, $   ; The name of the event structure.
                ID: 0L, $            ; The ID of the compound widget's top-level base.
                TOP: 0L, $           ; The widget ID of the top-level base of the hierarchy.
                HANDLER: 0L, $       ; The event handler ID. Filled out by IDL.
                OBJECT: Obj_New(), $ ; The "self" object reference. Provided so you can call methods.
                VALUE: Ptr_New(), $  ; A pointer to the widget value.
                TYPE:""              ; A string indicating the type of data in the VALUE field.
              }
      Note that if the field is "empty", the VALUE will be a pointer
      to an undefined variable. You should check this value before you
      use it. You code will look something like this:
        IF N_Elements(*event.value) EQ 0 THEN $
            Print, 'Current Value UNDEFINED.' ELSE $
            Print, 'Current Value: ', *event.value

GETTING and SETTING VALUES

      Almost all the properties of the widget can be obtained or set via
      the object's GetProperty and SetProperty methods (described below).
      Traditional compound widgets have the ability to get and set the "value"
      of the compound widget identifier (e.g., fieldID in the calling
      sequence above). Unfortunately, it is impossible to retreive a variable
      in this way when the variable is undefined. In practical terms, this
      means that the undefined variable must be set to *something*. You can
      determine what that something is with the UNDEFINED keyword, or I will set
      it to !VALUES.F_NAN for numerical fields and to the null string for string
      fields. In any case, you will have to check for undefined variables before
      you try to do something with the value. For a numerical field, the code
      might look something like this:
         fieldID = FSC_FIELD(parent, Title="X Size:", Value=256, Object=fieldObject, Digits=3)
         currentValue = fieldObject->Get_Value()
         IF Finite(currentValue) EQ 0 THEN Print, 'Value is Undefined' ELSE Print, currentValue
      Additional examples are provided in the numerical example fields in Example Program below.
      Setting the value of the compound widget is the same as calling the Set_Value
      method on the object reference. In other words, these two statements are equivalent.
           fieldObject->Set_Value, 45.4
           Widget_Control, fieldID, Set_Value=45.4
      The data type of the value is determined from the value itself. Be sure you set it appropriately.

OBJECT PROCEDURE METHODS

      GetProperty -- This method allows various properties of the widget to be
          returned via output keywords. The keywords that are available are:
          CR_Only -- A flag, if set, means only report carriage return events.
          DataType -- The data type of the field variable.
          Decimal -- Set this keyword to the number of digits to the right of the decimal
                 point in FLOATVALUE and DOUBLEVALUE numbers.
          Digits -- Set this keyword to the number of digits permitted in INTERGERVALUE and LONGVALUE numbers.
          Event_Func -- The name of the event handler function.
          Event_Pro -- The name of the event handler function.
          Has_Focus -- Set to 1 if the text widget currently has the keyboard focus.
          Highlight -- The highlight flag.
          NoEdit -- The NoEdit flag.
          NonSensitive -- The NonSensitive flag.
          Undefined -- The "value" of any undefined value.
          UValue -- The user value assigned to the compound widget.
          Value -- The "value" of the compound widget.
        Name -- A scalar string name of the object.
      Resize -- This method allows you to resize the compound widget's text field.
           The value parameter is an X screen size for the entire widget. The text
           widget is sized by using the value obtained from this value minus the
           X screen size of the label widget.
             objectRef->Resize, screen_xsize_value
      Set_Value -- This method allows you to set the "value" of the field. It takes
          one positional parameter, which is the value.
             objectRef->Set_Value, 5
      SetProperty -- This method allows various properties of the widget to be
          set via input keywords. The keywords that are available are:
          CR_Only -- Set this keyword if you only want Carriage Return events.
          Decimal -- Set this keyword to the number of digits to the right of the decimal
                 point in FLOAT and DOUBLE numbers.
          Digits -- Set this keyword to the number of digits permitted in INTERGER and LONG numbers.
          Event_Func -- Set this keyword to the name of an Event Function.
          Event_Pro -- Set this keyword to the name of an Event Procedure.
          Highlight -- Set this keyword to highlight the existing text
                       when the widget gets the keyboard focus
          LabelSize --  The X screen size of the Label Widget.
          Name -- A scalar string name of the object. (default = '')
          NoEdit -- Set this keyword to make the text widget uneditable
          NonSensitive -- Set this keyword to make the widget nonsensitive
          Scr_XSize -- The X screen size of the text widget.
          Scr_YSize -- The Y screen size of the text widget.
          Title -- The text to go on the Label Widget.
          UValue -- A user value for any purpose.
          Value -- The "value" of the compound widget.
          XSize -- The X size of the Text Widget.
      SetTabNext -- This method allows you to specify which field to go to when a TAB character
         is typed in the text widget. See the Example program below for an example of how to
         use this method.

OBJECT FUNCTIONS METHODS

      Get_Value -- Returns the "value" of the field. No parameters. Will be undefined
          if a "number" field is blank. Should be checked before using:
          IF N_Elements(objectRef->Get_Value()) NE 0 THEN Print, Value is: ', objectRef->Get_Value()
      GetID -- Returns the widget identifier of the compound widget's top-level base.
         (The first child of the parent widget.) No parameters.
      GetLabelSize -- Returns the X screen size of the label widget. No parameters.
      GetTextID -- Returns the widget identifier of the compound widget's text widget.
         No parameters.
      GetTextSize -- Returns the X screen size of the text widget. No parameters.

PRIVATE OBJECT METHODS

      Although there is really no such thing as a "private" method in IDL's
      object implementation, some methods are used internally and not meant to
      be acessed publicly. Here are a few of those methods. I list them because
      it may be these private methods are ones you wish to override in subclassed
      objects.
         MoveTab -- This method moves the focus to the widget identified in the "next" field,
           which must be set with the SetTabNext method. No parameters. Called automatically
           when a TAB character is typed in the text widget.
         Text_Events -- The main event handler method for the compound widget. All
           text widget events are processed here.
         ReturnValue -- This function method accepts a string input value and converts
           it to the type of data requested by the user.
         Validate -- This function method examines all text input and removes unwanted
           characters, depending upon the requested data type for the field. It makes it
           impossible, for example, to type alphanumeric characters in an INTEGER field.

EXAMPLE

      An example program is provided at the end of the FSC_FIELD code. To run it,
      type these commands:
         IDL> .Compile FSC_Field
         IDL> Example

MODIFICATION HISTORY

      Written by: David W. Fanning, 18 October 2000. Based heavily on an earlier
         FSC_INPUTFIELD program and new ideas about the best way to write
         widget objects.
      Added LABEL_LEFT, LABEL_RIGHT, and UNDEFINED keywords. 29 Dec 2000. DWF.
      Modified the way the value is returned in the GET_VALUE method and the
         GET_VALUE function. Modified Example program to demonstrate. 30 Dec 2000. DWF.
      Added NOEDIT and NONSENSITIVE keywords, with corresponding SETEDIT and SETSENNSITIVE
         methods. 19 Jan 2001. DWF.
      Actually followed through with the changes I _said_" I made 29 Dec 2000. (Don't ask....) 13 June 2001. DWF.
      Added GetTextSize and GetLabelSize methods for obtaining the X screen
         size of the text and label widgets, respectively. 21 July 2001. DWF.
      Fixed a problem in SetProperty method where I was setting self.xsize, which doesn't exist. 24 April 2002. DWF.
      Small modification to the SetEdit method. 6 August 2003. DWF.
      Added Highlight keyword. Ported Focus_Events keyword from
         fsc_inputfield.pro. Updated documentation. 17 November
         2004. DWF and Benjamin Hornberger
      Added Has_Focus keyword to the GetProperty method. 18 November
         2004. Benjamin Hornberger
      Fixed bug in GetProperty method (set value to *self.undefined if
         *self.value is undefined. 24 Feb 2004. Benjamin Hornberger
      Modified FOCUS_EVENTS keyword handling so that *all* focus events are now
         passed to specified event handlers. Check event.select to see if the
         widget is gaining or losing focus. 10 August 2005. DWF.
      Added new tabbing functionality, introduced in IDL 6.2. To use tabbing
         functionality natually, the HIGHTLIGHT keywords must be set.
         See included EXAMPLE program for details. 10 August 2005. DWF.
      Added functionality to covert double precision values to strings properly. 30 Nov 2005. DWF.
      Set the default fonts to be the current widget font, rather than the default widget font. 4 Oct 2008. DWF.
      Fixed a problem with validating a float or double value when it was written with
         exponential notation. 2 April 2010. DWF.