motifdeveloper.com
Sponsored by IST Limited
Formerly MW3: Motif on the World Wide Web [MW3 Logo]
Last Updated
January 25, 2005
 


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 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

 

[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).