English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 27 July 2021, 20:21   #1
Sim085
Registered User
 
Join Date: Apr 2009
Location: N/A
Posts: 830
Intuition On Click Event?

I have gone through the documentation and cannot understand what I am doing wrong. Hopefully someone can help.

I have a window with a list and a text field. I want the focus to remain always in the text field regardless where the user clicks.

At first I thought of using IDCMP_INTUITICKS event and use ActivateGadget on each tick. However I was never much in love with the idea as this means calling ActivateGadget for the text field even when this is already in focus.

I therefore opted to instead only call ActivateGadget when the list is clicked or when the window is clicked. I thought the easiest way to do this is to listen for the IDCMP_MOUSEBUTTONS event (SELECTDOWN). This does work when clicking on the window, but not when clicking in the window title bar or the list.

So in addition to IDCMP_MOUSEBUTTONS I also listen to IDCMP_GADGETUP. When I receive the event I check if the event is for my list and if so I use ActivateGadget on the text field. This works for this list but ONLY WHEN the list actually has an entry in it. If the list is empty then no IDCMP_GADGETUP event is triggered.

So far I have not found how to capture an on click event on the title bar.

Does anyone have any idea how I can capture an on click event on the title bar and a list (when this is empty)?
Sim085 is offline  
Old 27 July 2021, 23:09   #2
thomas
Registered User
thomas's Avatar
 
Join Date: Jan 2002
Location: Germany
Posts: 6,352
Probably the only way to do this is to sub-class STRGCLASS and overload its GM_HANDLEINPUT method. When STRGCLASS decides to let go, change the return value to keep focus.
thomas is offline  
Old 28 July 2021, 12:02   #3
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 1,317
In general, I believe it is a bad idea to patronize the user. Thus, if the user decides to click somewhere else, for whatever reason, then the program should rather tolerate that.
Thomas Richter is offline  
Old 28 July 2021, 16:08   #4
Sim085
Registered User
 
Join Date: Apr 2009
Location: N/A
Posts: 830
To be honest I only meant to implement this logic in order to save the user from doing some extra clicks.

A clear example is when moving the window. Left as is, the user would move the window and then have to click on the text field to enter some text. What I wanted is that the user would not need to click on the text field after moving the window because he would see the focus is already on this. Same thing as when re-activating a window by clicking anywhere on it, user would need to then need to do another click on the text field to continue using the application.

I know it is sugar candy but thought it would be a nice touch.

Quote:
Originally Posted by Thomas Richter View Post
In general, I believe it is a bad idea to patronize the user. Thus, if the user decides to click somewhere else, for whatever reason, then the program should rather tolerate that.

Would I need to use BOOPSI to be able to do this?

Quote:
Originally Posted by thomas View Post
Probably the only way to do this is to sub-class STRGCLASS and overload its GM_HANDLEINPUT method. When STRGCLASS decides to let go, change the return value to keep focus.
Sim085 is offline  
Old 28 July 2021, 17:51   #5
bebbo
botcher

 
Join Date: Jun 2016
Location: Hamburg/Germany
Posts: 544
Quote:
Originally Posted by Sim085 View Post
To be honest I only meant to implement this logic in order to save the user from doing some extra clicks.

A clear example is when moving the window. Left as is, the user would move the window and then have to click on the text field to enter some text. What I wanted is that the user would not need to click on the text field after moving the window because he would see the focus is already on this. Same thing as when re-activating a window by clicking anywhere on it, user would need to then need to do another click on the text field to continue using the application.

I know it is sugar candy but thought it would be a nice touch.

Would I need to use BOOPSI to be able to do this?

As usally - I know nothing - but maybe this helps:


open the input.device
add a handler
that handler checks input events for IECLASS_ACTIVEWINDOW
signal your task or send a msg
...




just guessing^^
bebbo is offline  
Old 28 July 2021, 18:17   #6
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 1,317
Window activation as IDCMP exists, so there is certainly a possibility to activate a gadget when the user activates the window. That seems to be the most straight-forwared way of doing it. Some care should be taken if there are multiple string gadgets on the same window as then the input focus could potentially change.

A good principle to follow is "principle of least surprise", i.e. don't make any changes that have not been triggered by the user explicitly.
Thomas Richter is offline  
Old 28 July 2021, 18:26   #7
bebbo
botcher

 
Join Date: Jun 2016
Location: Hamburg/Germany
Posts: 544
Quote:
Originally Posted by Thomas Richter View Post
Window activation as IDCMP exists, so there is certainly a possibility to activate a gadget when the user activates the window. That seems to be the most straight-forwared way of doing it. Some care should be taken if there are multiple string gadgets on the same window as then the input focus could potentially change.

A good principle to follow is "principle of least surprise", i.e. don't make any changes that have not been triggered by the user explicitly.

maybe someone is able to track the last selected input gadget...
bebbo is offline  
Old 30 July 2021, 17:17   #8
Sim085
Registered User
 
Join Date: Apr 2009
Location: N/A
Posts: 830
I managed to achieve that with IDCMP_ACTIVEWINDOW. Now when user focus again on my window it immediately focuses the user on the single text field that I have.

With IDCMP_CHANGEWINDOW I managed to also keep the focus on the single text field when the window is moved. (In the future I should not judge an event by its name, thought this was triggered when user "changed" window).

With the IDCMP_MOUSEBUTTONS I have the click on anywhere on the window not covered by a gadget. Documentation says that this is only issued if not used internally by Intuition so I do not see it as that bad.

The only issue I have is with the list gadget. I cannot understand why when the list has no items it does not trigger the IDCMP_GADGETDOWN even (or IDCMP_GADGETUP).

Quote:
Originally Posted by Thomas Richter View Post
Window activation as IDCMP exists, so there is certainly a possibility to activate a gadget when the user activates the window. That seems to be the most straight-forwared way of doing it. Some care should be taken if there are multiple string gadgets on the same window as then the input focus could potentially change.

A good principle to follow is "principle of least surprise", i.e. don't make any changes that have not been triggered by the user explicitly.
Sim085 is offline  
Old 30 July 2021, 18:21   #9
bebbo
botcher

 
Join Date: Jun 2016
Location: Hamburg/Germany
Posts: 544
Quote:
Originally Posted by Thomas Richter View Post
A good principle to follow is "principle of least surprise"

forward this to the Kickstart developers
bebbo is offline  
Old 31 July 2021, 09:38   #10
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 1,317
Quote:
Originally Posted by Sim085 View Post
The only issue I have is with the list gadget. I cannot understand why when the list has no items it does not trigger the IDCMP_GADGETDOWN even (or IDCMP_GADGETUP).
There is nothing to click on, so why should it register something? IDCMP events are created whenever a gadget changes state, but there is nothing to change here.
Thomas Richter is offline  
Old 31 July 2021, 13:53   #11
Sim085
Registered User
 
Join Date: Apr 2009
Location: N/A
Posts: 830
Fair point.

Not sure what I can do to be honest at this point apart from leaving it as is. Other option is to add a dummy entry in the list when it is empty and than handle this case separate as part IDCMP_GADGETUP. Its a hack, but the only thing I can think of

Quote:
Originally Posted by Thomas Richter View Post
There is nothing o click on, so why should it register something? IDCMP events are created whenever a gadget changes state, but there is nothing to change here.
Sim085 is offline  
Old 31 July 2021, 15:35   #12
bebbo
botcher

 
Join Date: Jun 2016
Location: Hamburg/Germany
Posts: 544
Quote:
Originally Posted by Sim085 View Post
Fair point.

Not sure what I can do to be honest at this point apart from leaving it as is. Other option is to add a dummy entry in the list when it is empty and than handle this case separate as part IDCMP_GADGETUP. Its a hack, but the only thing I can think of

try setting the GadgetType to 0 if the list is empty, and restore the type once something is added.
bebbo is offline  
Old 31 July 2021, 22:55   #13
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 1,317
Quote:
Originally Posted by Sim085 View Post
Fair point.

Not sure what I can do to be honest at this point apart from leaving it as is. Other option is to add a dummy entry in the list when it is empty and than handle this case separate as part IDCMP_GADGETUP. Its a hack, but the only thing I can think of

Don't. The problem is that you try to achieve something that is not part of the user interface style the Os offers, so just don't force it. Other programs won't react this way either, so it is not expected to work this way anyhow.
Thomas Richter is offline  
Old 31 July 2021, 23:10   #14
Bruce Abbott
Registered User

Bruce Abbott's Avatar
 
Join Date: Mar 2018
Location: Hastings, New Zealand
Posts: 780
Quote:
Originally Posted by Sim085 View Post
The only issue I have is with the list gadget. I cannot understand why when the list has no items it does not trigger the IDCMP_GADGETDOWN even (or IDCMP_GADGETUP).
Do you get any messages at all?
Bruce Abbott is offline  
Old 01 August 2021, 00:16   #15
Sim085
Registered User
 
Join Date: Apr 2009
Location: N/A
Posts: 830
Hmm.. interesting. I test this by using the following code in the whole loop;
Code:
printf("%x\n", msg->Class);
As expected without touching anything I get the 400000 (IDCMP_INTUITICKS) printed. When I click on the list gadget I get the code f80ad4 printed. However I cannot find any IDCMP event with that code here. I have attached a screenshot.

Quote:
Originally Posted by Bruce Abbott View Post
Do you get any messages at all?
I will obviously test how the application feels and if it feels unnatural (or confusing) I would remove this or make it switchable on/off from a configuration file.

Quote:
Originally Posted by Thomas Richter View Post
Don't. The problem is that you try to achieve something that is not part of the user interface style the Os offers, so just don't force it. Other programs won't react this way either, so it is not expected to work this way anyhow.
Attached Thumbnails
Click image for larger version

Name:	Screenshot 2021-07-31 at 23.55.57.png
Views:	48
Size:	10.0 KB
ID:	72733  

Last edited by Sim085; 01 August 2021 at 00:32.
Sim085 is offline  
Old 01 August 2021, 11:02   #16
Sim085
Registered User
 
Join Date: Apr 2009
Location: N/A
Posts: 830
I did put a condition on event 0x00f80ad4. Works. But not always

I am thinking of going to the IDCMP_INTUITICKS path again. However ideally I would like to first check if my search field is already active and only call the ActivateGadget on this field if this is not activated.

But ... ... I cannot find any function to do that from here, or a way to achieve this with GT_GetGadgetAttrs as documented here.

Last edited by Sim085; 01 August 2021 at 11:42.
Sim085 is offline  
Old 01 August 2021, 15:44   #17
bebbo
botcher

 
Join Date: Jun 2016
Location: Hamburg/Germany
Posts: 544
Quote:
Originally Posted by Sim085 View Post
I did put a condition on event 0x00f80ad4. Works. But not always

I am thinking of going to the IDCMP_INTUITICKS path again. However ideally I would like to first check if my search field is already active and only call the ActivateGadget on this field if this is not activated.

But ... ... I cannot find any function to do that from here, or a way to achieve this with GT_GetGadgetAttrs as documented here.

hm:

gad->Flags & GFLG_SELECTED
does not work for you?


You could also call SetGadgetAttrsA with GFLG_SELECTED set...
bebbo is offline  
Old 01 August 2021, 17:56   #18
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 1,317
Quote:
Originally Posted by Sim085 View Post
Code:
printf("%x\n", msg->Class);
As expected without touching anything I get the 400000 (IDCMP_INTUITICKS) printed. When I click on the list gadget I get the code f80ad4 printed.
You are doing something wrong. How exactly do you retreive the message? Note that for gadtools, you need to use GT_GetIMsg(), not GetMsg(). Also, do you check the return code for GetMsg() for NULL? Note that you need to wait for a message to arrive (either Wait() or WaitPort()).
Thomas Richter is offline  
Old 01 August 2021, 18:44   #19
Sim085
Registered User
 
Join Date: Apr 2009
Location: N/A
Posts: 830
Yes that worked. I was under the impression that selected would need to be retrieved using GT_GetGadgetAttrs. I see this is a flag however not an attribute.

Quote:
Originally Posted by bebbo View Post
hm:
gad->Flags & GFLG_SELECTED
does not work for you?
This is my code;
Code:
/* Main Loop. */    
while(run)    {        

      /* Wait for an event to happen. */        
      int w = Wait(search_onKeyPressSignal | 1L << window->UserPort->mp_SigBit);

      ...

      /* Get message data. */        
      msg = (struct IntuiMessage *)GT_GetIMsg(window->UserPort);

      if(msg->Class == IDCMP_CLOSEWINDOW){ ... }
      ...

      /* Close message. */        
      GT_ReplyIMsg(msg);    
}
I do not check for nulls. I will add that. I suppose without that things might get pretty ugly at some point running the application.

Anything else looks wrong?

The f80ad4 signal is issued multiple times when I hold the mouse left button on the list gadget. But clicking multiple times some times did not trigger an event. Don't know if that helps.

This is why I reverted back to using IDCMP_INTUITICKS. Also something else I noticed is that this event is issued even if I did not register for it.

Quote:
Originally Posted by Thomas Richter View Post
You are doing something wrong. How exactly do you retreive the message? Note that for gadtools, you need to use GT_GetIMsg(), not GetMsg(). Also, do you check the return code for GetMsg() for NULL? Note that you need to wait for a message to arrive (either Wait() or WaitPort()).

Last edited by Sim085; 01 August 2021 at 19:37.
Sim085 is offline  
Old 01 August 2021, 19:23   #20
bebbo
botcher

 
Join Date: Jun 2016
Location: Hamburg/Germany
Posts: 544
Quote:
Originally Posted by Sim085 View Post
Yes that worked. I was under the impression that selected would need to be retrieved using GT_GetGadgetAttrs. I see this is a flag however not an attribute.



This is my code;
Code:
/* Main Loop. */    
while(run)    {        

      /* Wait for an event to happen. */        
      int w = Wait(search_onKeyPressSignal | 1L << window->UserPort->mp_SigBit);

      ...

      /* Get message data. */        
      msg = (struct IntuiMessage *)GT_GetIMsg(window->UserPort);

      if(msg->Class == IDCMP_CLOSEWINDOW){ ... }
      ...

      /* Close message. */        
      GT_ReplyIMsg(msg);    
}
I do not check for nulls. I will add that. I suppose without that things might get pretty ugly at some point running the application.

What exactly looks wrong?

looks good.



The most OS friendly way to get a gadget event in empty listviews seems to be setting GTLV_Labels with a one entry list of an empty string.
bebbo is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
intuition questions meynaf Coders. System 11 09 December 2020 11:27
Help needed for an Intuition event loop thyslo Coders. System 8 29 October 2018 19:08
C Intuition Help plasmab Coders. General 7 15 October 2018 09:05
ClassicWB MultiBoot Menu (right click/left click on boot) not working DuaneL project.ClassicWB 9 13 September 2016 16:32
click click bloody click Dave_wb support.Hardware 14 12 April 2005 09:31

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 13:30.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, vBulletin Solutions Inc.
Page generated in 0.11785 seconds with 14 queries