How can I use the arrow keys to move the cursor in the SpinBox text fields?
      | 
     
     20-Jan-04 12:30 GMT
      |  
      
Question:
The left and right arrows in an XmSpinBox are mapped to the spinbox up 
and down arrows. How can I change this so that they move the cursor left 
and right in SpinBox text fields instead?
 
 This can be done by overriding the translations and accelerators for the 
SpinBox and SimpleSpinBox widgets.
 
This can most easily be achieved by including the following in the X 
resources for your application:
 
    *XmSpinBox.translations: \
        <Btn1Down>:             SpinBArm()\n\
        <Btn1Up>:               SpinBDisarm()\n\
        <EnterWindow>:          SpinBEnter()\n\
        <LeaveWindow>:          SpinBLeave()\n\
        :<Key>osfUp:            SpinBNext()\n\
        :<Key>osfDown:          SpinBPrior()\n\
        :<KeyUp>osfUp:          SpinBDisarm()\n\
        :<KeyUp>osfDown:        SpinBDisarm()\n\
        :<KeyUp>osfLeft:        SpinBDisarm()\n\
        :<KeyUp>osfRight:       SpinBDisarm()\n\
        :<Key>osfBeginLine:     SpinBFirst()\n\
        :<Key>osfEndLine:       SpinBLast()
    *XmSpinBox.accelerators: \
        #override\n\
        <Key>osfUp:             SpinBNext()\n\
        <Key>osfDown:           SpinBPrior()\n\
        <KeyUp>osfUp:           SpinBDisarm()\n\
        <KeyUp>osfDown:         SpinBDisarm()\n\
        <KeyUp>osfLeft:         SpinBDisarm()\n\
        <KeyUp>osfRight:        SpinBDisarm()\n\
        <Key>osfBeginLine:      SpinBFirst()\n\
        <Key>osfEndLine:        SpinBLast()
    *XmSimpleSpinBox.translations: \
        <Btn1Down>:             SpinBArm()\n\
        <Btn1Up>:               SpinBDisarm()\n\
        <EnterWindow>:          SpinBEnter()\n\
        <LeaveWindow>:          SpinBLeave()\n\
        :<Key>osfUp:            SpinBNext()\n\
        :<Key>osfDown:          SpinBPrior()\n\
        :<KeyUp>osfUp:          SpinBDisarm()\n\
        :<KeyUp>osfDown:        SpinBDisarm()\n\
        :<KeyUp>osfLeft:        SpinBDisarm()\n\
        :<KeyUp>osfRight:       SpinBDisarm()\n\
        :<Key>osfBeginLine:     SpinBFirst()\n\
        :<Key>osfEndLine:       SpinBLast()
    *XmSimpleSpinBox.accelerators: \
        #override\n\
        <Key>osfUp:             SpinBNext()\n\
        <Key>osfDown:           SpinBPrior()\n\
        <KeyUp>osfUp:           SpinBDisarm()\n\
        <KeyUp>osfDown:         SpinBDisarm()\n\
        <KeyUp>osfLeft:         SpinBDisarm()\n\
        <KeyUp>osfRight:        SpinBDisarm()\n\
        <Key>osfBeginLine:      SpinBFirst()\n\
        <Key>osfEndLine:        SpinBLast()
Alternatively this can be done programmatically. First we need to construct 
the translation and accelerator tables that will be applied to the SpinBox 
or SimpleSpinBox widgets. The following routines (SpinBoxAccelerators and 
SpinBoxTranslations) can be used to perform this task:
 
    #include <stdlib.h>
    #include <X11/Intrinsic.h>
    #include <Xm/Xm.h>
    static _XmConst char SpinBoxTranslationString[] = "\
        <Btn1Down>:             SpinBArm()\n\
        <Btn1Up>:               SpinBDisarm()\n\
        <EnterWindow>:          SpinBEnter()\n\
        <LeaveWindow>:          SpinBLeave()\n\
        :<Key>osfUp:            SpinBNext()\n\
        :<Key>osfDown:          SpinBPrior()\n\
        :<KeyUp>osfUp:          SpinBDisarm()\n\
        :<KeyUp>osfDown:        SpinBDisarm()\n\
        :<Key>osfBeginLine:     SpinBFirst()\n\
        :<Key>osfEndLine:       SpinBLast()";
    static _XmConst char SpinBoxAcceleratorString[] = "\
        #override\n\
        <Key>osfUp:             SpinBNext()\n\
        <Key>osfDown:           SpinBPrior()\n\
        <KeyUp>osfUp:           SpinBDisarm()\n\
        <KeyUp>osfDown:         SpinBDisarm()\n\
        <Key>osfBeginLine:      SpinBFirst()\n\
        <Key>osfEndLine:        SpinBLast()";
    #ifndef   _NO_PROTO
        XtAccelerators SpinBoxAccelerators(void)
    #else  /* _NO_PROTO */
        XtAccelerators SpinBoxAccelerators()
    #endif /* _NO_PROTO */
    {
        static XtAccelerators accelerators = (XtAccelerators) 0 ;
        if (accelerators == (XtAccelerators) 0) {
            accelerators = 
               XtParseAcceleratorTable(SpinBoxAcceleratorString) ;
        }
        return accelerators ;
    }
    #ifndef   _NO_PROTO
        XtTranslations SpinBoxTranslations(void)
    #else  /* _NO_PROTO */
        XtTranslations SpinBoxTranslations()
    #endif /* _NO_PROTO */
    {
        static XtTranslations translations = (XtTranslations) 0 ;
        if (translations == (XtTranslations) 0) {
            translations = 
               XtParseTranslationTable(SpinBoxTranslationString) ;
        }
        return translations ;
    }
Having created the tables we need to set the appropriate widget resources. 
In terms of the SpinBox (as opposed to SimpleSpinBox) widget, it does not 
matter if the accelerators and translations are applied before or after the 
widget is created so either of the following code fragments could be used 
to set these on the widget:
 
    XtTranslations t = SpinBoxTranslations() ;
    XtAccelerators a = SpinBoxAccelerators() ;
    XtSetArg(al[ac], XmNaccelerators, a) ; ac++ ;
    XtSetArg(al[ac], XmNtranslations, t) ; ac++ ;
    spinBox = XmCreateSpinBox(parent, name, al, ac) ;
or
 
    spinBox = XmCreateSpinBox(parent, name, NULL, 0) ;
    XtVaSetValues(spinBox, XmNtranslations, t,
                  XmNaccelerators, a, NULL) ;
For the SimpleSpinBox widget the rules are a little different in that the 
accelerators at least have to be applied at widget creation time:
 
    XtAccelerators a = SpinBoxAccelerators() ;
    XtSetArg(al[ac], XmNaccelerators, a) ; ac++ ;
    simpleSpinBox = XmCreateSimpleSpinBox(parent, name, al, ac) ;
For safety we recommend applying both translations and accelerators in the 
create method for SimpleSpinBox widgets.
 
Using the above methods you should find that the left and right arrow keys 
will move the cursor through the text in the SpinBox TextField widgets 
instead of triggering the SpinBox up and down arrows.
 
Note that the above example includes translations to correct a problem on 
Solaris systems whereby the up and down SpinBox arrows are reversed. You 
can read more about this Solaris Motif bug in an 
earlier Motifdeveloper.com 
technical tip. It is not necessary to include these 
translations for other platforms.
 
To assist you in taking the above and incorporating it into your software we 
have provided the whole of the above as a text file.
Right click   here and 'Save As ...'.
  
   
Sponsored
by X-Designer - The Leading X/Motif GUI Builder
- Click to download a FREE evaluation
 
 
 
Goto top of page
     |