Event woes in custom dialogue
BlitzMax Forums/MaxGUI Module/Event woes in custom dialogue
| ||
I have been trying to make a stand-alone dialog function that works much like the Confirm command but also has a text field to get data from the user. This is the code for the function: This works fine when the main program uses a simple event loop, for example: However, if the main program uses event hooks to manage the events it hangs the program as in the following example: I've been working on this for hours but I can't work out how to solve the problem. I have tried making the RequestInput use hooks as well but that didn't work either (I can post the code if it helps). Any suggestions how to get this working? |
| ||
Hi, Have you seen this? On that base I made this 'about gadget' using proxygadgets, and it seems to work very well Maybe you can find inspiration to resolve your implementation. Cheers |
| ||
You can't make a nice neat self-contained function like that. You have to add an event hook, and detect when the button is closed. |
| ||
Thanks, I did do a search but somehow missed that one. The main thing I need to do that differs from those examples is to halt the main program flow whilst my dialog is running, as it is requesting user input partway through an operation (much like how RequestFile works), and the problem I'm getting is related to this. I already tried a hooked version but it resulted in the same problem. Full code below: The problem seems to be the Repeat/WaitSystem loop, but I need something like this to halt the main program flow until the dialog is closed. |
| ||
Any other suggestions to solve this? I really need it to behave like a Confirm dialog (or similar) so program flow only continues once the dialog is closed. |
| ||
What about deleting the event hook at start and re-installing upon exit? |
| ||
Create a window stack so when you open a window a new entry is added to the stack. All previous windows are disabled. When you close the dialogue, remove it from the stack and enable the top most window on stack. This is ripped from my dialogue class so no idea how well it is working but hopefully it will help. You will need the maxguiex module for some functions for bringing the window to the top n stuff. https://github.com/skn3/maxguiex you could probably remove the two lines BringWindowToTop(dialogue) FocusWindow(dialogue) and then you wouldn't need maxguiex and find an alternative? [bbcode]Import maxgui.drivers Import maxgui.proxygadgets Import skn3.maxguiex Type Skn3Dialogue Extends TProxyGadget Global hooked:Int Global stack:TList = CreateList() Global classes:TMap = CreateMap() Field Window:TGadget Field IsActive:Int = False Field isOpen:Int = False Field isModal:Int = True Field hasOpened:Int = False Field stackLink:TLink Field stackActiveGadget:TGadget 'function api Function OpenDialogue:Skn3Dialogue(dialogue:Skn3Dialogue,parent:Skn3Dialogue) ' --- open a dialogue spawned from this dialogue --- If dialogue = Null Return Null 'open this dialogue dialogue.Open() 'return it Return dialogue End Function Function GetTopMostDialogue:Skn3Dialogue() ' --- return teh top most dialogue in the applet --- Return Skn3Dialogue(stack.Last()) End Function 'hooks Function EventHook:Object(id:Int,data:Object,context:Object) Local event:TEvent = TEvent(data) 'check valid event If event 'process all dialogues from top of dialogue stack to bottom Local link:TLink = stack.LastLink() Local dialogue:Skn3Dialogue While link 'get dialogue dialogue = Skn3Dialogue(link.value()) 'see if the dialogue is handling the event If dialogue.isOpen And dialogue.OnFilterEvent(event) event = dialogue.OnEvent(event) If event = Null Return Null EndIf 'previous link link = link.PrevLink() Wend EndIf 'return Return event EndFunction 'constructor/destructor Method New() If hooked = False hooked = True AddHook(EmitEventHook,Skn3Dialogue.EventHook,Null) EndIf End Method 'events Method OnCreate:Skn3Dialogue() Abstract Method OnFilterEvent:Int(event:TEvent) Return True End Method Method OnEvent:TEvent(event:TEvent) Select event.id Case EVENT_WINDOWCLOSE ' --- window is closed --- If event.source = Self close() 'return event used Return Null End If End Select Return event End Method Method OnClose() If Window FreeGadget(Window) End Method 'api Method OpenChildDialogue:Skn3Dialogue(dialogue:skn3Dialogue) Return Skn3Dialogue.OpenDialogue(dialogue,Self) End Method Method Open() ' --- open the dialogue --- If Window And isOpen = False 'flag this dialogue open isOpen = True Local link:TLink Local dialogue:Skn3Dialogue 'for the top most dialogue remember the active gadget dialogue = Skn3Dialogue(stack.Last()) If dialogue 'get active gadget dialogue.stackActiveGadget = ActiveGadget() 'make sure the gadget is not the dialogue window If dialogue.stackActiveGadget = dialogue.Window dialogue.stackActiveGadget = Null EndIf 'lock all other dialogues if this new dialogue is modal! If isModal link = stack.FirstLink() While link 'get dialogue dialogue = Skn3Dialogue(link.value()) 'disable dialogue If dialogue.isModal DisableGadget(dialogue) 'next dialogue link = link.NextLink() Wend EndIf 'add this dialogue to the stack if it is a modal stackLink = stack.AddLast(Self) 'setup the dialogue window If hasOpened = False ShowGadget(Window) 'reset first open flag hasOpened = True EndIf End Method Method close() ' --- close the dialogue and remove it from the stack --- 'ok indicated whether we are just closing or if we are returning Local link:TLink Local dialogue:Skn3Dialogue 'first activate the what will be new top most dialogue link = stackLink.PrevLink() If link While link dialogue = Skn3Dialogue(link.value()) if dialogue.isModal Exit link = link.PrevLink() dialogue = Null Wend If dialogue And dialogue.Window 'activate the dialogue window EnableGadget(dialogue) BringWindowToTop(dialogue) FocusWindow(dialogue) 'activate a gadget if there was one If dialogue.stackActiveGadget <> Null ActivateGadget(dialogue.stackActiveGadget) dialogue.stackActiveGadget = Null EndIf EndIf EndIf 'now pop dead dialogues starting from this off the stack link = stackLink While link 'get dialogue dialogue = Skn3Dialogue(link.value()) dialogue.OnClose() 'next link link = link.NextLink() 'remove the dialogue from the stack If dialogue.isModal dialogue.stackLink.remove() dialogue.stackLink = Null EndIf Wend 'return successful close Return Null End Method End Type Type Skn3DialogueParent Extends Skn3Dialogue Field button:TGadget Method OnCreate:Skn3Dialogue() Window = CreateWindow("parent window",50,50,300,300,Null,WINDOW_TITLEBAR) SetProxy(Window) button = CreateButton("press",5,5,Window.ClientWidth()-10,Window.ClientHeight()-10,Window) Return Self End Method Method OnFilterEvent:Int(event:TEvent) Return event.source = button End Method Method OnEvent:TEvent(event:TEvent) Select event.id Case EVENT_GADGETACTION Select event.source Case button OpenChildDialogue(New Skn3DialogueChild.OnCreate()) Return Null End Select End Select Return Super.OnEvent(event) End Method End Type Type Skn3DialogueChild Extends Skn3Dialogue Method OnCreate:Skn3Dialogue() Window = CreateWindow("child window",50,50,150,150,Null,WINDOW_TOOL | WINDOW_TITLEBAR) SetProxy(Window) Return Self End Method End Type Local parentDialogue:Skn3Dialogue = New Skn3DialogueParent.OnCreate() parentDialogue.Open() Repeat WaitEvent() Forever[/bbcode] Last edited 2012 Last edited 2012 Last edited 2012 |