We value your input!
Please participate in Archicad 28 Home Screen and Tooltips/Quick Tutorials survey

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

Add Pop-up Control and Check Box in List Box Items.

Jahidur
Participant
I created a List Box where I will add some list items. And my plan is i will add individual Pop-up Control and Check Box with every list box item. Here I share my idea plan demo picture you will find that image in this post attachments.

I already check List specific functions and I did not find any way to do this task. If you know any kind of way to do this task it will be helpful for me if you let me know that way. Or if you let me know any example where I can get the idea to do this task that will be helpful for me too.

Here I also share the current condition of my coding part. Hope this will be helpful for you to understand my approach.

The ".hpp" File

 

// *****************************************************************************
// Header file for the AttributeList Example Dialog in DG Test Add-On
// API Development Kit 24; Mac/Win
//
// Namespaces:        Contact person:
//     -None-						LT
//
// [SG compatible] - Yes
// *****************************************************************************

#ifndef ATTRIBUTELISTDIALOG_H
#define ATTRIBUTELISTDIALOG_H

#pragma once

#include	"DGModule.hpp"

#define ATTRIBUTE_LIST_DIALOG_RESID			32590

// --- AttributeListDialog -----------------------------------------------------

class TestListDialog : public DG::ModalDialog,
	public DG::PanelObserver,
	public DG::ListBoxObserver,
	public DG::ButtonItemObserver
{
private:
	
	DG::Button					okButton;
	DG::SingleSelListBox		ListBox;
	DG::PopUp					PopupEdit;

public:

	void	ButtonClicked(const DG::ButtonClickEvent& ev) override;
	void	PanelResized(const DG::PanelResizeEvent& ev) override;
	void SetTabData(short dialId, short item);
	void TestInitListBox(short dialId);

	TestListDialog();
	~TestListDialog();
};

#endif // ATTRIBUTELISTDIALOG_H

 

The ".cpp" File

 

// *****************************************************************************
// Source code for the AttributeList Example Dialog in DG Test Add-On
// API Development Kit 24; Mac/Win
//
// Namespaces:			Contact person:
//		-None-						LT
//
// [SG compatible] - Yes
// *****************************************************************************

#include	"Test.hpp"

#include	"APIEnvir.h"
#include	"ACAPinc.h"					// also includes APIdefs.h
#include    "APIdefs.h"
//#include	"APICommon.h"
#include "DGModule.hpp"

//---------------------------- Class AttributeListDialog -----------------------

enum {
	OKButtonId = 1,
	ListBoxId = 2,
	PopupId = 3
};


TestListDialog::TestListDialog() :
	DG::ModalDialog(ACAPI_GetOwnResModule(), 32590, ACAPI_GetOwnResModule()),
	okButton(GetReference(), OKButtonId),
	ListBox(GetReference(), ListBoxId),
	PopupEdit(GetReference(), PopupId)

{
	Attach(*this);
	okButton.Attach(*this);
	TestInitListBox(32590);
}


TestListDialog::~TestListDialog()
{
	okButton.Detach(*this);
	Detach(*this);
}



void TestListDialog::SetTabData(short dialId, short item)
{
	DGListTabData lTabData[2];
	API_Rect lBox;

	DGGetItemRect(dialId, item, &lBox.left, &lBox.top, &lBox.right, &lBox.bottom);
	lBox.right -= 10;
	short width = (short)(lBox.right - lBox.left);

	lTabData[0].begPos = 0;
	lTabData[0].endPos = (short)(width);
	lTabData[0].justFlag = DG_IS_LEFT;
	lTabData[0].truncFlag = DG_IS_TRUNCEND;
	lTabData[0].hasSeparator = false;
	lTabData[0].disabled = false;

	lTabData[1].begPos = lTabData[0].endPos;;
	lTabData[1].endPos = (short)(lBox.right);//250;
	lTabData[1].justFlag = DG_IS_LEFT;
	lTabData[1].truncFlag = DG_IS_TRUNCEND;
	lTabData[1].hasSeparator = false;
	lTabData[1].disabled = false;

	DGListSetTabData(dialId, item, 2, &lTabData[0]);
}



void TestListDialog::TestInitListBox(short dialId)
{
	SetTabData(dialId, ListBoxId);
	GS::Array<GS::UniString> modulList;
	ACAPI_ModulData_GetList(&modulList);

	DGListDeleteItem(dialId, ListBoxId, DG_ALL_ITEMS);

	DGListInsertItem(dialId, ListBoxId, DG_LIST_BOTTOM);
	GS::UniString itemString = GS::UniString("First Part") + "\t" + GS::UniString("Second Part");
	DGListSetItemText(dialId, ListBoxId, DG_LIST_BOTTOM, GS::UniString(itemString.ToCStr().Get()));
	DGListSetItemColor(dialId, ListBoxId, DG_LIST_TOP, 15000, 32000, 60000);



	GS::UniString itemString2 = GS::UniString("Item Number-1") + "\t" + GS::UniString("Test-1");
	DGListInsertItem(dialId, ListBoxId, DG_LIST_BOTTOM);
	DGListSetItemText(dialId, ListBoxId, DG_LIST_BOTTOM, itemString2.ToCStr().Get());
	//DGListSetItemColor(dialId, ListBoxId, DG_LIST_TOP, 15000, 32000, 60000);


	GS::UniString itemString3 = GS::UniString("Item Number-2") + "\t" + GS::UniString("Test-2");
	DGListInsertItem(dialId, ListBoxId, DG_LIST_BOTTOM);
	DGListSetItemText(dialId, ListBoxId, DG_LIST_BOTTOM, itemString3.ToCStr().Get());

	GS::UniString itemString4 = GS::UniString("Item Number-3") + "\t" + GS::UniString("Test-3");
	DGListInsertItem(dialId, ListBoxId, DG_LIST_BOTTOM);
	DGListSetItemText(dialId, ListBoxId, DG_LIST_BOTTOM, itemString4.ToCStr().Get());


	GS::UniString itemString5 = GS::UniString("Item Number-5") + "\t" + GS::UniString("Test-5");
	DGListInsertItem(dialId, ListBoxId, DG_LIST_BOTTOM);
	DGListSetItemText(dialId, ListBoxId, DG_LIST_BOTTOM, itemString5.ToCStr().Get());

}



void TestListDialog::PanelResized(const DG::PanelResizeEvent& ev)
{
	short hGrow = ev.GetHorizontalChange();
	short vGrow = ev.GetVerticalChange();
	if (hGrow != 0 || vGrow != 0) {
		BeginMoveResizeItems();
		okButton.MoveAndResize(0, vGrow, hGrow, 0);
		EndMoveResizeItems();
	}

}


void	TestListDialog::ButtonClicked(const DG::ButtonClickEvent& ev)
{
	if (ev.GetSource() == &okButton) {
		PostCloseRequest(Accept);
	}
}

 

6 REPLIES 6
Jahidur
Participant
Can anyone find any idea?
Viktor Kovacs
Graphisoft
Graphisoft
It is possible to insert controls in the selected line. Look for the SetOnTabItem function of the DG::ListBox. You can see example usage in the Navigator_Test Add-On.
Jahidur
Participant
Thanks for your suggestion.
Jahidur
Participant
Viktor wrote:
It is possible to insert controls in the selected line. Look for the SetOnTabItem function of the DG::ListBox. You can see example usage in the Navigator_Test Add-On.

Sir, i tried this method but still did not get solution. When i use this "SetOnTabItem" function it did not add the new item in the list box. i shared my code and the screenshot of the created window. Can you please help me to find the problem of this task.

For this I have edited the GRC file like this:

//--------------------------------------------------
// GRC File
//--------------------------------------------------
'GDLG'  32597  Modal | grow         0    0  510  270  "Test Example Dialog" {
/* [  1] */ Button				    0    0  70   24	   LargePlain  "OK"
/* [  2] */ SingleSelList		    0    0  510  230	LargePlain  PartialItems  23 HasHeader 25
/* [  3] */ TextEdit		        0    0  70  18	LargePlain  40
}

'DLGH'  32597  DLG_32597_Test_Example_Dialog {
1	""							Button_0
2	""							SingleSelList_0
3	""							TExt_0
}

 

 

And in the TestDialog.cpp file at first I have crated tab inside the ListBox and after that tried to add the “TextEdit” control using the “SetOnTab()” function. But the item is not appending inside the Tab in the listbox.
TestDialog.cpp file

//----------------------------------------------------
// TestDialog.cpp
//----------------------------------------------------
TestDialog::TestDialog() :
	DG::ModalDialog(ACAPI_GetOwnResModule(), 32597, ACAPI_GetOwnResModule()),
	okButton(GetReference(), OKButtonId),
	ListBox(GetReference(), ListBoxId),
	EditBox(GetReference(), checkItemId),
	tempBtn(GetReference(), OKButtonId)
{
	
	Attach(*this);
	AttachToAllItems(*this);
	TestInitListBox(32597);
}


void TestDialog::TestInitListBox(short dialId)
{
	//SetTabData(dialId, ListBoxId);
	ListBox.SetHeaderSynchronState(false);
	ListBox.SetHeaderItemCount(2);

	//setting the text of the tab item
	ListBox.SetHeaderItemText(1, "Name");
	ListBox.SetHeaderItemText(2, "Template");

	//setting the header size of the tab
	ListBox.SetHeaderItemSize(1, 150);
	ListBox.SetHeaderItemSize(2, 150);

	ListBox.SetHeaderItemSizeableFlag(1, true);
	ListBox.SetHeaderItemSizeableFlag(2, true);

	ListBox.SetHeaderItemStyle(1, DG::ListBox::DefaultJust, DG::ListBox::EndTruncate);
	ListBox.SetHeaderItemStyle(2, DG::ListBox::DefaultJust, DG::ListBox::EndTruncate);

	ListBox.SetTabFieldCount(2);

	//setting properties of the tab
	short pos = 0;
	ListBox.SetTabFieldProperties(1, pos, pos+ 150, DG::ListBox::Left, DG::ListBox::NoTruncate, false);
	pos += 150;
	ListBox.SetTabFieldProperties(2, pos, pos + 150, DG::ListBox::Left, DG::ListBox::NoTruncate, false);

	ListBox.AppendItem();
	ListBox.SetTabItemText(1, 1, "Ground Floor");
	ListBox.SetOnTabItem(2, *(this->GetItem(checkItemId)));
}

 

 

The “EditBox” is always appending to the (0,0) position not inside the Tab.

I also attached the created window screenshot of this code.

Viktor Kovacs
Graphisoft
Graphisoft

Please check the DG_Test example Add-On for a working solution, but basically you have to follow these steps:

1. Define the control you would like to add in the GRC.
2. Initialize it in the dialog constructor.
3. Call myControl.Hide () because you don't want to see it normally.
4. Listbox tab items appear only when there is a selected row in the listbox. To catch selection event, implement the ListBoxSelectionChanged event handler.

In the selection handler do something like this:

 

void MyDialog::ListBoxSelectionChanged (const DG::ListBoxSelectionEvent& ev)
{
    if (ev.GetSource () == &myListBox) {
        short listItemIndex = myListBox.GetSelectedItem ();
        // Check if there is a selection
        if (listItemIndex <= myListBox.GetItemCount () && listItemIndex > 0) {
            // show on tab item
            myListBox.SetOnTabItem (myTabIndex, myControl);
        }
    }
}

Hi, every control put on a listbox row as ontab item must precede the listbox control in the  resource. This is because the drawing order of the controls. In your resource the TextEdit control is listed after the Listbox, therefore the control will be covered by the list and will not be visible.
Please change the order of the SingleSelList and the TextEdit controls to fix this problem.