Lisp HUG Maillist Archive

"Modal" interfaces (DISPLAY vs. DISPLAY-DIALOG)

Hi!

In an application I'm working on I have several interfaces that can be
stacked upon each other and are supposed to be "modal" in the sense
that if interface B is displayed as an effect of something that's done
in interface A then one should not be able to do something in A (or
any other displayed interface) until B is closed.

At the moment this is achieved by using CAPI:DISPLAY-DIALOG instead of
CAPI:DISPLAY.  The downside of this approach is that the interfaces
can't be resized by the user if they are displayed as dialogs but I'd
like to enable the user to do this.

Is there a way to have my cake and eat it, too?  Like somehow making
the interfaces "modal" without using CAPI:DISPLAY-DIALOG?

Thanks,
Edi.


Re: "Modal" interfaces (DISPLAY vs. DISPLAY-DIALOG)

Hi Edi,

> In an application I'm working on I have several interfaces that can be
> stacked upon each other and are supposed to be "modal" in the sense
> that if interface B is displayed as an effect of something that's done
> in interface A then one should not be able to do something in A (or
> any other displayed interface) until B is closed.
>
> At the moment this is achieved by using CAPI:DISPLAY-DIALOG instead of
> CAPI:DISPLAY.  The downside of this approach is that the interfaces
> can't be resized by the user if they are displayed as dialogs but I'd
> like to enable the user to do this.
>
> Is there a way to have my cake and eat it, too? Like somehow making
> the interfaces "modal" without using CAPI:DISPLAY-DIALOG?

I don't know if there's an 'official' way of doing this.  If there isn't,
you could try out something like the following hack:

- before putting a new 'pseudo-modal' dialog on top of your stack, disable
  the current dialog (on Windows, you can do this with EnableWindow).

- after popping a 'pseudo-modal' dialog from your stack, re-enable
  the parent (again, you can do this with EnableWindow on Windows).

This way, you don't need to use DISPLAY-DIALOG but you'll still get
the effect of a modal dialog (because none of the other interfaces
of your application is enabled).

Hope this helps,

Arthur

(By the way, I don't think that this model of having a stack of modal
dialogs is very pretty.  But I understand that it may be hard to come
up with a better interface for your application.)


Re: "Modal" interfaces (DISPLAY vs. DISPLAY-DIALOG)

Edi Weitz wrote:

>Is there a way to have my cake and eat it, too?  Like somehow making
>the interfaces "modal" without using CAPI:DISPLAY-DIALOG?
>  
>

Edi,

An alternative may be to only supply "one" interface in this case.  If 
you use
a capi:switchable-layout you can change the contents of the interface and
then when done return the contents to the original.  So instead
of using capi:display-dialog to popup a new modal window you change which
child is visible.  (Note: that a capi:interface can be a child of a layout).

Wade


Re: "Modal" interfaces (DISPLAY vs. DISPLAY-DIALOG)

At 17:18 25/08/2005, Arthur Lemmens wrote:
>Edi Weitz wrote:
>
>>>- before putting a new 'pseudo-modal' dialog on top of your stack,
>>>disable the current dialog (on Windows, you can do this with
>>>EnableWindow).
>>
>>You mean getting the handle with CAPI:SIMPLE-PANE-HANDLE and applying
>>the Win32 function EnableWindow?
>
>Yes, exactly.
>
>If you try this, I'd be interested to know if it works well.
>
>Arthur

fwiw
I think you could use capi:simple-pane-enabled rather than having to use 
the Win32 function.

cheers

paulm



Re: "Modal" interfaces (DISPLAY vs. DISPLAY-DIALOG)

>Edi Weitz wrote:
>
>>However, no matter if I use the Win32 or the CAPI way I
>>sometimes end up with the re-enabled interface minimized.

I noticed that your modal-display example did not make the from-interface 
the owner of the new interface.
Does changing this help at all ? i.e. change the call to capi:display

       (capi:display interface :owner from-interface)))

Does the simple example below exhibit the same problems for you ?
It uses activate-pane as you suggested.
It seems OK for me in LWW 4.3.7

Note I had to call activate-pane on a pane that accepts focus.
It should just work on the interface but it not seem to when I tried it.

cheers

paulm

(in-package "CL-USER")

(capi:define-interface dialog-test ()
   ()
   (:panes
    (input-pane
     capi:text-input-pane
     :accessor dialog-text-input-pane
     :callback-type :interface)
    (buttons
     capi:push-button-panel
     :items '("New" "Close")
     :layout-args '(:x-uniform-size-p t)
     :callback-type :interface
     :callbacks '(new-dialog-test close-dialog-test)))
   (:layouts
    (default
     capi:column-layout
     '(input-pane buttons)
     :x-adjust :centre))
   (:default-initargs
    :title "Enter some text:"))

(defun modal-display (interface from-interface)
     (let ((old-destroy-callback (capi:interface-destroy-callback interface)))
       (setf (capi:interface-destroy-callback interface)
             (lambda (interface)
               (when old-destroy-callback
                 (funcall old-destroy-callback interface))
               (setf (capi:simple-pane-enabled from-interface) t)
               (capi:activate-pane (dialog-text-input-pane from-interface))))
       (setf (capi:simple-pane-enabled from-interface) nil)
       (capi:display interface :owner from-interface)))

(defun new-dialog-test (interface)
   (let ((dialog (make-instance 'dialog-test)))
     (modal-display dialog interface)))

(defun close-dialog-test (interface)
   (capi:quit-interface interface))

(defun test-dialog ()
   (capi:display (make-instance 'dialog-test)))



Updated at: 2020-12-10 08:50 UTC