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.

How to get a list of all the layouts from the selected subset?

Anonymous
Not applicable
The user has selected a subset.
I need to step by step collect data from the properties of the drawings of this subset.
How can I get the selected subset?
How can I get the elements of the selected subset?
Thank.
7 REPLIES 7
Anonymous
Not applicable
Sorry))
Apparently I need to learn an example.
Navigator_Test
Anonymous
Not applicable
Tsepov wrote:
learn an example
It would be nice to have a list of methods in examples with a brief description. It's easy to miss some stuff in examples.
Anonymous
Not applicable
Unfortunately, this is so.
The dialog box in the example is not completely unloaded from memory when close.
Therefore, it is necessary to reboot ARCHICAD for compilation with the debugger.
To avoid this in my work, I work with dialogues through classes of dialog elements.
But they are not documented at all now.
So it is very difficult to work.
Anonymous
Not applicable
I need to get selected elements from Navigator by :

Int32 DGTreeViewGetSelItems (
short dialId,
short item,
Int32* selItems,
Int32 maxCount
);

How I can get Navigator dialogID ?
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
Tsepov wrote:
How I can get Navigator dialogID ?
I think it's a wrong direction. Even if I could tell you the dialogID of the Navigator palette, you still need the itemID of the TreeView and finally you will retrieve only the index of the selected items.
But anyway, if you choose this solution, then maybe you can use DGGetFocus method to find out the ID of the Navigator and the TreeView:
#include "DG.h"

short currDialID;
short currItem;
DGGetFocus (DG_ALL_DIALOGS, &currDialID, &currItem);

Today I wrote a cleaner example code for handling layout book navigator items:
#include "Queue.hpp"

using NavItemChildren = GS::Array<API_NavigatorItem>;
using NavItemParentChildrenPair = GS::Pair<API_NavigatorItem, NavItemChildren>;


static NavItemChildren GetNavItemChildren (const API_NavigatorItem& parentItem)
{
    NavItemChildren childrenItems;
    API_NavigatorItem** items = nullptr;
    GSErrCode err = ACAPI_Navigator (APINavigator_GetNavigatorChildrenItemsID, (void*)&parentItem, &items);
    if (err == NoError) {
        Int32 childCount = BMhGetSize ((GSHandle)items) / Sizeof32 (API_NavigatorItem);
        for (Int32 ii = 0; ii < childCount; ++ii) {
            childrenItems.Push ((*items)[ii]);
        }

        BMhKill ((GSHandle *)&items);
    }

    return childrenItems;
}

static API_Guid GetLayoutBookRootGuid ()
{
    API_NavigatorSet  set = {};
    set.mapId = API_LayoutMap;
    ACAPI_Navigator (APINavigator_GetNavigatorSetID, &set, nullptr);

    return set.rootGuid;
}

static GS::HashTable<API_Guid, NavItemParentChildrenPair> GetLayoutBook ()
{
    GS::HashTable<API_Guid, NavItemParentChildrenPair> result;

    API_NavigatorItem item = {};
    item.guid = GetLayoutBookRootGuid ();
    item.mapId = API_LayoutMap;

    GS::Queue<API_NavigatorItem> queue = { item };
    while (queue.IsEmpty () == false) {
        API_NavigatorItem parentItem = queue.Pop ();
        NavItemChildren childrenItems = GetNavItemChildren (parentItem);

        for (const auto& child : childrenItems) {
            queue.Push (child);
        }

        result.Add (parentItem.guid, NavItemParentChildrenPair (parentItem, childrenItems));
    }

    return result;
}

static GS::Array<API_NavigatorItem> GetLayoutSubsets (const GS::HashTable<API_Guid, NavItemParentChildrenPair>& layoutBook)
{
    GS::Array<API_NavigatorItem> subsets;

    for (const NavItemParentChildrenPair& parentChildrenPair : layoutBook.Values ()) {
        if (parentChildrenPair.first.itemType == API_SubSetNavItem)
            subsets.Push (parentChildrenPair.first);
    }

    return subsets;
}

static const NavItemChildren& GetLayoutsFromSubset (const API_Guid& subsetGuid, const GS::HashTable<API_Guid, NavItemParentChildrenPair>& layoutBook)
{
    return layoutBook[subsetGuid].second;
}

// Usage:

const GS::HashTable<API_Guid, NavItemParentChildrenPair> layoutBook = GetLayoutBook ();

for (const auto& subset : GetLayoutSubsets (layoutBook)) {
    const NavItemChildren& layouts = GetLayoutsFromSubset (subset.guid, layoutBook);
    // ...
}
Note, this code works in ARCHICAD 22.
If you use previous versions, then you have to replace ACAPI_Navigator with ACAPI_Environment and APINavigator_* with APIEnv_*.
There could be other compilation issues also, because of the new C++ standard features, but I think it's better to have here the up-to-date version of the code now.
Anonymous
Not applicable
Thank you so much for the support!
I have already made, on the basis of the old example, the basis of an application for counting sheets in a draft equivalent to A4.
Now I will try to make the transition button from the selected position to the same position in the navigator and back.
To do this, you need to somehow get the ID of the navigator dialog and the ID of the layouts treeview.
Anonymous
Not applicable
And else problem.
I need to get the page orientation for current layout item.
I can't find a way to do it.
---------------------------------------

API_NavigatorItem** items = nullptr;
API_NavigatorItem item;

BNZeroMemory(&item, sizeof(API_NavigatorItem));
item.guid = guid;
item.mapId = mapId;

GSErrCode err = ACAPI_Navigator(APINavigator_GetNavigatorChildrenItemsID, &item, &items);
if (err != NoError || items == nullptr)
return;

Int32 n = BMhGetSize((GSHandle)items) / Sizeof32(API_NavigatorItem);
for (Int32 i = 0; i < n; i++) {
if ((*items).itemType == API_LayoutNavItem)
{
//
API_LayoutInfo layoutInfo;
ULong actualPageIndex = 0;
API_DatabaseUnId databaseUnId = (*items).db.databaseUnId;
err = ACAPI_Environment(APIEnv_GetLayoutSetsID, &layoutInfo, &databaseUnId, actualPageIndex);
if (err == GS::NoError)
{
sizeX = layoutInfo.sizeX;
// And there I need to get page orientation->
// <-
}
}
}