Can't maintain focus on a TextField when pressing Enter

Started by TomToad, May 15, 2019, 20:44:35

Previous topic - Next topic

TomToad

Trying to create a chat program.  Below is a scaled down version of the code.  Type into the text field and click send, the information is sent to the text area and focus is returned to the text field.  When you type something in, but press Enter instead of clicking, the text is still sent to the text area, but focus on the gadget is lost.  Even stranger, type in some text, but don't click Send or press Enter.  Instead, click outside of the text field to change focus to somewhere else, then press Enter.  You should still see the text being sent due to the BUTTON_OK style, but it isn't.  It is like the button is deactivated until you either click on it, or press Enter while the text area has focus.

I can't just simply do "If ActiveGadget() <> TextField Then ActivateGadget TextField", as this will affect interaction with other gadgets.
Code (blitzmax) Select
SuperStrict
Import maxgui.drivers

Global MainWindow:TGadget = CreateWindow("Test",0,0,600,600)
Global TextArea:TGadget = CreateTextArea(0,0,ClientWidth(MainWindow),ClientHeight(MainWindow)-20,MainWindow,TEXTAREA_WORDWRAP|TEXTAREA_READONLY)
Global TextField:TGadget = CreateTextField(0,ClientHeight(MainWindow)-20,ClientWidth(MainWindow)-80,20,MainWindow)
Global SendButton:TGadget = CreateButton("Send",ClientWidth(MainWindow)-80,ClientHeight(MainWindow)-20,80,20,MainWindow,BUTTON_OK)
AddHook EmitEventHook,HandleEvents

Repeat
WaitEvent()
Forever

Function HandleEvents:Object(id:Int,data:Object,context:Object)
Local EVent:TEvent = TEvent(data)

Select Event.id
Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE
End
Case EVENT_GADGETACTION
Select Event.source
Case SendButton
AddTextAreaText TextArea,GadgetText(TextField)+"~n"
SetGadgetText TextField,""
ActivateGadget TextField
Return Null
End Select
End Select
Return data
End Function



Edit:  I also tried adding a gadget filter to handle Enter there, but the Text Field gadget doesn't send Enter to the filter.
------------------------------------------------
8 rabbits equals 1 rabbyte.

Henri

Hi Tom,

if you don't mind editing MaxGui source a bit, there is this line in 'maxgui.mod\win32maxguiex.mod\win32maxguiex.bmx :
Code (blitzmax) Select
Function KeyboardProc:Byte Ptr( code, wp:WParam, lp:LParam) "win32" nodebug
Local ev:TEvent, hwnd:Byte Ptr, tmpClassName:Short[16], mods:Int, key:Int = wp
If code>=0 Then
'Removed: http://www.blitzbasic.com/Community/posts.php?topic=72737
' Rem
If wp = $D Then '$D: VK_RETURN
hwnd = GetFocus()
If hwnd And GetClassNameW(hwnd,tmpClassName,tmpClassName.length) And String.FromWString(tmpClassName).ToUpper() = "EDIT" Then
SetFocus(GetParent_(hwnd))
EndIf
EndIf
' EndRem


Un-comment the rem block and the behavior should be as you expect (just remember to build modules).

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

TomToad

looking here http://www.mojolabs.nz/posts.php?topic=72737, it appears that this behavior was intentional.  Since I am wanting to share my final code, modifying MaxGui is really not an option.  I did manage to make a workaround by using a TextArea and filtering for the Enter key.
Code (blitzmax) Select
SuperStrict
Import maxgui.drivers

Global MainWindow:TGadget = CreateWindow("Test",0,0,600,600)
Global TextArea:TGadget = CreateTextArea(0,0,ClientWidth(MainWindow),ClientHeight(MainWindow)-20,MainWindow,TEXTAREA_WORDWRAP|TEXTAREA_READONLY)
Global TextField:TGadget = CreateTextArea(0,ClientHeight(MainWindow)-20,ClientWidth(MainWindow)-80,20,MainWindow)
SetGadgetFilter TextField,EnterFilter
Global SendButton:TGadget = CreateButton("Send",ClientWidth(MainWindow)-80,ClientHeight(MainWindow)-20,80,20,MainWindow)
AddHook EmitEventHook,HandleEvents

Function EnterFilter:Int(event:TEvent,context:Object)
If event.id = EVENT_KEYDOWN And event.data = 13
AddLine()
Return False
EndIf
Return True
End Function

Function AddLine()
AddTextAreaText TextArea,GadgetText(TextField)+"~n"
SetGadgetText TextField,""
End Function

Repeat
WaitEvent()
Forever

Function HandleEvents:Object(id:Int,data:Object,context:Object)
Local EVent:TEvent = TEvent(data)

Select Event.id
Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE
End
Case EVENT_GADGETACTION
Select Event.source
Case SendButton
AddLine()
ActivateGadget TextField
Return Null
End Select
End Select
Return data
End Function
------------------------------------------------
8 rabbits equals 1 rabbyte.

Henri

Looking at that thread it seems that this behavior was originally requested by JoshK. Before that, it functioned as you would intuitively expect.

I believe that many resented this, but it was never 'fixed' back as Sebholl mentioned.

Personally, I prefer the expected behavior, where gadget doesn't lose focus and always fix it the way it suppose to be.

We could make this a default behavior?

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

Derron

@ Henri
Yes, MaxGUI is open source :-)

But instead of removing the current behaviour I would tend to add a flag/SetXYZBehaviour() function call. That way people could use the behaviour they "know" from other software or from MaxGUI.


@ shareable code
Can't you extend your code to have a "custom" widget with your behaviour?


bye
Ron