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

How to create dialog or menu like attached picture after right click event?

Newbie
Participant

As shown in picture, is there any suggestion of how to detect right click event then create select able menu with API functions?

 


Screenshot 2023-07-26 214805.png
2 REPLIES 2
Joel Buehler
Enthusiast
Miklos Vegh
Graphisoft
Graphisoft

You can detect right mouse click by implementing/overriding the

 

virtual void ListBoxContextMenuRequested (const ListBoxContextMenuEvent& ev, bool* processed);

 

virtual function of the ListboxObserver.

And you can create a custom context menu like this:

 

void OpenContextMenu (const DG::NativePoint& pos)
{
	const ULong CmdId1 = 1001;
	const ULong CmdId2 = 1002;
	const ULong CmdId3 = 1003;

	DG::Command cmd1 (CmdId1, 0, 0);
	DG::Command cmd2 (CmdId2, 0, 0);
	DG::Command cmd3 (CmdId3, 0, 0);
	DG::CommandDescriptor cmddesc1(cmd1, GS::UniString ("Command 1"));
	DG::CommandDescriptor cmddesc2(cmd2, GS::UniString ("Command 2"));
	DG::CommandDescriptor cmddesc3(cmd3, GS::UniString ("Command 3"));

	GS::UniString menuNameStr ("ContextMenu");
	DG::Menu* menu = new DG::Menu (menuNameStr);
	if (menu == nullptr)
		return;

	menu->AddMenuItem (DG::MenuSimpleItem (CmdId1));
	menu->AddMenuItem (DG::MenuSimpleItem (CmdId2));
	menu->AddMenuItem (DG::MenuSimpleItem (CmdId3));
	DG::ContextMenu* contextMenu = new DG::ContextMenu (menuNameStr, menuNameStr, menu);
	if (contextMenu == nullptr) {
		delete menu;
		return;
	}

	DG::CommandTable enabledCommands;
	enabledCommands.Put (CmdId1, &cmddesc1);
	enabledCommands.Put (CmdId2, &cmddesc2);
	enabledCommands.Put (CmdId3, &cmddesc3);
	contextMenu->SetEnabledCommands (enabledCommands);

	Int32 commandId = 0;
	DG::CommandEvent* commandEvent = contextMenu->Display (pos);
	if (commandEvent != nullptr)
		commandId = commandEvent->GetCommand ().GetCommandId ();

	delete commandEvent;
	delete contextMenu;
	delete menu;

	switch (commandId) {
		case CmdId1:
		case CmdId2:
		case CmdId3:
			break;

		default:
			break;
	}
}

 

 

Or you can also create a popup-like dialog with a listbox or any other controls inside. The popup like dialog is closed on a mouseclick outside of the dialog area. You can set the popup-like style with the DG::Dialog::SetPopupStyle() member function. Popup dialogs must not have caption and sizeable flag. See the following example:

'GDLG'   SAMPLE_POPUP_DLG_ID  Modal | noFrame | noCaption | noGrow  0    0  100  100  "" {
/* [  1] */ LeftText			    5    5  90   23	SmallPlain  vCenter  "Text"
}

'DLGH'   SAMPLE_POPUP_DLG_ID  DLG_SAMPLE_POPUP {
1	""	LeftText_0
}

 

class SamplePopupDialog: public DG::ModalDialog,
						 public DG::PanelObserver
{
	enum {
		LeftTextId	= 1
	};

	DG::LeftText text;
	const DG::NativeRect& openButtonScreenRect;

public:
	SamplePopupDialog(const DG::NativeRect& openButtonScreenRect_);
	~SamplePopupDialog();

	virtual void	PanelOpened (const DG::PanelOpenEvent& ev) override;
};


SamplePopupDialog::SamplePopupDialog (const DG::NativeRect& dialogOpeningButtonScreenRect_, ...):
	DG::ModalDialog	(resModule, SAMPLE_POPUP_DLG_ID, resModule),
	text (GetReference (), LeftTextId),
	dialogOpeningButtonScreenRect (dialogOpeningButtonScreenRect_)
{
	SetPopupStyle ();
	Attach (*this);
}


SamplePopupDialog::~SamplePopupDialog ()
{
	Detach (*this);
}


void	SamplePopupDialog::PanelOpened (const DG::PanelOpenEvent& /*ev*/)
{
	DG::Utils::PlaceDialogNextToNativeRect (*this, dialogOpeningButtonScreenRect, DG::Utils::RightCenter);
}