pc@ukc.ac.uk (R.P.A.Collinson) (01/22/89)
I have begun to write X applications programs recently and have come across what I believe to be a deficiency in the way that event translations are handled. It may be that I am missing something and there is a solution to this, if so then please let me know. Example problem: Create a text data entry area which acts in the exactly the same way as the existing text widget but which only permits one line of data to be entered. All actions which will cause a newline to be entered - or which deal with line oriented functions (e.g. scroll-one-line-down()) should cause the bell to ring on the console. This *should* interwork in the same applications program with `normal' text area widgets. Sample use: a dialog box asking for a filename. Current solution (1): You supply a translation table which binds <Key>Return to Bell() rather than <Key>Return: newline() This is not good enough to my thinking. It means that the application writer has to second guess the bindings which the user may or may not supply for all these actions. What is *really* needed is the ability to alter the action of newline(). Registering an action table for newline() does not work because this is not widget specific. It alters every newline() action in the program. Registering an action table for newline() and then calling the old newline() code does not work because the old newline code is private. Current solution (2): Write a new widget which replicates most of the code in the text widget. Question: Why should all problems be solved by writing widgets? I do intend to get involved with the full horror of this at some point in the near future but at the moment it seems to a good idea to write applications programs. Eventually I guess we will enter the realm of binary only X libraries and so this solution will not be available to people. Anyway, all I want to do is to be able to selectively replace the actions for a known widget with my own actions. After all a OneLineTextWidget will be forced to copy most of the source from a normal TextWidget which seems a little wasteful. Any help gratefully received. Peter Collinson pc@ukc.ac.uk
sundar@WHEATIES.AI.MIT.EDU (Sundar Narasimhan) (01/25/89)
Current solution (2): Write a new widget which replicates most of the code in the text widget. You are right. I decided after careful evaluation (and actually using the text widgets provided in the Athena and Hp Widget sets) to do just this. (But I don't think that it is the translation mechanism that is at fault, but rather the poor interface or hooks provided by current text widgets to the application writer). The way I think it should have been done is to have before, during, and after procedures that an application can alter or supply (these could be just callbacks but you really want to have something more like Lisp machine method combinations). The hp widget actually provides you such a facility (it has Verify callbacks on modification, for example). With this capability writing a field editor that returns on carriage return would be simple. I have, in fact a command and argument parser, that for example dispatches on characters like ' ' to attempt completing what the user typed, provide help etc. Notice that some of these operations may involve modifying the text, the cursor position etc.. operations which are very cumbersome to do in the current text edit widgets at the application level. It will also provide you a simple way to implement a tty window -- (a widget that just scrolls error messages is actually hard to do with the present text widgets -- I know this facility can also be gotten by running xterm in slave mode but then you'd have a whole extra process to contend with). I think that such an interface to a text widget is more powerful than the ones provided by the current widgets, and will make the widget useable in more applications. (Mine is currently being used by programs in a multiprocessor development environment, a plotter program, and an experimenatal motion vision analysis package -- but it runs only on Suns at this time). -Sundar
kit@ATHENA.MIT.EDU (Chris D. Peterson) (01/27/89)
> You supply a translation table which binds > <Key>Return to Bell() > rather than > <Key>Return: newline() > This is not good enough to my thinking. It means that the application > writer has to second guess the bindings which the user may or may not > supply for all these actions. There is no need to replace the entire translation table, just use XtOverrideTranslations() in your application to override only the translation for Return. This is what xman does for its "search" prompter, the code is publically avaliable: R3: clients/xman/ Even better is to add a line it the AppDefaults file that overrides the translations. foo.bar.baz.text_widget: #override \n\ <Key>Return: newline() Chris D. Peterson MIT X Consortium / Project Athena Net: kit@athena.mit.edu Phone: (617) 253 - 1326 USMail: MIT - Room E40-321 77 Massachusetts Ave. Cambridge, MA 02139
alan@metasoft.UUCP (Alan Epstein) (01/27/89)
In article <8901261848.AA02930@DORA.MIT.EDU>, kit@ATHENA.MIT.EDU (Chris D. Peterson) writes: > There is no need to replace the entire translation table, just use > XtOverrideTranslations() in your application to override only the > translation for .... In tweaking the asciiStringWidget, I wanted to remap the <Key> event to do an additional step. Unfortunately, the placement of the <Key> event in the default translation table with respect to other 'modified' <Key> events, allowed it to do the right thing, whereas adding an #override <Key> event caused the other modified <Key> events to be ignored. Does this mean that XtOverrideTranslations places the new bindings at the start of the table? ----------------------------- Alan Epstein Meta Software Corp UUCP: ...bbn!metasoft!alan 150 Cambridgepark Dr Internet/ARPA: alan%metasoft@bbn.com Cambridge, MA 02140 USA -----------------------------
pc@ukc.ac.UK (Peter Collinson) (01/28/89)
You miss the point. Suppose the user has bound ^U to previous-line() because they believe that ^U means `UP' rather than ^P being `PREVIOUS'. The current mechanism does not allow me as an application writer to trap that... I will have trapped and replaced the binding ^P -> previous-line() I want to replace the ACTION previous-line() by something and not the bindings.
rlh2@ukc.ac.uk (Richard Hesketh) (01/31/89)
In article <8901261848.AA02930@DORA.MIT.EDU> kit@ATHENA.MIT.EDU (Chris D. Peterson) writes: > >> You supply a translation table which binds > >> <Key>Return to Bell() > >> rather than > >> <Key>Return: newline() > >> This is not good enough to my thinking. It means that the application >> writer has to second guess the bindings which the user may or may not >> supply for all these actions. > >There is no need to replace the entire translation table, just use >XtOverrideTranslations() in your application to override only the >translation for Return. > I think the point Peter was trying to make is that although it is very easy to override the event-to-action bindings by replacing the action called when a particular event sequence is caught. It is impossible to replace the action side of the translations. For example he wants to catch all calls to the "newline()" action and therefore wishes to replace the "newline()" action defined in the textWidgetClass with a "newline()" action defined by the application. The fact that the user can modify the translations from a defaults file so that s/he could specify that the "newline()" action is called by, say the <Meta><Shift><Key>[ sequence cannot be guessed by the application. Just because a widgetclass defines actions does not mean that an application wants them to be used. The application may not want a particular action to be ever called in a particular widget instance. However the action can still be called by the user specifying an event-to-action binding in a defaults file and therefore upsets the designed interface! Would any of the toolkit designers care to comment on the usefulness of having a facility to override the action tables defined in widget classes for particular widget instances? Would the inclusion of an action resource in the core part of the instance record be applicable or are we missing something important which precludes this facility? Richard Hesketh : rlh2@ukc.ac.uk ..!mcvax!ukc!rlh2 --- Computing Lab., University of Kent at Canterbury, Canterbury, Kent, CT2 7NF, England.
asente@decwrl.dec.com (Paul Asente) (02/02/89)
In article <31@harrier.ukc.ac.uk> rlh2@ukc.ac.uk (Richard Hesketh) writes: >Would any of the toolkit designers care to comment on the usefulness of >having a facility to override the action tables defined in widget classes >for particular widget instances? Would the inclusion of an action resource >in the core part of the instance record be applicable or are we missing >something important which precludes this facility? I'm always happy to comment on anything whatsoever! It would definitely be useful to be able to change action bindings. For example, you might have a text editing widget with an action for "visit new file". In a particular application, you might want this to call your own version of the action procedure to make use of additional context (the current directory, for example). Modifying the translation table to do this only works assuming that the user hasn't changed the default binding for this action (e.g. the default binding might be escape-f for find file, but the user might have rebound it to control-x control-v). What is really needed here is a way to rebind an action name to a different or an additional action procedure. While this would be useful on a per-widget rather than a per-class basis, that is unlikely to happen since it would involve changing the core widget records, something we are reluctant to do any more. However, it could certainly be done on a per-class basis, and the new class action procedure could do different things depending upon the widget it's being passed. You really need several new functions: XtAddActionName(widgetClass, actionName, newActionName) to add a new name to an action procedure so you can still get to it after you do an XtReplaceActionBinding(widgetClass, actionName, newActionProcedure) to replace an action procedure with a new one. You also need XtCallActionProc(widget, actionName, event, params, numParams) to call the original action procedure from within your new action procedure, if appropriate. This last function is generally useful, anyway; application should be able to call action procedures by name. Anybody on the intrisics list think these are important enough to make into a formal proposal? -paul asente asente@decwrl.dec.com decwrl!asente