02 July 2021, 17:13 | #1 |
Registered User
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 301
|
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. |
05 July 2021, 06:53 | #2 |
Registered User
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 301
|
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); } 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); } } |
05 July 2021, 09:28 | #3 |
Coder/webmaster/gamer
Join Date: Oct 2001
Location: Canberra/Australia
Posts: 2,630
|
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. |
05 July 2021, 14:24 | #4 |
ex. demoscener "Bigmama"
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,624
|
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. |
05 July 2021, 15:33 | #5 |
Registered User
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 301
|
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).
|
06 July 2021, 10:52 | #6 |
Coder/webmaster/gamer
Join Date: Oct 2001
Location: Canberra/Australia
Posts: 2,630
|
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.
|
06 July 2021, 18:48 | #7 |
Registered User
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 301
|
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. |
06 July 2021, 23:07 | #8 |
Coder/webmaster/gamer
Join Date: Oct 2001
Location: Canberra/Australia
Posts: 2,630
|
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.
|
07 July 2021, 00:57 | #9 | |
Registered User
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 301
|
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:
|
|
07 July 2021, 05:36 | #10 |
Coder/webmaster/gamer
Join Date: Oct 2001
Location: Canberra/Australia
Posts: 2,630
|
Yes, looks like a copy/paste error. The default pen for FUELGAUGE_FillPen is indeed FILLPEN.
|
07 July 2021, 07:14 | #11 | |
Registered User
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 301
|
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:
|
|
07 July 2021, 08:24 | #12 |
Coder/webmaster/gamer
Join Date: Oct 2001
Location: Canberra/Australia
Posts: 2,630
|
They are passed as tags, and tags are always handled as ULONGs.
|
08 July 2021, 15:15 | #13 |
Registered User
Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 301
|
ah, of course. Doh.
|
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 01:19 |
Exclusive use of Right and Left Windows Keys | cybermat | support.FS-UAE | 11 | 04 November 2016 11:06 |
Map spare gamepad buttons to left/right mouse buttons (for skipping intros) | dreamkatcha | support.FS-UAE | 6 | 02 February 2013 23:03 |
CD32 exclusive games? | Antiriad | Retrogaming General Discussion | 18 | 01 April 2012 08:59 |
CD-32 exclusive games ? | Overdoc | Nostalgia & memories | 27 | 26 July 2006 21:29 |
|
|