English Amiga Board


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

 
 
Thread Tools
Old 02 July 2021, 18:13   #1
Warty
Registered User

 
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 238
Help (or example) Needed for Mutually Exclusive SpeedBar Buttons

I'm building Reaction support into my app, it's the first time working with Reaction, and I could use some help.

I have a SpeedBar, with 2 groups of buttons (see attachment):

| sort by date | sort by name | sort by size | sort by type| (ideally a spacer here) view as columns | view as list | view as icons |

All the buttons are toggles. Any button in the first group should de-select all other buttons in the first group, but not do anything to buttons in the second group. An vice versa.

It *looks* to me as if this is supported by SpeedBar. From the docs:
--
SBNA_MXGroup (BOOL) (V41)
Set the MXGroup a button belongs in. This setting implies the
SBNA_Toggle setting as TRUE also. The default is ~0, or not
in any MXGroup. Note, a single speedbar can contain several
MX groupings and mixtures of toggles and normal selections!
--
SBNA_Toggle (BOOL) (V41)
Designates the button as a boolean toggle button. Defaults FALSE.
--

it's not clear to me how to set these up though, and I couldn't find any examples online. I tried configuring it with the assumption that it works as the mutually exclusive menu items work in RKM.
--
<<group 1 buttons>>
[DEBUG] make_speedbar_list 255: mX group for button i 1 = 14
[DEBUG] make_speedbar_list 255: mX group for button i 2 = 13
[DEBUG] make_speedbar_list 255: mX group for button i 3 = 11
[DEBUG] make_speedbar_list 255: mX group for button i 4 = 7
<<group 2 below>>
[DEBUG] make_speedbar_list 255: mX group for button i 5 = 224
[DEBUG] make_speedbar_list 255: mX group for button i 6 = 208
[DEBUG] make_speedbar_list 255: mX group for button i 7 = 176
--

works out to |00001110| for button 1, |00001101| for button 2, etc.

I start out with button 1 and button 5 selected. It doesn't seem to matter what I do with the MXgroup though.

Am I calculating the number wrong? Or do I have a false expectation of how this is supposed to work? I don't care if I have to manage the behavior myself at this point, but obviously if there's some built-in support, that's one less bit of code to maintain on my side.

The other thing I noticed, is that when I Have MXgroup set, the computer gets REALLY slow when the cursor is over the speedbar. Move cursor off the speedbar, the slowdown goes away.
Attached Thumbnails
Click image for larger version

Name:	Screen Shot 2021-07-02 wb2k speedbar buttons.png
Views:	59
Size:	2.3 KB
ID:	72437  
Warty is offline  
Old 05 July 2021, 07:53   #2
Warty
Registered User

 
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 238
If anyone knows how to make that MX stuff work, let me know.

I had to move on, so I coded up my own solution. It works ok, but there is a little "flash" every time a button is pressed. I think this happens because I detach the list from the speedbar, go through and change the selected on/off for some grouped buttons, and then reattach the list. I don't KNOW that's why it flickers.

In case anyone else tries, I also couldn't find a way to (cleanly) get a spacer going, so I ended up adding a button with a blank graphic, and adding it as a disabled button. Looks fine. Anyway, I tried setting SBNA_Left, but looks like you can't override the "automatic" setting described in the Autodoc. Probably for the best, since users can configure Reaction styles in their prefs.

In my workaround, I decided to use the SBNA_MXGroup value [set up for Reaction]. Seems as good a way to do it as any other. And if I ever learn how to get the mutually exclusive native code working, I can just take out part of my code.

This is in the loop to set up each button. If following along in the speedbar code example from the 3.2 NDK, this is just before the node = (struct Node *)AllocSpeedButtonNode() bit.

Code:
// set mutual exclusion
if (i < SBID_SPACER)
{
	// the sort buttons
	mutual_exclusion = (0x0F & ~(1<<(i-1))); // mask off all lower 4 buttons, then unmask the current button
	//DEBUG_OUT(("make_speedbar_list %d: mX group for button i %i = %i", __LINE__, i, mutual_exclusion ));
}
else
{
	// the view as... buttons
	mutual_exclusion = (0xF0 & ~(1<<(i-1))); // mask off all 3 of the higher nibble buttons, then unmask the current button			
}

Then, in the event handler, once you know a speedbar gadget has been clicked and you have the clicked button ID ("reaction_code" here), iterate through the buttons and set selected=no for any that are in the same MX group (if already selected).

Code:
// handle radio button behavior because I can't figure out how reaction is supposed to be handling it
// idea is to reuse the MXGroup values set for Reaction
{
	struct Node*	clicked_node;
	struct Node*	this_node;
	ULONG			mutual_exclusion = 0;							
	BYTE			i;

	clicked_node = find_speedbar_node(&speedbar_list, (int)reaction_code);

	if (clicked_node == NULL)
	{
		LOG_ERR(("deselect_speedbar_node %d: couldn't find a node matching clicked button id %i", __LINE__, (int)reaction_code));
		App_Destroy(); // crash early, crash often
	}
	
	GetSpeedButtonNodeAttrs(clicked_node, SBNA_MXGroup, &mutual_exclusion, TAG_DONE);
	
	//DEBUG_OUT(("AboutWindow_HandleEvents %d: clicked button's mx is %lu", __LINE__, mutual_exclusion));
	
	// detach list from SpeedBar gadget: required before values can be modified
	SetGadgetAttrs(the_about_window->gadgets_[ABOUT_GID_SPEEDBAR], the_about_window->window_, NULL, SPEEDBAR_Buttons, ~0, TAG_DONE);
	
	for (i = SBID_SORT_BY_NAME; i < SBID_LAST; i++)
	{
		if ( (1<<(i-1)) & mutual_exclusion )
		{
			deselect_speedbar_node(&speedbar_list, i);
			//DEBUG_OUT(("AboutWindow_HandleEvents %d: deselecting button %i for MX reasons (mask=%lu, this=%i)", __LINE__, i, mutual_exclusion, 1<<(i-1)));
		}
	}
	
	// reattach list
	SetGadgetAttrs(the_about_window->gadgets_[ABOUT_GID_SPEEDBAR], the_about_window->window_, NULL, SPEEDBAR_Buttons, &speedbar_list, TAG_DONE);
	
}
2 little helper classes to find individual nodes in the speedbar (and de-select them). Is there some function that will do this for me, so I don't have to step through the exec list?

Code:
// find a specific node within the speedbar list
struct Node* find_speedbar_node(struct List* the_speedbar_list, BYTE button_id)
{
	// LOGIC:
	//   iterate through the exec list for the speedbar, and find the node (button) that matches the passed ID
	//   does not use SBNA_ButtonID because it doesn't exist. 
	//   as of 3.2, the IDs are stored in ln_Pri (priority), which is a hack, but the way it works. 
	//   from speedbar_gc.doc: "Note the current limitation, ln_Pri is a BYTE. This will be addressed, and *posibly* made obsolete and overridden by SBNA_ButtonID."
	struct Node*	this_node;
	struct Node*	next_node;

	this_node = the_speedbar_list->lh_Head;
	
	while (next_node = this_node->ln_Succ)
	{
		if (this_node->ln_Pri == button_id)
		{
			return this_node;
		}
		this_node = next_node;
	}
	
	LOG_ERR(("find_speedbar_node %d: couldn't find a node matching button id %u", __LINE__, button_id));
	return NULL;
}

// modify the properties of a speedbar button by deselecting it. Used to simulate mutual exclusive buttons
void deselect_speedbar_node(struct List* the_speedbar_list, BYTE button_id)
{
	struct Node*	the_button_node;
	boolean			had_been_selected = false;
	
	the_button_node = find_speedbar_node(the_speedbar_list, button_id);
	
	if (the_button_node == NULL)
	{
		LOG_ERR(("deselect_speedbar_node %d: couldn't find a node matching button id %u", __LINE__, button_id));
		//return false;
		App_Destroy(); // crash early, crash often
	}
	
	GetSpeedButtonNodeAttrs(the_button_node, SBNA_Selected, &had_been_selected, TAG_DONE);
	
	if (had_been_selected)
	{
		SetSpeedButtonNodeAttrs(the_button_node, SBNA_Selected, FALSE, TAG_DONE);
	}
}
Attached Thumbnails
Click image for larger version

Name:	Screen Shot 2021-07-04 wb2k speedbar_buttons.png
Views:	41
Size:	2.5 KB
ID:	72462  
Warty is offline  
Old 05 July 2021, 10:28   #3
Minuous
Coder/webmaster/gamer
Minuous's Avatar
 
Join Date: Oct 2001
Location: Canberra/Australia
Posts: 2,343
SBNA_Spacing will adjust the spacing between each button individually, but be aware that OS3.2 speedbar.gadget (V47.8) puts the space to the right of the button, whereas OS3.9 and OS4.1 both put the space to the left. This will be fixed in BB1.

I haven't used SBNA_MXGroup so will need to check exactly how that is used and get back to you. The documentation of that tag certainly needs improving.
Minuous is offline  
Old 05 July 2021, 15:24   #4
hooverphonique
ex. demoscener "Bigmama"

 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,297
Looking at what you posted, it sounds to me as MXGroup isn't a boolean, but a number indicating which mutually exclusive group a button is in.
The number should then be assigned to all buttons which are mx with each other.

Disclaimer: I know nothing about ReAction.
hooverphonique is offline  
Old 05 July 2021, 16:33   #5
Warty
Registered User

 
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 238
Quote:
Originally Posted by Minuous View Post
SBNA_Spacing will adjust the spacing between each button individually, but be aware that OS3.2 speedbar.gadget (V47.8) puts the space to the right of the button, whereas OS3.9 and OS4.1 both put the space to the left. This will be fixed in BB1.
Thanks for pointing that out. Not sure why I gave up on SBNA_Spacing so quickly, but it does indeed work fine (with caveat above that it puts it on a different side than described in the Autodocs).
Warty is offline  
Old 06 July 2021, 11:52   #6
Minuous
Coder/webmaster/gamer
Minuous's Avatar
 
Join Date: Oct 2001
Location: Canberra/Australia
Posts: 2,343
SBNA_MXGroup turns out to be really easy to use; you just specify which group number you want and the gadget takes care of all the rest, no need for bitwise flags. Eg. if you have 6 buttons, and you want the 1st-4th to be one group, and the 5th-6th to be another group, you could specify SBNA_MXGroup, 0 for the first four buttons and SBNA_MXGroup, 1 for the other two.
Minuous is offline  
Old 06 July 2021, 19:48   #7
Warty
Registered User

 
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 238
Thanks for looking into it. Well, that's definitely a very simple solution. Kind of bummed I didn't try it out.

BTW, is there a GitHub or anything for filing bugs or suggestions about the Autodocs? I know they are part of the code, and it's not open source, so that limits contributions from us, but there are probably some bits that could be improved.
Warty is offline  
Old 07 July 2021, 00:07   #8
Minuous
Coder/webmaster/gamer
Minuous's Avatar
 
Join Date: Oct 2001
Location: Canberra/Australia
Posts: 2,343
If you write something here or at the official support forum ( https://forum.hyperion-entertainment.com/index.php ) I'll see it. Eg. I already improved the speedbar.gadget SBNA_MXGroup autodocs today in preparation for the next NDK update.
Minuous is offline  
Old 07 July 2021, 01:57   #9
Warty
Registered User

 
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 238
Thanks Minuous. I'll post here then (don't have an account over there).

fuelgauge_gc.doc:

Not sure this is wrong, but seems like you wouldn't use background pen for the FILL part of the fuel gauge, especially if you are also using background for the empty part.

Quote:
FUELGAUGE_EmptyPen (WORD)
Pen number used to render the empty section of the gauge.

Defaults to BACKGROUNDPEN.

Applicability is (OM_NEW, OM_SET, OM_UPDATE)

FUELGAUGE_FillPen (WORD)
Pen number used to render the filled section of the gauge.

Defaults to BACKGROUNDPEN.

Applicability is (OM_NEW, OM_SET, OM_UPDATE)
Warty is offline  
Old 07 July 2021, 06:36   #10
Minuous
Coder/webmaster/gamer
Minuous's Avatar
 
Join Date: Oct 2001
Location: Canberra/Australia
Posts: 2,343
Yes, looks like a copy/paste error. The default pen for FUELGAUGE_FillPen is indeed FILLPEN.
Minuous is offline  
Old 07 July 2021, 08:14   #11
Warty
Registered User

 
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 238
Maybe another: is WINDOW_Qualifier supposed to be a ULONG or UWORD? Doc has UWORD, but I was getting warning when doing GetAttr for it, switched to ULONG, and warning goes away. See uint32 in some 4.x sources online, FWIW.

GetAttr(WINDOW_Qualifier, the_surface->objects_[MAIN_OID_PRIMARY], &the_qualifiers);

UWORD the_qualifiers: warning
ULONG the_qualifiers: no warning


RKRM has intuimessage's qualifier as a UWORD though.

Quote:
WINDOW_Qualifier (UWORD)
Current qualifiers from the IntuiMessage.Qualifier field.
Useful for obtaining the qualifiers after WM_HANDLEINPUT
has returned. (V47)

Applicability is (OM_GET)
Warty is offline  
Old 07 July 2021, 09:24   #12
Minuous
Coder/webmaster/gamer
Minuous's Avatar
 
Join Date: Oct 2001
Location: Canberra/Australia
Posts: 2,343
They are passed as tags, and tags are always handled as ULONGs.
Minuous is offline  
Old 08 July 2021, 16:15   #13
Warty
Registered User

 
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 238
ah, of course. Doh.
Warty 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
Atari ST exclusive games s2325 Retrogaming General Discussion 709 03 November 2021 02:19
Exclusive use of Right and Left Windows Keys cybermat support.FS-UAE 11 04 November 2016 12:06
Map spare gamepad buttons to left/right mouse buttons (for skipping intros) dreamkatcha support.FS-UAE 6 03 February 2013 00:03
CD32 exclusive games? Antiriad Retrogaming General Discussion 18 01 April 2012 09:59
CD-32 exclusive games ? Overdoc Nostalgia & memories 27 26 July 2006 22:29

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 18:07.


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