Panel with 'Enter' as default Ok button action.

Hello,

I'm trying to build a small panel, that is supposed to resemble a dialog. Purpose is to enter a numeric value and store it in a global variable. The panel has for this purpose a SetVariable field and two buttons (OK and Cancel).

I'm handling the button actions via proc calls. Entering a value in the field and using the mouse to cancel or confirm the set value works fine.

What I miss is having the Return/Enter Buttons on the keyboard act as if clicking the corresponding button. I can't help but find no way to handle this?

With best regards, Lars Sölter


Function /S UI_NVarInput( varname, panelname ) : Panel
    String varname
    String panelname
   
    String windowname
    String usrdat = ""
    String tmpvarname = varname+"_DNVI"
   
    NVAR numvar = $(varname)
    NVAR tmpnumvar = $(tmpvarname)
   
    usrdat = ReplaceStringByKey( "NVARNAME", usrdat, varname, "=" )
   
    if( NVAR_Exists( tmpnumvar ) == 0 )
        Variable/G/D $(tmpvarname) = 0
        NVAR tmpnumvar = $(tmpvarname)
    endif
    if( NVAR_Exists( numvar ) == 1 )
        tmpnumvar = numvar
    endif
   
    usrdat = ReplaceStringByKey( "TMPNVARNAME", usrdat, tmpvarname, "=" )

    PauseUpdate; Silent 1       // building window...
    NewPanel /FLT=2 /K=1 /N=UI_NVarInput /W=(267,122,586,236) as panelname
    windowname = S_name
   
    SetDrawLayer UserBack

    SetDrawEnv fname= "Segoe UI"
    DrawText 15, 30, "Name"
    SetDrawEnv fname= "Andale Mono"
    DrawText 60, 30, varname
    SetDrawEnv fname= "Segoe UI"
    DrawText 15, 55, "Value"
    SetVariable PanVar1 value=tmpnumvar, title=" ", pos={60,40}, size={240,10}, limits={-inf,inf,0}, font="Andale Mono"
   
    Button ButtonOk, pos={140,78}, size={70,22}, userdata=usrdat, proc=UI_NVarInput_Ok, title="Ok"
    Button ButtonOk,font="Segoe UI"
    Button ButtonCancel, pos={230,78}, size={70,22}, font="Segoe UI", userdata=usrdat, proc=UI_NVarInput_Cancel, title="Cancel"
    Button ButtonCancel,font="Segoe UI"
   
    return windowname
End


Function UI_NVarInput_Ok( s ) : ButtonControl
    STRUCT WMButtonAction &s
   
    String varname
    varname = StringByKey( "NVARNAME", GetUserData( s.win, s.ctrlName, "" ), "=" )
    NVAR numvar = $(varname)
   
    String tmpvarname
    tmpvarname = StringByKey( "TMPNVARNAME", GetUserData( s.win, s.ctrlName, "" ), "=" )
    NVAR tmpnumvar = $(tmpvarname)
   
    switch( s.eventCode )
        case 2: // mouse up
            if( NVAR_Exists( tmpnumvar ) == 1 )
                if( NVAR_Exists( numvar ) == 0 )
                    Variable/G/D $(varname) = 0
                    NVAR numvar = $(varname)
                endif
                numvar = tmpnumvar
                KillVariables /Z $tmpvarname
            endif
   
            KillWindow $s.win
            break
    endswitch
End


Function UI_NVarInput_Cancel( s ) : ButtonControl
    STRUCT WMButtonAction &s
   
    String tmpvarname
    tmpvarname = StringByKey( "TMPNVARNAME", GetUserData( s.win, s.ctrlName, "" ), "=" )
   
    switch( s.eventCode )
        case 2: // mouse up
            KillVariables /Z $tmpvarname
            KillWindow $s.win
            break
    endswitch
End
You need to use a Window Hook function. Here is an example of the basic technique:
Function DoneButtonProc(ba) : ButtonControl
    STRUCT WMButtonAction &ba

    switch( ba.eventCode )
        case 2: // mouse up
            // First, do whatever needs to be done, then close the panel
            KillWindow Panel0
            break
        case -1: // control being killed
            break
    endswitch

    return 0
End

Function DefaultButtonHook(s)
    STRUCT WMWinHookStruct &s

    Variable hookResult = 0

    switch(s.eventCode)
        case 11:                // Keyboard
            if (s.keycode == 11 || s.keycode == 13)     // linefeed or carriage return
                KillWindow panel0
                hookResult = 1
            endif
            break

    endswitch

    return hookResult       // 0 if nothing done, else 1
End


Window panel0() : Panel
    PauseUpdate; Silent 1       // building window...
    NewPanel /W=(150,50,450,250)
    Button donebutton,pos={113,87},size={50,20},proc=DoneButtonProc,title="done"
    Button donebutton,fColor=(0,0,65535)
    SetWindow kwTopWin,hook(defaultbuttonhook)=DefaultButtonHook
EndMacro

First, run Panel0(). Then try clicking the button or pressing Enter.

Read about window hooks:
DisplayHelpTopic "Window Hook Functions"
My example uses a named hook function, which is preferred:
DisplayHelpTopic "Named Window Hook Functions"

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
Since you're using window hook functions anyway, why not extend them to enable increment/decrement of the setvariable control (I know it's not what your asking for but why not?).

Function SetVariableHook(s)
    STRUCT WMWinHookStruct &s

    Variable hookResult = 0

    switch(s.eventCode)
        case 11:                // Keyboard
            if (s.keycode == 30)        // linefeed or carriage return
                //increment the setvariable in your panel
                hookResult = 1
            elseif (s.keycode ==31)
                //decrement the setvariable in your panel
                hookResult = 1
            endif
            break

    endswitch

    return hookResult       // 0 if nothing done, else 1
End


Window panel0() : Panel
    PauseUpdate; Silent 1       // building window...
    NewPanel /W=(150,50,450,250)
    Button donebutton,pos={113,87},size={50,20},proc=DoneButtonProc,title="done"
    Button donebutton,fColor=(0,0,65535)
    SetWindow kwTopWin,hook(defaultbuttonhook)=DefaultButtonHook, hook(setvariablehook) = SetVariableHook
EndMacro


I added the setvariable hook to John's Panel