motifdeveloper.com
Sponsored by IST Limited
Formerly MW3: Motif on the World Wide Web [MW3 Logo]
Last Updated
November 18, 2002
 


X-Designer - The Leading X/Motif GUI Builder - Click to download a FREE evaluation
 

motifdeveloper.com
Home
About the site
Bulletin Board
News Archive
OpenGroup News
Events
Search
Frequently Asked Questions
The Motif FAQ
X/Motif FAQs
General FAQs
Ask Antony
Latest Q & A
All Q & As
Submit Question
Tips & Pointers
Code Examples
Software
OpenMotif
Widget Sets
GUI Toolkits & Libraries
Motif suppliers
Non-commercial S/W
Commercial Software
Multimedia
Miscellaneous
Organizations
Docs & Pubs
X/Motif Newsgroups
Security
Internationalization
Feedback
Feedback Form
Contributors
 

How can I change the colors in a TextField as characters are typed?

7-Feb-01 12:00 GMT

Question: In a TextField widget with white background and black foreground, how can I get the background to change to a different color as soon as I type in a first new character. Then, when I have finished entering the new data, and ONLY when I hit the return key, the original background color returns?

Colors in a TextField can be changed as characters are typed using the following methods:

  • Add an XmNmodifyVerifyCallback which simply changes the Text Colors from the normal background and foreground
    
    
  • Add an XmNactivateCallback which reverts the foreground and background back to the normal default
    
    
  • For safety, add an XmNfocusOutCallback which also reverts the colors. This is in case the user moves out of the TextField using the mouse pointer, rather than presses the Activate key.

Utility Routines

Firstly, we define a utility routine to change the TextField colors: this routine is generalized to change both background and foreground, although the question as originally framed was only concerned with the background. This scheme allows for either both background and foreground changes, or for a single resource change.

     /*
     ** Motif 1.2 does not define this, but Motif 2.1 does
     */

     #ifndef   XmUNSPECIFIED_PIXEL
     #define   XmUNSPECIFIED_PIXEL    ((Pixel) (~0))
     #endif /* XmUNSPECIFIED_PIXEL */

     static void set_text_colors(Widget text, Pixel new_fg, Pixel new_bg)
     {
	  Pixel    current_fg = XmUNSPECIFIED_PIXEL ;
	  Pixel    current_bg = XmUNSPECIFIED_PIXEL ;
	  Arg      argv[2] ;
	  Cardinal argc = 0 ;

	  if (new_fg != XmUNSPECIFIED_PIXEL) {
	       XtSetArg (args[argc], XmNforeground, ¤t_fg) ; argc++ ;
	  }

	  if (new_bg != XmUNSPECIFIED_PIXEL) {
	       XtSetArg (args[argc], XmNbackground, ¤t_bg) ; argc++ ;
	  }

	  if (argc > 0) {
	       XtGetValues (text, argv, argc) ;

	       argc = 0 ;

	       if ((new_fg != XmUNSPECIFIED_PIXEL) && (new_fg != current_fg)) {
		    XtSetArg (args[argc], XmNforeground, new_fg) ; argc++ ;
	       }

	       if ((new_bg != XmUNSPECIFIED_PIXEL) && (new_bg != current_bg)) {
		    XtSetArg (args[argc], XmNbackground, new_bg) ; argc++ ;
	       }

	       if (argc > 0) {
		    XtSetValues (text, argv, argc) ;
	       }
	  }
     }

Secondly, a utility to convert from a color name to a Pixel value. This is not actually used in the example callbacks below, but is provided for those who require the extra information. The callbacks below assume that the Pixel values are already allocated.

     Pixel convert_color_name_to_pixel(Widget any_widget, char *name)
     {
	  XrmValue from_value ;
	  XrmValue to_value ;

	  from_value.addr = name ;
	  from_value.size = strlen(name) + 1 ;
	  to_value.addr   = (XtPointer) 0 ;

	  XtConvertAndStore(any_widget, XmRString, &from_value, XmRPixel, &to_value) ;

	  if (to_value.addr != (XtPointer) 0) {
	       return (*(Pixel *) to_value.addr) ;
	  }

	  return XmUNSPECIFIED_PIXEL ;
     }

The XmNmodifyVerifyCallback

This routine simply changes the foreground/background colors of the TextField to the stand-out colors. We assume here that the Pixel values associated with the requirements are already allocated.

     extern Pixel special_foreground ;
     extern Pixel special_background ;

     void text_modify_verify_callback
		(Widget text, XtPointer client_data, XtPointer call_data)
     {
	  /* Simple: just call the text color change utility routine              */
	  /* If you only want foreground, pass XmUNSPECIFIED_PIXEL as background, */
	  /* and vice versa for background-only changes.                          */

	  set_text_colors(text, special_foreground, special_background) ;
     }

The XmNactivateCallback and XmNfocusOutCallback

These are identical in effect, so you could add the same callback to each. You need to cache the original pre-editing TextField foreground and background colors before applying the callback(s). The following kind of code can be used for this purpose:

     Pixel cached_text_foreground ;
     Pixel cached_text_background ;

     XtVaGetValues (text,
		    XmNforeground, &cached_text_foreground,
		    XmNbackground, &cached_text_background,
		    NULL) ;

The callbacks themselves are therefore as follows:

     void text_focus_out_callback
		(Widget text, XtPointer client_data, XtPointer call_data)
     {
	  /* Again simple: just call the text color change utility routine      */
	  /* but this time using the cached original colors.                    */
	  /* if you are only changing the foregrounds, pass XmUNSPECIFIED_PIXEL */
	  /* as the background parameter (and vice versa).                      */

	  set_text_colors(text, cached_text_foreground, cached_text_background) ;
     }

     void text_activate_callback
		(Widget text, XtPointer client_data, XtPointer call_data)
     {
	  /* As above */

	  set_text_colors(text, cached_text_foreground, cached_text_background) ;
     }

An Example

A simple application which contains a single dialog with two TextFields configured for color change is given in the following sources. The application has been built using X-Designer for speed, although you don't need the GUI builder in any way to read, understand, or build the program. The design file is included with the sample sources, in case anyone is interested or has use of this. The example consists of the following code:

  • TextColors.c - the code which creates the widget hierarchy
  • TextColors.h - widget declarations
  • TextColors_stubs.c- callback code
  • Makefile - a general purpose Makefile for the application. Its configured for Solaris, but at the top of the file are rules for various platforms: simply comment out the Solaris section, and uncomment your platform as required.
  • TextColors.xd - the X-Designer design save file. Feel free to ignore this.

Alternatively download a tar archive, TextColors.tar, of all the above source files. If you are using Netscape Navigator you may have to hold down the Shift key when you click on the file name in order to ensure that you are prompted to save the file.

Optimizations

The scheme above will perform an XtGetValues() call on every keyboard event in the TextField. Although there are generally far more expensive things going on in an application which are more worthy of attention, there are a few slight modifications which could be considered, and which are left as an exercise for the reader:

  • Don't call the color change routine if the user is deleting characters. At present, if the user switches into the TextField, and selects characters with the mouse, then deletes these, the contents changes to the stand-out color only when the delete key is issued. This may or may not be as required.
         void text_modify_verify_callback
    		(Widget text, XtPointer client_data, XtPointer call_data)
         {
    	  XmTextVerifyCallbackStruct *tp =
    				(XmTextVerifyCallbackStruct *) call_data ;
    
    	  if (call_data->text->length > 0) {
    	       set_text_colors(text, special_foreground, special_background) ;
    	  }
         }
    
  • Add an XmNfocusInCallback which sets a flag such that the colors are checked only once, if and only if a character is typed.
         Boolean change_colors = False ;
    
         void text_focus_in_callback
    		(Widget text, XtPointer client_data, XtPointer call_data)
         {
    	  change_colors = True ;
         }
    
         void text_modify_verify_callback
    		(Widget text, XtPointer client_data, XtPointer call_data)
         {
    	  XmTextVerifyCallbackStruct *tp =
    				(XmTextVerifyCallbackStruct *) call_data ;
    
    	  if (change_colors && (tp->text->length > 0)) {
    	       set_text_colors(text, special_foreground, special_background) ;
    
    	       change_colors = False ;
    	  }
         }
    
    This scheme ought to work in principle regardless of the number of TextFields involved, provided that they share the same XmNmodifyVerifyCallback. There should be no need to make sure that a XmNfocusOutCallback sets the change flag to false, since any subsequent focus-in for any TextField will simply reset it.
    
    
  • The scheme could indeed be modified so that focus-in changes the text to the stand-out mode, focus-out reverts to normal colors, regardless of whether anything is typed. This would do away with the need for a modify verify callback. In effect, it simply becomes a kind of special focus highlighting, and is not related to any typing. This, however, is not the same as the question requirements as originally stated.
         void text_focus_in_callback
    		(Widget text, XtPointer client_data, XtPointer call_data)
         {
    	  set_text_colors(text, special_foreground, special_background) ;
         }
    
         void text_focus_out_callback
    		(Widget text, XtPointer client_data, XtPointer call_data)
         {
    	  set_text_colors(text, cached_text_foreground, cached_text_background) ;
         }
    
  • A combination of effects is also possible, so that the background is changed on focus in, leaving the original foreground, which is only modified on text change, and the foreground reverts on activate.
         void text_focus_in_callback
    		(Widget text, XtPointer client_data, XtPointer call_data)
         {
    	  set_text_colors(text, XmUNSPECIFIED_PIXEL, special_background) ;
         }
    
         void text_focus_out_callback
    		(Widget text, XtPointer client_data, XtPointer call_data)
         {
    	  set_text_colors(text, cached_text_foreground, cached_text_background) ;
         }
    
         void text_modify_verify_callback
    		(Widget text, XtPointer client_data, XtPointer call_data)
         {
    	  set_text_colors(text, special_foreground, XmUNSPECIFIED_PIXEL) ;
         }
    
         void text_activate_callback
    		(Widget text, XtPointer client_data, XtPointer call_data)
         {
    	  set_text_colors(text, cached_text_foreground, XmUNSPECIFIED_PIXEL) ;
         }
    

 


Sponsored by X-Designer - The Leading X/Motif GUI Builder - Click to download a FREE evaluation

 

Goto top of page

 

[IST Limited]
IST Limited is the
proud sponsor of motifdeveloper.com.
 

Thanks to all the contributors to these pages.

Privacy Policy

 
"Motif" is a registered trademark of The Open Group. All other trademarks are the property of their respective owners.

Some articles/papers here have their own copyright notice. All other information is copyright ©1999-2008 IST Limited

[CommerceOne] MW3 site originally by Ken Sall of Commerce One (formerly Century Computing).