Archicad C++ API
About Archicad add-on development using the C++ API.
SOLVED!

Radio Buttons: Enable/Disable ability to select at runtime

MudratDetector
Enthusiast

My goal is to gray out or disable the ability to select a radio button at runtime.  For example, all of these are non-grayed and selectable:

MudratDetector_0-1668017193827.png

I suspect this is a TRUE/FALSE  or a .IsEnabled/.IsDisabled setting for the individual button based on the control ID and I am already able to determine which ones get which setting.  I am also guessing I can loop through the controls collection and apply the predetermined setting to each button as it comes up in the for loop.

What I am not sure of is how to acquire the controls collection and the type or use of the control ID.

MudratDetector_1-1668017666610.png

Is the control ID the string ["JHP_UL_AB"] or the other reference [RadioButton_0] from the .grc file?

MudratDetector_2-1668017913968.png

Is the control ID the non-string [UL_AB_Radio] or the other reference [UL_ABID] from the class definition?

MudratDetector_3-1668018077997.png

I suspect it is the non-string [UL_AB_Radio] since I am able to know which button is selected by using the non-string and provide the corresponding argument to a function that will determine the enable/disable state.

In testing, I am successfully scanning a list of strings that represents the control IDs for each individual radio button and verify the setting with text output to the Report window.

 

 

	list<std::string> strCategories;
	if (argc != "")
	{
		strCategories = { argc };
	}
	else
	{
		strCategories = { "UL_AB", "UL_DEF", "UL_GH", "UL_I", "UL_JK", "UL_LM", "UL_NO", "UL_PQR", "UL_UVW" }; // , "UL_X", "UL_C-AJ-", "UL_F-A-", "UL_F-B-", "UL_F-C-", "UL_W-L-"
	}

	for (list<std::string>::iterator i = strCategories.begin(); i != strCategories.end(); i++)
	{ // determine enable/disable state of each radio button and set accordingly

 

 

I am looking for the correct type format to build this list and the proper syntax to apply the enable/disable setting to each button using the list.

Please and thank-you.  Have a great day!
Chris
 

Chris Gilmer
Intel i9-12950HX CPU @ 2.30GHz, 16 cores
NVIDIA GeForce RTX 3080
48.0 GB RAM
Windows 10 Pro 64-bit
1 ACCEPTED SOLUTION

Accepted Solutions
Solution

In which fonction of your dialog class you put the disable logic will depend on the behaviour you want.

 

I wouldn't place any logic in the constructor  though.

I'm quite new to this so I'm not completely certain, but for code clarity and to avoid any hard to trace bugs  i'd use the dialog functions to do all the work.

 

The point of my post was that DGDisableItem(32500, UL_DEFID); is the old C syntax which the API is moving away from. The one I posted is the new c++ implementation which you should prefer. Avoid mixing C and C++ any chance you get.

 

 

View solution in original post

10 REPLIES 10
MudratDetector
Enthusiast

I think I have narrowed down what I am looking for.  If I hover over any of the Radio Buttons, a tool tip sort of identifier appears and I suspect that this is the Control ID I am looking for.

MudratDetector_0-1668115625485.png

 

Or maybe not.  Chipping away at it over here boss...

 

Chris Gilmer
Intel i9-12950HX CPU @ 2.30GHz, 16 cores
NVIDIA GeForce RTX 3080
48.0 GB RAM
Windows 10 Pro 64-bit
MudratDetector
Enthusiast

If you dig deep enough, you will finally have a hole...

 

Hard coding this:

DGDisableItem(32500, UL_DEFID);

Results in this:

MudratDetector_1-1668117944355.png

 

Now... to just loop through the Controls collection and be able to access and manipulate with the non-string identifier.

 

Chris Gilmer
Intel i9-12950HX CPU @ 2.30GHz, 16 cores
NVIDIA GeForce RTX 3080
48.0 GB RAM
Windows 10 Pro 64-bit

in you dialog class you should have a panelOpened function.

All you have to do is add:

nameOfYourRadioButton.Disable();

 

of course you can add any logic you want to it so its disabled/enabled as you wish

Thanks for the reply Julien.

 

I am currently accomplishing this button availability exercise in my constructor.  The code below disables all buttons without the logic in place to determine which ones get the ax.  This configuration is only proof of concept for me.

 

JHP_UL_Dialog::JHP_UL_Dialog() :
	DG::ModalDialog(ACAPI_GetOwnResModule(), 32500, ACAPI_GetOwnResModule()),
	UL_JHP_Button(GetReference(), UL_JHPID),
	GA_JHP_Button(GetReference(), GA_JHPID),
	UL_ONLINE_Button(GetReference(), UL_ONLINEID),
	GA_ONLINE_Button(GetReference(), GA_ONLINEID),

	UL_BOX_0(GetReference(), UL_BOX_0ID),
	UL_AB_Radio(GetReference(), UL_ABID),
	UL_C_Radio(GetReference(), UL_CID),
	//more of the same
	OK_Button(GetReference(), OkID),
	Cancel_Button(GetReference(), CancelID),
	UL_LOGO_Icon(GetReference(), LOGOID),
	File_Button(GetReference(), FileID),
	Verify_Button(GetReference(), VerifyID)
{
	short arrRadBut[11] = { UL_ABID, UL_DEFID, UL_GHID, UL_IID, UL_JKID, UL_LMID, UL_NOID, UL_STID, UL_PQRID, UL_UVWID, UL_XYZID};
	for (int k=0;k<11;k++)
		DGDisableItem(32500, arrRadBut[k]);

	AttachToAllItems(*this);
}

 

 Is there a disadvantage to performing this task here in the constructor?  Or am I better served by creating:

 

JHP_UL_Dialog::PanelOpened()
	short arrRadBut[11] = { UL_ABID, UL_DEFID, UL_GHID, UL_IID, UL_JKID, UL_LMID, UL_NOID, UL_STID, UL_PQRID, UL_UVWID, UL_XYZID};
	for (int k=0;k<11;k++)
		DGDisableItem(32500, arrRadBut[k]);

 

and removing the button settings from my constructor?

 

Thanks for any insight you can provide to my continued learning effort.

Chris

Chris Gilmer
Intel i9-12950HX CPU @ 2.30GHz, 16 cores
NVIDIA GeForce RTX 3080
48.0 GB RAM
Windows 10 Pro 64-bit
Solution

In which fonction of your dialog class you put the disable logic will depend on the behaviour you want.

 

I wouldn't place any logic in the constructor  though.

I'm quite new to this so I'm not completely certain, but for code clarity and to avoid any hard to trace bugs  i'd use the dialog functions to do all the work.

 

The point of my post was that DGDisableItem(32500, UL_DEFID); is the old C syntax which the API is moving away from. The one I posted is the new c++ implementation which you should prefer. Avoid mixing C and C++ any chance you get.

 

 

Thank you for that explanation.  I am pretty new to this as well and don't know what I don't know.  But I did grab that approach using DGDisableItem from the AC API 24 documentation.

MudratDetector_0-1668193580136.png

After a little more study, I can see the benefit of not putting logic in the constructor.   And now the line is not as blurred between straight up initialization and logic used for initialization.  Also a long time fan of the one job > one function approach.

Porting this old AutoCAD tool into Archicad continues to be quite the adventure.

Thanks again,

chris

Chris Gilmer
Intel i9-12950HX CPU @ 2.30GHz, 16 cores
NVIDIA GeForce RTX 3080
48.0 GB RAM
Windows 10 Pro 64-bit

The documentation that comes with the API still use the C implementation, refer to the one here which is more up to date but also less complete. https://archicadapi.Graphisoft.com/api-reference

and the examples in the doc.

MudratDetector
Enthusiast

After looking at examples of implementing  PanelOpened, I cannot get this to activate the same disabling action on the radio button of my dialog.  I believe I have all the parts of this in place.

 

 

 

In my class definition [in .cpp file], I have the PanelOpened function.  I know, as shown here, this is using the older C implementation, but my strategy is to confirm PanelOpened before getting that switched to the newer C++ ways.  I don't even see the ACAPI_WriteReport that is in place to confirm with somethign easy.  Maybe dialogs aren't allowed in PanelOpened?

void JHP_UL_Dialog::PanelOpened(const DG::PanelOpenEvent& /*ev*/)
{
	ACAPI_WriteReport("PanelOpened", TRUE);
	short arrRadBut[11] = { UL_ABID, UL_DEFID, UL_GHID, UL_IID, UL_JKID, UL_LMID, UL_NOID, UL_STID, UL_PQRID, UL_UVWID, UL_XYZID };
	for (int k = 0; k < 11; k++)
		DGDisableItem(32500, arrRadBut[k]);
}

I don't even see the 

 

 I also am utilizing the DG::PanelObserver, from my .hpp file.

class JHP_UL_Dialog :		public DG::ModalDialog,
									public DG::ButtonItemObserver,
									public DG::CompoundItemObserver,
									public DG::RadioItemObserver,
									public DG::PanelObserver, 
									public DG::ListBoxObserver
{
protected:
	enum Controls {
		UL_JHPID = 1,
		GA_JHPID = 2,
		// more of the same
	DG::RadioButton UL_FC_Radio;
	DG::RadioButton UL_WL_Radio;
		// more of the same

	virtual void PanelOpened(const DG::PanelOpenEvent& /*ev*/) override;
		// more of the same

 Am I missing a piece of the puzzle?  I have also tried alternate placement in either .hpp or .cpp files without success.  A point in the right direction would be appreciated.

 

thanks - chris

Chris Gilmer
Intel i9-12950HX CPU @ 2.30GHz, 16 cores
NVIDIA GeForce RTX 3080
48.0 GB RAM
Windows 10 Pro 64-bit
julienK
Advocate

I think its because you're putting the Ids  in the array,  try putting the actual name of the DG::RadioButton

i.e:

UL_FC_Radio
UL_WL_Radio