FYI: Your dialog isn't Modeless


Subject: FYI: Your dialog isn't Modeless
From: Paul Cubbage (paul@opencountry.net)
Date: Fri May 26 2000 - 23:53:41 CDT


I bcc'd Jef Raskin my comments and he replied:

I have some comments on Martin's note (I am not sure who is
communicating to
whom here).

"Open 4 windows on your desktop, now which window does your symbol go
into?" From a UI point of view the answer is "The Window Most Recently
Focussed".

I disagree. As soon as you have windows, you have modes. If one of the
windows has the system focus, then it will behave differently than the
other
windows if, say, you try to type into it. Any other window will require
a
click in it (or some such) before you can type, but that one can be
typed
into directly. I think there is a quote in my book about windows being
modes
in sheep's clothing.

Jef
-------------------
Paul Cubbage wrote:
>
> FWIW.
> Jef Raskins new book, "The Humane Interface" is the best thing I've seen
> on interface design, modeless states, dealing with focus... He
> originated the Mac project designed the Canon CAT, probably the best
> word processor machine ever done.
>
> Martin Sevior wrote:
> >
> > HI everyone,
> >
> > I thought it would be a good idea to provide some documentation for the
> > modeless dialog framework so here it is :-)
> >
> > A while ago I thought I had a way to implement a modeless "Insert SYmbol"
> > dialog. Paul Rohr then asked the question. "Open 4 windows on your
> > desktop, now which window does your symbol go into?" From a UI point of
> > view the answer is "The Window Most Recently Focussed". The modeless
> > dialog framework makes this happen.
> >
> > The basic ideas are as follows:
> >
> > hj and Mike provided the unix and Windows code to recognise a change in
> > the focus state of the open frames. Upon receiving an a focus_in event a
> > method in fv_View is called. Within this method is a call to an xap_App
> > method
> >
> > XAP_App::rememberFocussedFrame( void * pJustFocussedFrame)
> >
> > This records the most recently focussed frame in a protected variable in
> > xap_App. xap_App is the bottom most class uniformly accessible to all the
> > useful abi classes.
> >
> > So now a modeless dialog knows which fv_View to interogate or manipulate.
> > All it has to do is look up this frame pointer then call
> > "getCurrentFrame". There are a couple of ways to do this but the best
> > is via the xap_Dialog_Modeless class method
> >
> > xap_Dialog_Modeless::getActiveFrame()
> >
> > Which returns the most recently focussed frame to any child class of
> > xap_Dialog_Modeless. This method has checks to verify the frame is
> > actually present. If it isn't present it returns oldest running frame.
> > xap_Dialog_Modeless has a couple of other useful methods available to
> > child classes and abi in general. These are:
> >
> > isRunning() : UT_TRUE if the dialog is running.
> > modeless_cleanup() : Which cleans up the various pointers and tables to do
> > with the dialog. You run this upon closing the
> > dialog.
> >
> > In addition there is code in xap_App to keep track of currently
> > running modeless dialogs. Things we have to watch out for are:
> >
> > 1. If the dialog is running just activate it, don't rebuild it.
> >
> > The activate() method must be implemented seperately in the platform
> > specific code for every modeless dialog via the
> >
> > XAP_Dialog_Modeless::activate(void)
> >
> > virtual function. The code for this is really easy. Look at either
> > Insert_Symbol or WordCount for examples.
> >
> > 2. If abi is closed, gracefully shut down the modeless dialogs.
> >
> > This method must also be implemented seperately in the platform specific
> > code for every modeless dialog via:
> >
> > XAP_Dialog_Modeless::destroy(void)
> >
> > In addition these is code in the unix modeless dialogs to make xap_App
> > remember the dialog in its tables. This is:
> >
> > void XAP_App::rememberModelessId( UT_sint32 id ,
> > XAP_Dialog_Modeless * pDialog)
> >
> > This call should be made within RunModeless immediately after calling the
> > dialog for the first time. It should NOT be called more than once for each
> > dialog otherwise bad things will happen.
> >
> > There is one other magic function needed in every gtk modeless dialog. It
> > is
> >
> > connectFocusModeless(GTK_WIDGET(mainWindow),m_pApp)
> >
> > this function is placed in the unix platform sepefic code just after the
> > top level widget (called mainWindow) is created.
> >
> > Finally Bruce has implemented a scheme to notify all the running modeless
> > dialogs of changes in the active frame. The uses the
> >
> > setActiveFrame(XAP_Frame *pFrame);
> >
> > method. This function must be provided by every modeless dialog and it is
> > executed by xap_App upon a change of Active Frame. pFrame is the new
> > active frame passed down from xap_App.
> >
> > setActiveFrame is useful to enable the modeless dialog to change it's
> > behaviour upon receiving notice of a change in the active frame. For
> > example "WordCount" changes the statistics displayed to reflect the
> > current active frame from the setActiveFrame method.
> >
> > In addition the function:
> >
> > virtual void notifyCloseFrame(XAP_Frame *pFrame);
> >
> > Must be present and coded."notifyCloseFrame" is called when the active
> > frame is closed. The Windows front end needs this. See Bruce's code in
> > Insert_Symbol for examples.
> >
> > In summary:
> > ----------------------------------------------------------------------
> > In ap_EditMethods you invoke a Modeless dialog like this:
> >
> > <Usual stuff about raising frames etc.> then:
> >
> > AP_Dialog_WordCount * pDialog
> > = (AP_Dialog_WordCount
> > *)(pDialogFactory->requestDialog(AP_DIALOG_ID_WORDCOUNT));
> > UT_ASSERT(pDialog);
> >
> > if(pDialog->isRunning()) // Check to see if the dialog is running
> > {
> > pDialog->activate(); // if so activate it
> > }
> > else
> > {
> > pDialog->setCount(pView->countWords()); // Otherwise
> > pDialog->runModeless(pFrame); // Construct it.
> > }
> > UT_Bool bOK = UT_TRUE;
> > return bOK;
> > }
> > ---------------------------------------------------------------------------
> > You must supply code for the following functions in your modeless dialog.
> >
> > //------------------------------------------------------------
> > // All these are needed for a modeless dialog
> >
> > virtual void useStart(void);
> > virtual void useEnd(void);
> > virtual void runModal(XAP_Frame * pFrame) = 0;
> > virtual void runModeless(XAP_Frame * pFrame) = 0;
> > virtual void destroy(void)=0;
> > virtual void activate(void)=0;
> > void setActiveFrame(XAP_Frame *pFrame);
> > virtual void notifyCloseFrame(XAP_Frame *pFrame){};
> >
> > The useStart(), useEnd() and runModal() are cruft from the fact
> > XAP_Modeless_Dialog inherits from XAP_Dialog_AppPersistent. They can be
> > stubbed if you want.
> > --------------------------------------------------------------------------
> >
> > In the runModeless method you must include the code:
> >
> > void XAP_App::rememberModelessId( UT_sint32 id , XAP_Dialog_Modeless *
> > pDialog)
> >
> > to register your dialog as running.
> >
> > ---------------------------------------------------------------------------
> > Finally the unix front end must include the code:
> >
> > connectFocusModeless(GTK_WIDGET(mainWindow),m_pApp)
> >
> > to make the cursor in currently active window show up when the dialog is
> > focussed.
> > --------------------------------------------------------------------------
> >
> > Have a look at "Insert_Symbol" and "WordCount" for more clues and feel
> > free to ask questions if you need more info.
> >
> > Cheers!
> >
> > Martin
>
> --
> Paul Cubbage, CEO 408-353-2164 408-353-8181FAX 408-472-1112cel
> Open Country, Inc. paul@opencountry.net
> 23450 Old Santa Cruz Hwy.
> Los Gatos, CA 95033

-- 
Paul Cubbage, CEO	408-353-2164 408-353-8181FAX 408-472-1112cel
Open Country, Inc.      paul@opencountry.net
23450 Old Santa Cruz Hwy.
Los Gatos, CA 95033



This archive was generated by hypermail 2b25 : Fri May 26 2000 - 23:51:07 CDT