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

Rolldown modal dialog resizing

Leonardo Lopes
Contributor

I am implementing a rolldown modal dialog, really similar to the scheme settings rolldown dialog (see attached image). I already looked up the SDK example BasicElementIconsRollDownDialog (DG_Test), but i am having a really hard time handling the resize of the items inside the rolldown panels. Do i have to move/resize all the items (from the tab pages) inside the PanelResized event of the dialog, or inside the PanelResized event of each individual tab page? If neither of these are the case, how can i accomplish the same resizing effects as the scheme settings?


Rolldown dialog.png
1 ACCEPTED SOLUTION

Accepted Solutions
Solution
Oleg
Expert

Have you except AttachToAllItems(*this) in your constructor and Attach(*this) also ?

View solution in original post

8 REPLIES 8
Oleg
Expert

Inside the PanelResized event of each individual tab page.

Every RollDown panel may have individual GrowType.
So it may have different "Change" value.

I use like this:

void TabDocReport::PanelResized (const DG::PanelResizeEvent& ev)
{
	short h = ev.GetHorizontalChange();
	short v = ev.GetVerticalChange();

	mi_path_set.Move( h, 0 );
	mi_path.Resize( h, 0 );
	mi_list.Resize( h, v );
	m_table.ResizeTableColumns();
}

 

Leonardo Lopes
Contributor

Thanks for the reply Oleg, but I already tried doing this way. When I debug my code the event never gets fired. My TabPage class and the event are defined as follows:

 

TabPage Constructor

SubsetRollDownTabPage::SubsetRollDownTabPage(const DG::TabControl& tabControl) : 
	DG::TabPage(tabControl, 1, ACAPI_GetOwnResModule(), SUBSET_PAGE_ID, ACAPI_GetOwnResModule()),
	newSubsetRB(GetReference(), NewRadioButtonId),
	existingSubsetRB(GetReference(), ExistingRadioButtonId),
	subSetText(GetReference(), SubSetTextId),
	subsetTree(GetReference(), SubSetTreeId)
{
	// Attach items
	AttachToAllItems(*this);
	
	// Select default radiobutton
	newSubsetRB.Select();

	// Build and expand tree view
	BuildTreeview(API_LayoutMap, API_SubSetNavItem, &SubSetTreeNodes, &subsetTree);	
	subsetTree.ExpandItem(1);
}

PanelResized Event

void SubsetRollDownTabPage::PanelResized(const DG::PanelResizeEvent& ev)
{
	short hGrow = ev.GetHorizontalChange();
	short vGrow = ev.GetVerticalChange();

	subsetTree.Resize(hGrow, vGrow);
}

 

The dialog has a roll panel on the left side, 2 roll panels on the right side and a bottom panel with the "OK" and "Cancel" buttons. All of the roll panels have GrowType set to HVGrow. The code above refers to one of the panels on the right side.

 

I got confused where the event should be implemented, because unlike the dialog class that has methods like BeginMoveResizeItems( ) and EndMoveResizeItems( ), the TabPage class does not have this kind of methods.

Oleg
Expert

The PanelResized is a virtual method of the PanelObserver, not TabPage itself.
So you need some class inherits from PanelObserver, implements PanelResized and Attach it to Panel. 

Most simple way is to inherit your TabPage class from the PanelObserver and Attach in your tabpage's constructor.

 

Like this:

class SubsetRollDownTabPage : public DG::TabPage, private DG::PanelObserver
...

SubsetRollDownTabPage::SubsetRollDownTabPage(...)
...
{
...
	Attach(*this);
}


 

Oleg
Expert

BTW about AttachToAllItems(*this). 
If you want got events from items you will need inherits from different observers as well.
And override required virtual functions of some observer.


Like this:

class TabDocReport
	: public TabDocBase
	, private DG::PanelObserver
	, private DG::ButtonItemObserver
	, private DG::RadioItemObserver
	, private DG::ListBoxObserver
...
private:
	virtual void PanelResized (const DG::PanelResizeEvent& ev);
	virtual void PanelResizeExited (const DG::PanelResizeEvent& ev);
	virtual void ButtonClicked (const DG::ButtonClickEvent& ev);
	virtual void RadioItemChanged (const DG::RadioItemChangeEvent& ev);
	virtual void ListBoxSelectionChanged (const DG::ListBoxSelectionEvent& ev);
	virtual void ListBoxClicked (const DG::ListBoxClickEvent& ev);

I also already have this inheritance setup in my .h file.

 

Snippet of SubsetRollDownTabPage Class

class SubsetRollDownTabPage : public DG::TabPage, 
			                  public DG::RadioItemObserver,
			                  public DG::PanelObserver,
			                  public DG::CompoundItemObserver
{
private:
    ...
    virtual void PanelResized(const DG::PanelResizeEvent& ev) override;
    ...
};

 

An instance of this class is being created inside the constructor of the dialog:

MainDialog::MainDialog(DG::NativePoint* position) : UD::RollDownModalDialog(dialogGUID, position)													
{
	// Dialog properties
	SetGrowType(HVGrow);
	...

	UD::IRollDownSurface* rollDownSurface = GetRollDownSurface();
	bool valid = rollDownSurface != nullptr && UD::RollDownModalDialog::IsValid();

	UD::IRollDownPanelSet* rollDownPanelSet = nullptr;

	try {
		if (valid) {
			rollDownPanelSet = rollDownSurface->CreateRollDownPanelSet();
			if (rollDownPanelSet == nullptr)
				valid = false;
		}

		// Subset roll panel ==========
		if (valid) {
			UD::IRollPanel* subsetRollDownPanel = rollDownPanelSet->CreateRollDownPanel();

			subsetRollDownPanel->SetGrowType(UD::IRollPanel::HVGrow);
			subsetRollDownPanel->SetTitle("LAYOUT BOOK");
			subsetRollDownPanel->SetIcon(DG::Icon(ACAPI_GetOwnResModule(), BOOK_ICON_ID));

			if (subsetRollDownPanel == nullptr)
				valid = false;
			else
				new SubsetRollDownTabPage(subsetRollDownPanel->GetTabControl());
		}
        ...
    }
    catch (...) {
	    ...
    }
}

 

The closest i've got from achieving the resize effect i want is when i defined the PanelResized event inside the dialog class and created a pointer to all of the rollpanels (as properties of the dialog class) and then, inside the PanelResized event, called public methods of the TagPages to handle their resizing individually. This didn't work out, because the roll panels didn't grow proportionally. Every time i resized the dialog to it's original size, the roll panels were not being resized to their original size as well, they were a little bit bigger.

Thanks for the advice, i ended up learning this the hard way while debugging my code hahaha.

Solution
Oleg
Expert

Have you except AttachToAllItems(*this) in your constructor and Attach(*this) also ?

This worked perfectly. I thought AttachToAllItems(*this) already handled all the panel events like resizing, opening, etc.

Thanks a lot for the help!

Didn't find the answer?

Check other topics in this Forum

Back to Forum

Read the latest accepted solutions!

Accepted Solutions

Start a new conversation!