[Plib-devel] Active Widgets and Selecting Items in the Main Window
Brought to you by:
sjbaker
From: Fay J. F C. AAC/W. <joh...@eg...> - 2000-08-17 19:42:51
|
My PUI application has a requirement for me to click on an input box in the user interface and then select an item in the main graphics window. The name of the selected item would then appear in the input box. I used the display list feature of OpenGL to implement this. These are the changes to PUI that I needed to make to support it; other parts of the code invoke the active callback if one exists and handle the display list. I present them as one solution to the problem; if someone else has addressed this problem before, I would be interested in hearing of alternative solutions. <begin changes to PUI> Here are the changes to "pu.cxx": - add a global variable just before the definition of "puInit". The new global variable is "puObject *active_widget ;". - inside "puInit", within the "firsttime" block, initialize "active_widget = NULL ;". - at the end of the file add three functions: void puDeactivateWidget () { active_widget = NULL ; } void puSetActiveWidget ( puObject *w ) { active_widget = w ; } puObject *puActiveWidget () { return active_widget ; } I'd like to make these functions inline for execution speed, but to do that I'd have to define them in the "pu.h" header file and so expose the "active_widget" variable to the users. Do other people have a preference one way or the other? Here are the changes to "pu.h": - add prototypes for "puDeactivateWidget", "puSetActiveWidget", and "puActiveWidget" before the definition of "puValue" - add to the definition of "puObject" two new callback variables: "puCallback active_cb" and "puCallback down_cb". The first of these is to be called when the widget is active and the user has clicked the mouse somewhere besides the user interface; the second is to be called when the widget is losing focus (becoming inactive) and the user has activated another widget. The down callback is not strictly necessary for using the display list but I thought it would be a good thing to add. - add to the definition of "puObject" six new methods to set, return, and activate the active and down callbacks. These new methods are strictly analogous to the existing methods for the current callback. Except as noted below, add the following code to the beginning of each "doHit" and "checkKey" method (after the "return FALSE" checks) in the interface: if ( puActiveWidget() && ( this != puActiveWidget() ) ) { puActiveWidget() -> invokeDownCallback () ; puDeactivateWidget () ; } This code invokes the down callback if there is an active widget and the user has selected a different widget. The following exceptions are made: in puGroup, do not add this code to either method; in puOneShot, do not add this code to "doHit" since it is taken care of in "puButton::doHit". The code should also be added to "puButtonBox::checkHit". (This may raise a question about the relative roles of "checkHit" and "doHit" in the case of the "puButtonBox" but I will not go into it here.) Except as noted below, wherever the user interface calls the "invokeCallback" method, add a line to set "puSetActiveWidget ( this ) ;". This assigns the present widget the active widget for later mouse clicks elsewhere. The exception is in "puInput::checkKey", where the interface invokes the callback when the user has pressed <Enter>. In this case, the interface should deactivate the widget. Wherever a widget has its destructor explicitly defined, add code to check whether the present widget is the active widget. If it is, deactivate it. <end changes to PUI> Separate callbacks for activating and deactivating a widget may be useful in other contexts as well. For example, a user may wish to invoke a callback when a "puInput" is being deactivated after the user has entered all the keystrokes, rather than having to check for valid data with each keystroke. John F. Fay joh...@eg... <mailto:joh...@eg...> |