3 weeks ago
I need to get the specific code that does that
2 weeks ago - last edited 2 weeks ago by Laszlo Nagy
Hi, I won't explain how to do this in Layout (SDK 25) , but here's the code that draws an image in a template, Master Layout (SDK 26). Where you place DO_CreatePicture, you can add lines, text, etc.
void QuantitiesDialog::Create_MasterLayout_Frame_A3(const char* masterLayoutName) {
// Step 1: Retrieve the list of master layout templates
GS::Array<API_DatabaseUnId> masterLayouts;
GSErrCode err = ACAPI_Database(APIDb_GetMasterLayoutDatabasesID, nullptr, &masterLayouts);
if (err != NoError) {
WriteReport("Error while retrieving master layout templates: %d\n", err);
return;
}
// Step 2: Find the template with the specified name
API_DatabaseUnId targetMasterLayoutUnId = {};
for (const auto& dbUnId : masterLayouts) {
API_DatabaseInfo dbInfo = {};
dbInfo.databaseUnId = dbUnId;
err = ACAPI_Database(APIDb_GetDatabaseInfoID, &dbInfo);
if (err == NoError) {
GS::UniString dbName(reinterpret_cast<const GS::uchar_t*>(dbInfo.name));
if (dbName == masterLayoutName) {
targetMasterLayoutUnId = dbUnId;
break;
}
}
else {
WriteReport("Error while retrieving template info: %d\n", err);
}
}
// Step 3: Check if the template was found
if (targetMasterLayoutUnId.elemSetId == APINULLGuid) {
WriteReport("Master layout template '%s' not found.\n", masterLayoutName);
return;
}
// Step 4: Set the context to the selected master layout template
API_DatabaseInfo dbInfo = {};
dbInfo.typeID = APIWind_MasterLayoutID;
dbInfo.databaseUnId = targetMasterLayoutUnId;
err = ACAPI_Database(APIDb_ChangeCurrentDatabaseID, &dbInfo);
if (err != NoError) {
WriteReport("Error while changing database to the master layout template: %d\n", err);
return;
}
err = ACAPI_CallUndoableCommand("Rysowanie linii na szablonie arkusza", [&]() -> GSErrCode {
// Additional elements (image and text)
Do_CreatePicture("Logo.png", 0.365, 0.270, 0.001);
if (err != NoError) {
WriteReport("Error during operations in a context enabling undo: %d\n", err);
}
// Step 6: Refresh the view
ACAPI_Automate(APIDo_RedrawID, nullptr, nullptr);
}
void QuantitiesDialog::Do_CreatePicture(GS::UniString picture_name, double my_X, double my_Y, double Scale_Factor) {
// Initialize API_Element and API_ElementMemo
API_Element element = {};
API_ElementMemo memo = {};
USize nBytes;
API_Coord c = {};
USize rwnum = 0;
Int32 hSize, vSize, hRes, vRes, pixelBitNum;
GSErrCode err;
// Step 1: Construct the full path to the picture file
GS::UniString pictureFile = "Resources\\" + picture_name;
GS::UniString fullPath = Set_myAddOnPath(pictureFile);
IO::Location location(fullPath);
// Step 2: Retrieve image file information (dimensions and resolution)
err = GX::ImageBase::GetFileInfo(location, &hSize, &vSize, &hRes, &vRes, &pixelBitNum);
if (err != NoError) {
ErrorBeep("GX::ImageBase::GetFileInfo", err);
return;
}
// Step 3: Calculate dimensions in millimeters based on resolution and scale factor
double width_mm = (hSize / static_cast<double>(hRes)) * 25.4 * Scale_Factor;
double height_mm = (vSize / static_cast<double>(vRes)) * 25.4 * Scale_Factor;
// Step 4: Configure the picture element
element.header.type = API_PictureID;
element.picture.usePixelSize = false; // Set to true to use pixel dimensions instead of mm
element.picture.mirrored = false;
element.picture.destBox.xMin = my_X;
element.picture.destBox.yMin = my_Y;
element.picture.destBox.xMax = my_X + width_mm; // Add width in mm
element.picture.destBox.yMax = my_Y + height_mm; // Add height in mm
element.picture.rotAngle = 0.0;
element.picture.anchorPoint = APIAnc_LB;
element.picture.storageFormat = APIPictForm_PNG;
element.picture.transparent = false;
GS::ucscpy(element.picture.pictName, L("First try"));
// Step 5: Open the image file and read its data into a memory handle
IO::File file(location);
file.Open(IO::File::ReadMode);
if (file.GetDataLength(&nBytes) == NoError) {
memo.pictHdl = BMAllocateHandle(nBytes, ALLOCATE_CLEAR, 0);
if (memo.pictHdl != nullptr) {
DBPrintf("Tiff file size: %d", nBytes);
file.ReadBin(*memo.pictHdl, nBytes, &rwnum);
if (rwnum != nBytes)
err = ErrIO;
}
} else {
err = ErrIO;
}
file.Close();
// Step 6: Create the picture element in the Archicad environment
if (err == NoError) {
err = ACAPI_Element_Create(&element, &memo);
if (err != NoError) {
WriteReport("ACAPI_Element_Create (picture)", err);
}
}
// Step 7: Dispose of the memory handle to free resources
if (memo.pictHdl != nullptr) {
ACAPI_DisposeElemMemoHdls(&memo);
}
}
2 weeks ago - last edited 2 weeks ago
And here is the code (sdk 26) to insert drawing elements (like picture) into Layout. It use void QuantitiesDialog::Do_CreatePicture form above. Be careful about the coordinates of the inserted elements, because before You select the values, you will often have them outside the layout area. That's why I added "zoom" in the code. I hope that based on this code you will adopt it to version 25
void QuantitiesDialog::Show_Layout(const char* LayoutName) {
API_DatabaseUnId targetLayoutUnId = {};
API_DatabaseInfo dbInfo = {};
WriteReport("Starting Show_Layout for layout '%s'.\n", LayoutName);
// Retrieve the list of layouts
GS::Array<API_DatabaseUnId> layouts;
GSErrCode err = ACAPI_Database(APIDb_GetLayoutDatabasesID, nullptr, &layouts);
if (err != NoError) {
WriteReport("Error retrieving layout list. Error code: %d\n", err);
return;
}
// Search for the specified layout
bool layoutFound = false;
for (const auto& dbUnId : layouts) {
dbInfo.databaseUnId = dbUnId;
if (ACAPI_Database(APIDb_GetDatabaseInfoID, &dbInfo) == NoError) {
GS::UniString dbName(reinterpret_cast<const GS::uchar_t*>(dbInfo.name));
if (dbName.ToCStr() != nullptr && strcmp(dbName.ToCStr(), LayoutName) == 0) {
targetLayoutUnId = dbUnId;
layoutFound = true;
WriteReport("Layout '%s' found.\n", LayoutName);
break;
}
}
}
if (!layoutFound) {
WriteReport("Layout '%s' not found.\n", LayoutName);
return;
}
// Switch to the specified layout
API_WindowInfo windInfo = {};
windInfo.typeID = APIWind_LayoutID; // Window type: Layout
windInfo.databaseUnId = targetLayoutUnId;
err = ACAPI_Automate(APIDo_ChangeWindowID, &windInfo);
if (err == NoError) {
// Draw objects on the layout
err = ACAPI_CallUndoableCommand("Drawing on layout", [&]() -> GSErrCode {
// Insert here any object which need ACAPI_CallUndoableCommand
// add
Do_CreatePicture("Logo.png", 0.1100, 0.200, 0.001); // Insert a picture
// add
return NoError;
});
if (err != NoError) {
WriteReport("Error during undoable command operation: %d\n", err);
}
// Fit the view to the layout
GSErrCode zoomErr = ACAPI_Automate(APIDo_ZoomID);
if (zoomErr == NoError) {
WriteReport("View fitted to layout '%s'.\n", LayoutName);
}
else {
WriteReport("Error fitting view to layout '%s'. Error code: %d\n", LayoutName, zoomErr);
}
}
else {
WriteReport("Error switching to layout '%s'. Error code: %d\n", LayoutName, err);
}
}