Page 1 of 1

Modal windows

Posted: Thu Jan 29, 2009 2:50 am
by ozzie
Yes, I know it's been asked many times before, going back to 2002, but I'd like to put in another vote for a cross-platform method of making a window modal, such as by using a flag like #PB_Window_Modal as suggested here. Meanwhile, I'll use the tip posted here, but a single extra flag would be really nice! After all, we've probably all got an Options window that needs to be modal.

Posted: Thu Jan 29, 2009 11:03 am
by Trond
After all, we've probably all got an Options window that needs to be modal.
Why would it need that?

Posted: Thu Jan 29, 2009 11:49 am
by srod
I'd like proper (modal and modeless) Windows dialogs (although I am unsure if there are GTK equivalents etc?) I use them more and more these days (via api of course); although using api is no real hardship in these cases.

Posted: Fri Jan 30, 2009 1:26 am
by ozzie
Trond wrote:
After all, we've probably all got an Options window that needs to be modal.
Why would it need that?
Good question! In Microsoft land it seems to be the norm. I've just checked several applications on my Windows PC and they all display Options dialogs as modal windows, except for PureBasic, which leaves the window on top but still allows me to access the main PB window. On my Apple iMac the rules are looser. Some Apple apps treat the Preferences window modally, but many do not. Those that do not treat the Preferences window as just another window, and don't even keep it on top if you go another window in the app.

In my app the Options window probably doesn't need to be modal. I'll review this. But I do have some other modal windows.
srod wrote:I'd like proper (modal and modeless) Windows dialogs (although I am unsure if there are GTK equivalents etc?) I use them more and more these days (via api of course); although using api is no real hardship in these cases.
Don't know anything about GTK, but in a quick check of the documentation I found the function gtk_window_set_modal (). By "api" I presume you mean Windows api? I'm trying wherever possible to keep everything cross-platform, but Windows api calls are OK if I can find equivalent functionality for Apple and Linux, and then use CompilerIf #PB_Compiler_OS=... commands to select the appropriate code.

Re: Modal windows

Posted: Sat Dec 19, 2009 6:30 pm
by WilliamL
I would like, and use, modal windows also and it would be a good addition to pb.

It occurs to me that, if you are entering data, that affects other windows, then the window should be modal. Otherwise, you will have to read the data as it is being put in and the other windows will have to be updated real-time or the other windows will have to be updated upon closing the window (ie. preferences window). It would be easier just to have one window open at a time but that is a problem with the Mac since you end up moving the menus all the time (you can only have one menu and it has to have a window).

I suppose you could make a window modal by the code in the event loop but I haven't tried it.. yet.

Oh, thanks ts-soft. I was writing this as you posted. I'm going to look at your example!

Re: Modal windows

Posted: Sat Dec 19, 2009 6:43 pm
by ts-soft
A Modal-Window (crossplattform) is available!

Code: Select all

Procedure ModalWindow()
  OpenWindow(1, 0, 0, 300, 200, "Modal", #PB_Window_SystemMenu | #PB_Window_WindowCentered, WindowID(0))
  DisableWindow(0, #True)
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        CloseWindow(1)
        DisableWindow(0, #False)
        Break
    EndSelect
  ForEver
EndProcedure

OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "Main", #PB_Window_SystemMenu)
ButtonGadget(0, 100, 100, 80, 30, "Modal Dialog")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0
        ModalWindow()
      EndIf
  EndSelect
ForEver
Greetings
Thomas

Re: Modal windows

Posted: Sat Dec 19, 2009 7:20 pm
by WilliamL
This works but there is the problem of clicking on the window 'close box' (which I use as a 'cancel' in some programs). Ideally, I wouldn't want to have to check on which window is open in the event loop which defeats the whole purpose of 'DisableWindow()' otherwise I could just check which window is open and make it modal that way.

Code: Select all

#maxwindows=2

Procedure MakeModalWindow(mwnd)
    For cnt=1 To #maxwindows
        If IsWindow(cnt)
            If cnt<>mwnd : DisableWindow(cnt, #True) : EndIf
        EndIf
    Next
EndProcedure

Procedure ReleaseModalWindow()
    For cnt=1 To #maxwindows
        If IsWindow(cnt)
            DisableWindow(cnt, #False)
        EndIf
    Next
EndProcedure

OpenWindow(1, 0, 0, 300, 200, "Window 1", #PB_Window_SystemMenu | #PB_Window_WindowCentered)
ButtonGadget(3,10,10,60,20,"Done")

OpenWindow(2, 40,40, 200, 200, "Window 2", #PB_Window_SystemMenu)
MakeModalWindow(2)
ButtonGadget(4,10,10,90,20,"Release")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 4
        ReleaseModalWindow()
      EndIf
  EndSelect
ForEver

Re: Modal windows

Posted: Sat Dec 19, 2009 7:29 pm
by ts-soft
I miss the ParentID in your code, this is required!
Your EventLoop should select the Window!

PB can't go the way with a simple flag, PB is not eventdriven!

greetings
Thomas

Re: Modal windows

Posted: Sat Dec 19, 2009 7:58 pm
by WilliamL
ts-soft - you're right. The parent window concept is new to me. It's pretty cool but I'm thinking of a modal window, like preferences, that is opened from a menu selection.

Here is some hastily thrown together code trying to make a modal window using the event loop. Yeah, I don't like it either. :?

Code: Select all

#maxwindows=2
#prefwnd=2
Global modalwindow.l=0

Procedure MakeModalWindow(mwnd)
    For cnt=1 To #maxwindows
        If IsWindow(cnt)
            If cnt<>mwnd : DisableWindow(cnt, #True) : EndIf
        EndIf
    Next
    modalwindow=mwnd
EndProcedure

Procedure ReleaseModalWindow()
    For cnt=1 To #maxwindows
        If IsWindow(cnt)
            DisableWindow(cnt, #False)
        EndIf
    Next
    modalwindow=0
EndProcedure

OpenWindow(1, 50, 50, 200, 200, "Window 1", #PB_Window_SystemMenu)
ButtonGadget(3,10,10,60,20,"End")

OpenWindow(#prefwnd, 140,140, 200, 200, "Preferences", #PB_Window_SystemMenu)
MakeModalWindow(#prefwnd)
ButtonGadget(4,10,10,90,20,"Release")

Repeat
    event=WaitWindowEvent()
    wndw=EventWindow()
    If modalwindow
        If modalwindow<>wndw
            wndw=0
        EndIf
    EndIf
    Select wndw
    Case #prefwnd
        Select event
        Case #PB_Event_CloseWindow
            Break
        Case #PB_Event_Gadget
            Select EventGadget()
            Case #PB_Event_CloseWindow
                Break
            Case 4
                ReleaseModalWindow()
            EndSelect
        EndSelect
    Case 1
        Select event
        Case #PB_Event_CloseWindow
            Break
        Case #PB_Event_Gadget
            Select EventGadget()
            Case #PB_Event_CloseWindow
                Break
            Case 3
                Break
            EndSelect
        EndSelect
    EndSelect
ForEver

Re: Modal windows

Posted: Sat Dec 19, 2009 8:10 pm
by ts-soft
I don't understand the problem, here another example:

Code: Select all

OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "Main", #PB_Window_SystemMenu)

If CreateMenu(0, WindowID(0))
  MenuTitle("Options")
  MenuItem(1, "Preferences")
EndIf

; ...
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Select EventWindow()
        Case 0
          Break
        Default
          CloseWindow(EventWindow())
          DisableWindow(0, #False)
      EndSelect
    Case #PB_Event_Menu
      If EventMenu() = 1
        DisableWindow(0, #True)
        OpenWindow(1, 0, 0, 200, 150, "Preferences", #PB_Window_SystemMenu | #PB_Window_WindowCentered, WindowID(0))
        ; ...
      EndIf
  EndSelect
ForEver

Re: Modal windows

Posted: Sat Dec 19, 2009 8:44 pm
by WilliamL
I guess what I don't understand is, what if there is more than one window open? You've tied the modal window to one window but what about the other windows? What if the modal window is the first window of the program (ie Game name:). Your example would be perfect for modal input to an existing window and I would use your example for that.

Re: Modal windows

Posted: Sat Dec 19, 2009 8:50 pm
by ts-soft
WilliamL wrote:I guess what I don't understand is, what if there is more than one window open? You've tied the modal window to one window but what about the other windows?
You have to disable the others to, the only active window for the application can only one modal window.
WilliamL wrote: What if the modal window is the first window of the program (ie Game name:). Your example would be perfect for modal input to an existing window and I would use your example for that.
Modal to what? The first window can never applicationmodal.
Or your question for a Systemmodal window? This is not available without API.

Re: Modal windows

Posted: Sat Dec 19, 2009 9:12 pm
by WilliamL
ts-soft

Thanks for the insight. I think I've exhausted my understanding and will have to think about what you have shown me.

It's this kind of dialog that makes this forum so good! :D

Re:

Posted: Sun Dec 20, 2009 12:22 am
by UserOfPure
Trond wrote:
After all, we've probably all got an Options window that needs to be modal.
Why would it need that?
Depends on the app. Some apps need an option to be selected by the user before continuing, to prevent data loss. It's quite normal.
ozzie wrote:except for PureBasic, which leaves the window on top but still allows me to access the main PB window
Access to it, yes, but you can't edit the code when it's running. The debugger has made the IDE modal for all intents and purposes.