Re: How to write a Modeless Dialog.


Subject: Re: How to write a Modeless Dialog.
From: Thomas Fletcher (thomasf@qnx.com)
Date: Fri May 26 2000 - 08:23:58 CDT


Martin,

  Thanks ... I had loosely been following the modeless dialog
discussion and was planning on doing the Photon side of things
this weekend. This has cleared up a lot of things for me. Hopefully
much of this work has been taken care of in XAP/XP land and there
will be very few platform specific things that I have to do to
make things work.

Thomas

On Fri, 26 May 2000, 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
>
>
>
>

-------------------------------------------------------------
Thomas (toe-mah) Fletcher QNX Software Systems
thomasf@qnx.com Neutrino Development Group
(613)-591-0931 http://www.qnx.com/~thomasf



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