Any MaxGUI turtorials out there?

Started by Juiceter, June 09, 2020, 20:13:25

Previous topic - Next topic

Juiceter

Hi,

can anyone point me in the direction of a decent blitz maxGUI tutorial please?

I've gone through Assari's (2005) one which is pretty good but it doesn't tell me enough about events and why the dreaded return key is not picked up in textfield gadgets.

In particular I'm having a lot of trouble with EVENT_GADGETLOSTFOCUS and trapping the return key so i can act on it (perhaps disable it so I can tab between textfields instead).

EDIT: anyone know if  Slone's "blitzmax for absolute beginners" covers the GUI portion of blitz max? Has anyone read it? Is it any good?

Thanks!

Juiceter

Got it straight from the horses mouth. Slone said his book doesn't cover the blitzmax gui stuff :-(

wombats

You can use SetGadgetFilter to intercept keys.

Import MaxGUI.Drivers

Local window:TGadget
Global gadget:TGadget

window = CreateWindow("Window", 0, 0, 320, 150)
gadget = CreateTextField(10, 10, ClientWidth(window) - 20, 25, window)

SetGadgetLayout(gadget, 1, 1, 1, 0)
ActivateGadget gadget

SetGadgetFilter(gadget, filter)

Function filter(event:TEvent, context:Object)
Select event.id
Case EVENT_KEYDOWN
Select event.data
Case KEY_RETURN, KEY_ENTER
Notify "Return/Enter pressed."
Return 0
EndSelect
EndSelect
Return 1
EndFunction

While WaitEvent()
Select EventID()
Case EVENT_WINDOWCLOSE
End
EndSelect
Wend

Juiceter

#3
Thanks I'll have a look at that code you posted there (which may provide the answer). This is what I have so far. What I want is to type into a and press return, which should put you into b. But it just bounces you out of b without giving you a chance to put any text into it.




Strict

Import maxgui.drivers

Local win:Tgadget=CreateWindow:Tgadget("",100,100,800,600,Null,WINDOW_TITLEBAR|WINDOW_MENU|WINDOW_CENTER|WINDOW_STATUS)
Local a:Tgadget=CreateTextField(521,302,20,20,win) 
Local b:Tgadget=CreateTextField(551,302,20,20,win)


ActivateGadget(a)
Repeat
WaitEvent()             
Select EventID()
Case EVENT_GADGETLOSTFOCUS
Select EventSource()
Case a
    If b<>ActiveGadget() Exit
    End Select
End Select
Forever

ActivateGadget(b)

Repeat
WaitEvent()           
Select EventID()
Case EVENT_GADGETLOSTFOCUS
Select EventSource()
Case b
    If a<>ActiveGadget() Exit
    End Select
End Select
Forever


Print "finished"


Juiceter

#4
It does the same with your code here. If you type into the first gadget and press return it does not jump into the second gadget. What am I doing wrong? Logically the second activategadget should put the cursor into gadget 2 ready for text to be entered there should it not?

SyntaxBomb - Indie Coders »Languages & Coding »BlitzMax / BlitzMax NG »MaxGUI »Can't maintain focus on a TextField when pressing Enter

It seems tom had the same problem here (I've seen this post before but it was never fully solved, only by using textarea instead). Is it a bug or something?


Import MaxGUI.Drivers

Local window:TGadget
Global gadget:TGadget

window = CreateWindow("Window", 0, 0, 320, 200)
gadget = CreateTextField(10, 10, ClientWidth(window) - 20, 25, window)
gadget1 = CreateTextField(10, 50, ClientWidth(window) - 20, 25, window)

SetGadgetLayout(gadget, 1, 1, 1, 0)


SetGadgetFilter(gadget, filter)

Function filter(event:TEvent, context:Object)
Select event.id
Case EVENT_KEYDOWN
Select event.data
Case KEY_RETURN, KEY_ENTER
Notify "Return/Enter pressed."
Return 0
EndSelect
EndSelect
Return 1
EndFunction

[b]ActivateGadget gadget[/b]

While WaitEvent()
Select EventID()
Case EVENT_WINDOWCLOSE
End
EndSelect
Wend


ActivateGadget gadget1

While WaitEvent()
Select EventID()
Case EVENT_WINDOWCLOSE
End
EndSelect
Wend


wombats

Hmm, you're right. This works as expected on macOS, but not on Windows.
Import MaxGUI.Drivers

Local window:TGadget
Global gadget:TGadget, gadget1:TGadget

window = CreateWindow("Window", 0, 0, 320, 200)
gadget = CreateTextField(10, 10, ClientWidth(window) - 20, 25, window)
gadget1 = CreateTextField(10, 50, ClientWidth(window) - 20, 25, window)

SetGadgetLayout(gadget, 1, 1, 1, 0)
SetGadgetFilter(gadget, filter)

ActivateGadget(gadget)

Function filter(event:TEvent, context:Object)
Select event.id
Case EVENT_KEYDOWN
Select event.data
Case KEY_RETURN, KEY_ENTER
If ActiveGadget() = gadget
ActivateGadget(gadget1)
Return 0
EndIf
EndSelect
EndSelect
Return 1
EndFunction

While WaitEvent()
Select EventID()
Case EVENT_WINDOWCLOSE
End
EndSelect
Wend

Juiceter

#6
Very annoying, isn't it?! If I could just find a way to ignore the enter key so that it does nothing (i.e. switch it off) then this code works if you tab it through. Alternatively if I could find a way to stop it 'bouncing' past g1 (maybe the enter key produces 2 events or something?)...


Henri commented in the above thread that this behaviour has annoyed many; I tend to agree. The behaviour it has ended up with makes no sense at all.


'Works if you tab it through. Works if you tab g and enter g1.
' skips g1 if you press enter on g.

Strict
Import MaxGUI.Drivers

Global window:TGadget
Global g:TGadget
Global g1:TGadget

window=CreateWindow("Window",0,0,320,200)
g=CreateTextField(10,10,30,25,window)
g1=CreateTextField(10,50,30,25,window)

Rem
SetGadgetFilter g,EnterFilter
SetGadgetFilter g1,EnterFilter

Function EnterFilter:Int(event:TEvent,context:Object)
If(event.id=EVENT_KEYDOWN And event.data=13) Return False  ' this isnt even detected!
    Return True
End Function
EndRem

Function wait()
While WaitEvent()
Select EventID()
Case EVENT_WINDOWCLOSE End
Case EVENT_GADGETLOSTFOCUS
' Select EventSource()
' Case g  Exit   
' Case g1 Exit
Exit
'End Select
EndSelect
Wend
End Function


ActivateGadget g ; wait()
Print "from g:"+TextFieldText$(g)

ActivateGadget g1 ; wait()
Print "from g1:"+TextFieldText$(g1)

Print "finished"



Juiceter

Bribe time! If anyone can offer me a solution to the above problem that works as I have described then I'll send them a tenner. I think it would benefit a lot of us if this worked the way it should.

GW

You can see in line 433 of win32maxguiex.bmx where the change is.
You can try reverting the change back and rebuilding the module.The thread that made the change is here: https://mojolabs.nz/posts.php?topic=72737I have another method almost working using a global hotkey. But the edit may be faster. 

Juiceter

Thanks - unfortunately I can't access that site for some reason. The problem is will it work for everyone? Thats what tomtoad commented on in the thread I mentioned. If it just works for me then there's no point in doing it.

TomToad

In my case, I was working on a BlitzMax module and was planning on sharing the module when finished (never did finish it); However, I didn't want to share a module that required someone to edit the base BlitzMax modules as this could break their other projects.  If you only want to distribute a finished program, then making the changes should be ok.
------------------------------------------------
8 rabbits equals 1 rabbyte.

Henri

I think we can push the change to Maxgui source in Brucey's github. This probably is now the most official place for it. This would then be migrated to release version at some point.

I could try to create a pull/push request for this (haven't done one yet so that's new..)

-Henri
- Got 01100011 problems, but the bit ain't 00000001

Juiceter

#12
You would all agree though, that for the windows version the way it has been left implemented is strange is it not? If it works differently for the Mac it's not a good thing. Inconsistency between the same programming language for different platforms is a bad thing.

Henri, when you say push it to Brucey, that means NG doesn't it?

Anyway thanks for the advice guys. And the offer still stands. I know it's not much but the first to post code that works here gets a tenner as a thank you for solving the issue! I may just go the way GW has stated though, but I know someone will run into this problem again sooner or later, and it would be best to make it disappear for their sakes too :-)

Actually there is a piece of code in theat thread that kind of works and i'm modifying it now. Will post it here if I get the desired action. Note: if you can't get through to https://mojolabs.nz/ like I couldn't you will have to put an exception in your firewall (for some reason Avast seems to think the site is unsafe). There is some really useful stuff there (I remember using it back in the day) but thought it had been lost forever.


Juiceter

#13
This has the desired effect (finally!). Have a look and see if it works for you too. It works for tabbing through and returning. I can only conclude that 2 events occur when you press enter (see key line). Perhaps and enter and line feed, idk. It only works for 2 textfield gadgets though, but I'm sure it can be expended if you want to add more.

Incidentally, I'll send the tenner off to Brucey just because he's a nice guy :-).


Strict
Import MaxGui.Drivers

Global window:Tgadget=CreateWindow("Window",0,0,320,200)
Global g:Tgadget=CreateTextField(10,10,30,25,window)
Global g1:Tgadget=CreateTextField(10,50,30,25,window)
Global hiddenbtn:TGadget = CreateButton ("",10,150,250,20,window,BUTTON_OK)

HideGadget hiddenbtn ; ActivateGadget g
While WaitEvent()
'Print CurrentEvent.ToString()
Select EventID()
Case EVENT_GADGETACTION
Select EventSource()
Case hiddenbtn
ActivateGadget g1 ; WaitEvent ; ActivateGadget g1 ' <--- KEY LINE!
End Select

Case EVENT_GADGETLOSTFOCUS
Select EventSource() 
Case g1 Exit
End Select

Case EVENT_WINDOWCLOSE End
Case EVENT_APPTERMINATE End
End Select
Wend

Print "g= "+TextFieldText$(g)
    Print "g1= "+TextFieldText$(g1)


Juiceter

#14
This is interesting - if you have 3 textfields it will only work if you call a waitevent twice (and only then it only works with a return and not tab). If there is a command to flush the event queue before an event  then maybe this issue can be solved (flushkeys doesnt work). Is there such a command?


Strict
Import MaxGui.Drivers

Global window:Tgadget=CreateWindow("Window",0,0,320,200)
Global g:Tgadget=CreateTextField(10,10,30,25,window)
Global g1:Tgadget=CreateTextField(10,50,30,25,window)
Global g2:Tgadget=CreateTextField(10,80,30,25,window)

Global hiddenbtn:TGadget=CreateButton("ok",50,100,50,20,window,BUTTON_OK)

'HideGadget hiddenbtn
; ActivateGadget g
While WaitEvent()
Print CurrentEvent.ToString()
Select EventID()
' Case EVENT_GADGETACTION
' Select EventSource()
' Case hiddenbtn



' Select EventID()
Case EVENT_GADGETLOSTFOCUS
Select EventSource() 
Case g
ActivateGadget g1 ; WaitEvent ; ActivateGadget g1 ' <--- KEY LINE!
ActivateGadget g1 ; WaitEvent ; ActivateGadget g1 ' comment this out and it wont work
Case g1
ActivateGadget g2 ; WaitEvent ; ActivateGadget g2
ActivateGadget g2 ; WaitEvent ; ActivateGadget g2 ' comment this out and it wont work

' code needed in here for more than 2 textfields.
               Case g2 Exit

         End Select
'End Select

' works if button pressed when you want to move to next field. Works on tab through
' does not work if return pressed after g (g1 is skipped).

' this is interesting! works if 2 lots of waitevents for 3 fields! but for return only if we could flush the event queue...


'End Select

' Case EVENT_GADGETLOSTFOCUS
' Select EventSource() 
' Case g1 Exit
' Case g2 Exit
' End Select

Case EVENT_WINDOWCLOSE End
Case EVENT_APPTERMINATE End
End Select
Wend

Print "g= "+TextFieldText$(g)
    Print "g1= "+TextFieldText$(g1)
Print "g2= "+TextFieldText$(g2)