# coyote: XCOLORS

- coyote/Graphics
- [Source code]

Description

      The purpose of this program is to interactively change color tables
      in a manner similar to XLoadCT. No common blocks are used so
      multiple copies of XColors can be on the display at the same
      time (if each has a different `Title`). XColors has the ability
      to notify a widget event handler, an object method, or an IDL
      procedure if and when a new color table has been loaded. Brewer
      color tables can also be accessed from this program, if the file
      fsc_brewer.tbl can be found somewhere in your IDL path.
      Events are sent to widgets if the `NotifyID` keyword is used. Object
      methods are called if the `NotifyObj` keyword is used. This program
      is a non-blocking widget unless the `Block` keyword is set.
      .. image:: xcolors.png

Categories

      Graphics

Examples

      To load a color table into 100 colors, starting at color index
       50 and send an event to the widget identified at info.drawID
       in the widget heirarchy of the top-level base event.top, type::
          XCOLORS, NCOLORS=100, BOTTOM=50, NOTIFYID=[info.drawID, event.top]

Author

      FANNING SOFTWARE CONSULTING::
          David W. Fanning
          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

History

      Change History::
         Written by David W. Fanning, 15 April 97.
         Added OBJECT_DATA keyword so that I can get additional information
             about the state of the color table tool into object methods. 21 October 2008. DWF.
         Add REVERSE keyword and Reverse Color Table button. 12 April 2009. DWF.
         In looking for a Brewer color table file, I replaced all FILE_WHICH
             commands with cgFindPathTo commands. 28 April 2009. DWF.
         Made sure all "NOTIFY" data structures have both a "REVERSED" and
             "BREWER" field in them to indicate the status of the XCOLORS program. Also
             inproved the documentation and made it more accurate. 20 Sept 2009. DWF.
         Still a few problems getting the Brewer color tables completely integrated.
             Fixed several bugs with updating color table names and type. 14 Oct 2009. DWF.
         Modified the program to work correctly with a user-supplied color table file. 29 Sept 2010. DWF.
         Fixed a problem I noticed when starting the program with reversed color tables. The
              initial colors were incorrect on subsequent calls. Also made a modification so that
              color index -1 as input is handled properly (ignored). 26 November 2010. DWF.
         Added WINDOW and WINID keywords. 26 January 2011. DWF.
         Changed several Get_Decomposed calls to the more generic cgSetColorState. 15 Jan 2012. DWF.

Copyright

      Copyright (c) 1997-2012, Fanning Software Consulting, Inc.
       routines is identical to the IDL Congrid command, except that it
      les a problem with floating divides by zero properly.

Params

      tlb: in, required
          The widget identifier of the widget that just died.
       is a procedure to load color tables into a restricted color range of the physical
      r table. It is a highly simplified, but much more powerful, version of XLoadCT.

Keywords

      block: in, optional, type=boolean, default=0
         If this keyword is set, the program will try to block the
         IDL command line. Note that this is only possible if no other
         widget program is currently blocking the IDL command line. It
         is much more reliable to make XCOLORS a modal widget (see the MODAL
         keyword), although this can generally only be done when XCOLORS
         is called from another widget program.
      brewer: in, optional, type=boolean, default=0
         Set this keyword if you wish to use the Brewer Colors, as explained
         in this reference: http://www.idlcoyote.com/color_tips/brewer.html. The
         file, `fsc_brewer.tbl <http://www.idlcoyote.com/programs/fsc_brewer.tbl>`
         must be found somewhere in your IDL path for this option to be available.
         Note that if this file is found, the Brewer colors are automatically added
         to the program as an option. In this case, the BREWER keyword just makes sure
         this is the initial user choice.
      bottom: in, optional, type=integer, default=0
         The lowest color index of the colors to be changed.
      colorinfo: out, optional
         This output keyword will return either a pointer to a color information structure
         (if the program is called in a non-modal fashion) or a color information structure
         (if the program is called in modal or blocking fashion). The color information
          structure is an anonymous structure defined like this::
              struct = { R: BytArr(!D.Table_Size), $ ; The current R color vector.
                         G: BytArr(!D.Table_Size), $ ; The current G color vector.
                         B: BytArr(!D.Table_Size), $ ; The current B color vector.
                         NAME: "", $                 ; The name of the current color table.
                         INDEX: 0, $                 ; The index number of the current color table.
                         TYPE: "", $                 ; The type of color table (e.g, BREWER or IDL).
                         BREWER: 0, $                ; Set to 1 if using BREWER color tables, else to 0.
                         REVERSED: 0B }              ; Set to 1 if the color table is reversed.
         If a pointer to the structure is obtained, you will be responsible
         for freeing it to prevent memory leakage::
              XColors, ColorInfo=colorInfoPtr
              Print, "Color Table Name: ", (*colorInfoPtr).Name
              Ptr_Free, colorInfoPtr
         Note that that Name field will be "Unknown" and the Index field will
         be -1 until a color table is actually selected by the user. You are
         responsible for checking this value before you use it.
         When called in modal or blocking fashion, you don't have to worry about freeing
         the pointer, since no pointer is involved::
              XColors, /Block, ColorInfo=colorInfoData
              Help, colorInfoData, /Structure
              Print, "Color Table Name: ", colorInfoData.Name
      data: in, optional
         This keyword can be set to any valid IDL variable. If
         the variable is defined, the specified object method or notify
         procedure will be passed this variable via a DATA keyword. This
         keyword is defined primarily so that Notify Procedures are compatible
         with the XLOADCT way of passing data. It is not strictly required,
         since the _EXTRA keyword inheritance mechanism will allow passing
         of *any* keyword parameter defined for the object or procedure that is
         to be notified.
      drag: in, optional, type=boolean, default=0
         Set this keyword if you want colors loaded as you drag
         the sliders. Default is to update colors only when you release
         the sliders. Use of this keyword is greatly discouraged.
      file: in, optional, type=string, default="colors1.tbl"
         A name of a color table file. The supplied colors1.tbl file is used by default.
      group_leader: in, optional, type=long
         The group leader identifier for this program. When the group
           leader is destroyed, this program will be destroyed.
      index: in, optional, type=integer
         The index of the color table to start up. If provided, a color
         table of this index number is loaded prior to display. Otherwise,
         the current color table is used. Set this keyword if you wish
         to have the index number of the event structure correct when
         the user CANCELs out of the progam.
      modal: in, optional, type=boolean, default=0
         Set this keyword (along with the GROUP_LEADER keyword) to
         make the XCOLORS dialog a modal widget dialog. Note that NO
         other events can occur until the XCOLORS program is destroyed
         when in modal mode.
      ncolors: in, optional, type=integer, default=256
         Set this keyword to the number of colors to load when a color table
         is selected.
      nosliders: in, optional, type=boolean, default=0
         If this keyword is set, the color stretch and color gamma
         sliders are not displayed. This would be appropriate, for example,
         for programs that just load pre-defined color tables.
      notifyid: in, optional
         A 2-column by n-row array that contains the IDs of widgets
         that should be notified when XCOLORS loads a color table. The first
         column of the array is the widgets that should be notified. The
         second column contains IDs of widgets that are at the top of the
         hierarchy in which the corresponding widgets in the first column
         are located. (The purpose of the top widget IDs is to make it
         possible for the widget in the first column to get the "info"
         structure of the widget program.) An XCOLORS_LOAD event will be
         sent to the widget identified in the first column. The event
         structure is defined like this::
            event = {XCOLORS_LOAD, ID:0L, TOP:0L, HANDLER:0L, $
               R:BytArr(!D.TABLE_SIZE < 256), G:BytArr(!D.TABLE_SIZE < 256), $
               B:BytArr(!D.TABLE_SIZE < 256), INDEX:0, NAME:"", $
               TYPE:"", BREWER:0, REVERSED:0}
         The ID field will be filled out with NOTIFYID[0, n] and the TOP
         field will be filled out with NOTIFYID[1, n]. The R, G, and B
         fields will have the current color table vectors, obtained by
         exectuing the command TVLCT, r, g, b, /Get. The INDEX field will
         have the index number of the just-loaded color table. The name
         field will have the name of the currently loaded color table.
         The TYPE field with be "BREWER" if a Brewer color table was loaded,
         or "IDL" otherwise. The BREWER field will be set to 1 if a Brewer
         color table was loaded, or to 0 otherwise. The REVERSED field will
         be set to 1 if the color table is reversed, or to 0 otherwise.
         Note that XCOLORS can't initially tell *which* color table is
         loaded, since it just uses whatever colors are available when it
         is called. Thus, it stores a -1 in the INDEX field to indicate
         this "default" value. Programs that rely on the INDEX field of
         the event structure should normally do nothing if the value is
         set to -1. This value is also set to -1 if the user hits the
         CANCEL button. (Note the NAME field will initially be "Unknown").
         Typically the XCOLORS button will be defined like this::
              xcolorsID = Widget_Button(parentID, Value='Load New Color Table...', $
                 Event_Pro='Program_Change_Colors_Event')
         The event handler will be written something like this::
              PRO Program_Change_Colors_Event, event
                 ; Handles color table loading events. Allows colors be to changed.
              Widget_Control, event.top, Get_UValue=info, /No_Copy
              thisEvent = Tag_Names(event, /Structure_Name)
              CASE thisEvent OF
                 'WIDGET_BUTTON': BEGIN
                      ; Color table tool.
                    XColors, NColors=info.ncolors, Bottom=info.bottom, $
                       Group_Leader=event.top, NotifyID=[event.id, event.top]
                    ENDCASE
                 'XCOLORS_LOAD': BEGIN
                      ; Update the display for 24-bit displays.
                    Device, Get_Visual_Depth=thisDepth
                    IF thisDepth GT 8 THEN BEGIN
                    WSet, info.wid
                     ...Whatever display commands are required go here. For example...
                     TV, info.image
                  ENDIF
                  ENDCASE
               ENDCASE
               Widget_Control, event.top, Set_UValue=info, /No_Copy
               END
      notifyobj: in, optional, type=structure
         A vector of structures (or a single structure), with each element of the vector
         defined as follows::
              struct = {XCOLORS_NOTIFYOBJ, object:Obj_New(), method:''}
         where the Object field is an object reference, and the Method field
         is the name of the object method that should be called when XCOLORS
         loads its color tables::
              ainfo = {XCOLORS_NOTIFYOBJ, a, 'Draw'}
              binfo = {XCOLORS_NOTIFYOBJ, b, 'Display'}
              XColors, NotifyObj=[ainfo, binfo]
         Note that the XColors program must be compiled before these structures
         are used. Alternatively, you can put this program, named
         "xcolors_notifyobj__define.pro" (*three* underscore characters in this
         name!) in your PATH::
              PRO XCOLORS_NOTIFYOBJ__DEFINE
               struct = {XCOLORS_NOTIFYOBJ, OBJECT:Obj_New(), METHOD:''}
              END
         Or, you can simply define this structure as it is shown here in your code.
         "Extra" keywords added to the XCOLORS call are passed along to
         the object method, which makes this an alternative way to get information
         to your methods. If you expect such keywords, your methods should be defined
         with an _Extra keyword.
         If you set the /OBJECT_DATA keyword, the same structure defined for the
         COLORINFO keyword above will be passed to your object method via an
         XCOLORS_DATA keyword that you will have to define for the method.
      notifypro: in, optional, type=string
         The name of a procedure to notify or call when the color
         tables are loaded. If the DATA keyword is also defined with a valid
         IDL variable, it will be passed to this program via an DATA keyword.
         But note that *any* keyword appropriate for the procedure can be used
         in the call to XCOLORS. For example, here is a procedure that re-displays
         an image in the current graphics window::
              PRO REFRESH_IMAGE, Image=image, _Extra=extra, WID=wid
              IF N_Elements(wid) NE 0 THEN WSet, wid
              cgImage, image, _Extra=extra
              END
         This program can be invoked with this series of commands::
              IDL> Window, /Free
              IDL> cgImage, image, Position=[0.2, 0.2, 0.8, 0.8]
              IDL> XColors, NotifyPro='Refresh_Image', Image=image, WID=!D.Window
         Note that "extra" keywords added to the XCOLORS call are passed along to
         your procedure, which makes this an alternative way to get information
         to your procedure. If you expect such keywords, your procedure should
         be defined with an _Extra keyword as illustrated above.
      object_data: in, optional, type=boolean, default=0
         Set this keyword if you wish color information to be
         supplied to your object notification method via an XCOLORS_DATA
         keyword. This keyword is ignored unless the NOTIFYOBJ keyword is
         also used. The color information is supplied as a structure and is
         defined in the COLORINFO keyword definition above.
      reverse: in, optional, type=boolean, default=0
         If this keyword is set, the color table is reversed and the
         Reverse Color Table button is set on.
      title: in, optional, type='string'
         This is the window title. It is "Load Color Tables" by default. The program
         is registered with the name 'XCOLORS:' plus the TITLE string. The "register
         name" is checked before the widgets are defined. If a program with that name
         has already been registered you cannot register another with that name. This
         means that you can have several versions of XCOLORS open simultaneously as long
         as each has a unique title or name. For example, like this::
             IDL> XColors, NColors=100, Bottom=0, Title='First 100 Colors'
             IDL> XColors, NColors=100, Bottom=100, Title='Second 100 Colors'
      window: in, optional, type=boolean, default=0
         Set this keyword to send the colors to a Coyote Graphics cgWindow program.
      winid: in, optional, type=integer
         The window index number of a Coyote Graphics cgWindow program to receive the color vectors.
      xoffset: in, optional, type=integer
         This is the X offset of the program on the display. The program will be placed
         approximately in the middle of the display by default.
      yoffset: in, optional, type=integer
         This is the Y offset of the program on the display. The program will be placed
         approximately in the middle of the display by default.
      _extra: in, optional
         The keyword inheritance mechanism will pick up and pass along to any method or procedure
         to be notified any keywords that are defined for that procedure. Note that you should be
         sure that keywords are spelled correctly. Any mis-spelled keyword will be ignored.