English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. C/C++ (https://eab.abime.net/forumdisplay.php?f=118)
-   -   Intuition - Menu Command Keys and STRING_KIND gadgets (https://eab.abime.net/showthread.php?t=109611)

Sim085 25 January 2022 01:28

Intuition - Menu Command Keys and STRING_KIND gadgets
 
I have created a window with a simple form made of STRING_KIND gadgets. The window also has a menu with two menu items, "save" and "clear". I liked the command key 'S' with the save option and the command key 'C' with the clear option.

The command keys work fine when focus is on the window itself. However when focus in on one of the STRING_KIND gadgets these do not work.

Is there a workarounds for this?

Do I need to listen to the keystrokes in the STRING_KIND gadget and trigger the action linked to the menu when the right amiga key and 's' or 'c' are pressed?

If yes, how to know if the right amiga key is being pressed when another letter is pressed? I managed to detect what key is pressed but cannot figure how when a key is pressed (example 's') I can check if another key is still pressed (right amiga key).

a/b 25 January 2022 03:33

Not sure about gadgets but have you tried opening a window with IDCMP flags also containing IDCMP_MENUPICK, to get menu selections via GetMsg(), along mouse and key events (e.g. if you set them to IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_MENUPICK).
Then when you get a message, check if im_Class contains IDCMP_MENUPICK bit, and use im_Code to locate the right menu item via _LVOItemAddress().
For amiga/shift/ctrl/alt keys, check im_Qualifier field for IEQUALIFIER_XXX bits when you receive an IDCMP_RAWKEY event.

Sim085 25 January 2022 09:11

I can confirm I have the IDCMP_MENUPICK as part of the window flag. Indeed if focus is on the window itself everything works fine. I press AmigaR+S and I capture the event through the logic within my check if msg class is IDCMP_MENUPICK.

The problem is that no such event is raised when the focus is on the String_Kind gadget.

Quote:

Originally Posted by a/b (Post 1528800)
Not sure about gadgets but have you tried opening a window with IDCMP flags also containing IDCMP_MENUPICK, to get menu selections via GetMsg(), along mouse and key events (e.g. if you set them to IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_MENUPICK).
Then when you get a message, check if im_Class contains IDCMP_MENUPICK bit, and use im_Code to locate the right menu item via _LVOItemAddress().
For amiga/shift/ctrl/alt keys, check im_Qualifier field for IEQUALIFIER_XXX bits when you receive an IDCMP_RAWKEY event.


Thomas Richter 25 January 2022 10:23

Quote:

Originally Posted by Sim085 (Post 1528794)
The command keys work fine when focus is on the window itself. However when focus in on one of the STRING_KIND gadgets these do not work.


This is intentional. The string gadget evaluates such keys, in particular the (default or not) string hook of intuition. String gadgets can implement on such key events their own activity. For example, the "StringSnip" utility from Aminet replaces the global intuition input hook to allow copy and paste from the clipboard for string gadgets.

thomas 25 January 2022 10:51

You can implement an edit hook using the GTST_EditHook tag which returns control to Intuituion if the right Amiga key is pressed.

The hook function could look like this:

Code:

#include <intuition/sghooks.h>

__saveds
ULONG edithook_func (struct Hook *hook,struct SGWork *sgw, ULONG *msg)

{
if (*msg == SGH_KEY)
        {
        if (sgw->EditOp != EO_NOOP)
                if (sgw->IEvent->ie_Qualifier & IEQUALIFIER_RCOMMAND)
                        sgw->Actions = (sgw->Actions & ~SGA_USE) | SGA_END | SGA_REUSE;

        return (~0);
        }

return (0);
}


Sim085 25 January 2022 15:36

Thank you thomas for the code snippet. I adapted that for my code and it worked like a charm. Unfortunately I still find it hard to read some parts of it. With regards to this line of code what is it actually saying?

Code:

sgw->Actions = (sgw->Actions & ~SGA_USE) | SGA_END | SGA_REUSE;
I know what & ~ and | do, but in terms of readability how does one arrive to that? For example, why couldn't it be sgw->Actions = SGA_REUSE; ?

As I said I know it works, it is just that I still cannot get my head around it :nervous

Quote:

Originally Posted by thomas (Post 1528825)
You can implement an edit hook using the GTST_EditHook tag which returns control to Intuituion if the right Amiga key is pressed.

The hook function could look like this:

Code:

#include <intuition/sghooks.h>

__saveds
ULONG edithook_func (struct Hook *hook,struct SGWork *sgw, ULONG *msg)

{
if (*msg == SGH_KEY)
    {
    if (sgw->EditOp != EO_NOOP)
        if (sgw->IEvent->ie_Qualifier & IEQUALIFIER_RCOMMAND)
            sgw->Actions = (sgw->Actions & ~SGA_USE) | SGA_END | SGA_REUSE;

    return (~0);
    }

return (0);
}



I did not know about the StringSnip tool. Thank you for pointing it to me, will try it out.

Quote:

Originally Posted by Thomas Richter (Post 1528819)
This is intentional. The string gadget evaluates such keys, in particular the (default or not) string hook of intuition. String gadgets can implement on such key events their own activity. For example, the "StringSnip" utility from Aminet replaces the global intuition input hook to allow copy and paste from the clipboard for string gadgets.


thomas 25 January 2022 16:12

Quote:

Originally Posted by Sim085 (Post 1528865)
I know what & ~ and | do,

Not quite sure if you really know the difference between & and && resp. | and ||.

The double operators are boolean operators. They act on the whole variable at once, each non-zero value is treated as "true" while zero is treated as "false".

The single operators in contrast act on each corresponding bit of the operators individually.

So while 1 && 2 is true because both values are non-zero, the result of 1 & 2 is 0 because if you binary-and a binary 01 with a binary 10, both bits are different.

Now sgw->Actions is not a value but a bit mask consisting of many different bits which each has a seperate meaning. And because I don't know which bits are already set, I cannot just poke a new value into the Actions field, but have to act only on the bits I want to change.

Quote:

but in terms of readability how does one arrive to that? For example, why couldn't it be sgw->Actions = SGA_REUSE; ?
The values of SGA_USE, SGA_END and SGA_REUSE are all single bits.

The intention is to clear the SGA_USE bit and set the SGA_END and SGA_REUSE bits.

In order to clear the SGA_USE bit I bitwise-and the value of Actions with all other bits set and only the SGA_USE bit cleared. The result is that all other bits remain untouched and SGA_USE is cleared.

In order to set SGA_END amd SGA_REUSE I can just bitwise-or these values to the value of Action.

Maybe this is a bit more readable, but depending on (the lack of) the compiler's optimization capabilities it might create some unneeded code:

Code:

sgw->Actions &= ~SGA_USE;        // clear SGA_USE bit
sgw->Action |= SGA_END;        // set SGA_END bit
sgw->Action |= SGA_REUSE;        // set SGA_REUSE bit


Sim085 26 January 2022 11:10

Thank you for the explanation. I now understand better what is going on.

Quote:

Originally Posted by thomas (Post 1528872)

Maybe this is a bit more readable, but depending on (the lack of) the compiler's optimization capabilities it might create some unneeded code:

Code:

sgw->Actions &= ~SGA_USE;    // clear SGA_USE bit
sgw->Action |= SGA_END;    // set SGA_END bit
sgw->Action |= SGA_REUSE;    // set SGA_REUSE bit




All times are GMT +2. The time now is 16:20.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.08524 seconds with 11 queries