selectionBridge works
This commit is contained in:
@@ -114,6 +114,7 @@
|
||||
<ClCompile Include="Connector\Interface\Browser\Bridge\Selection\Arg\SelectionInfo.cpp" />
|
||||
<ClCompile Include="Connector\Interface\Browser\Bridge\Selection\GetSelection.cpp" />
|
||||
<ClCompile Include="Connector\Interface\Browser\Bridge\Selection\SelectionBridge.cpp" />
|
||||
<ClCompile Include="Connector\Interface\Browser\Bridge\Selection\SelectionChangeHandler.cpp" />
|
||||
<ClCompile Include="Connector\Interface\Browser\Bridge\Send\Arg\ConversionResult.cpp" />
|
||||
<ClCompile Include="Connector\Interface\Browser\Bridge\Send\Arg\SendError.cpp" />
|
||||
<ClCompile Include="Connector\Interface\Browser\Bridge\Send\Arg\SendObject.cpp" />
|
||||
@@ -169,6 +170,7 @@
|
||||
<ClInclude Include="Connector\Interface\Browser\Bridge\Selection\Arg\SelectionInfo.h" />
|
||||
<ClInclude Include="Connector\Interface\Browser\Bridge\Selection\GetSelection.h" />
|
||||
<ClInclude Include="Connector\Interface\Browser\Bridge\Selection\SelectionBridge.h" />
|
||||
<ClInclude Include="Connector\Interface\Browser\Bridge\Selection\SelectionChangeHandler.h" />
|
||||
<ClInclude Include="Connector\Interface\Browser\Bridge\Send\Arg\ConversionResult.h" />
|
||||
<ClInclude Include="Connector\Interface\Browser\Bridge\Send\Arg\SendError.h" />
|
||||
<ClInclude Include="Connector\Interface\Browser\Bridge\Send\Arg\SendObject.h" />
|
||||
|
||||
@@ -243,6 +243,9 @@
|
||||
<ClCompile Include="Connector\Interface\Browser\Bridge\Selection\Arg\SelectionInfo.cpp">
|
||||
<Filter>Connector\Interface\Browser\Bridge\Selection\Arg</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Connector\Interface\Browser\Bridge\Selection\SelectionChangeHandler.cpp">
|
||||
<Filter>Connector\Interface\Browser\Bridge\Selection</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Connector\ConnectorResource.h">
|
||||
@@ -411,5 +414,8 @@
|
||||
<ClInclude Include="Connector\Interface\Browser\Bridge\Selection\Arg\SelectionInfo.h">
|
||||
<Filter>Connector\Interface\Browser\Bridge\Selection\Arg</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Connector\Interface\Browser\Bridge\Selection\SelectionChangeHandler.h">
|
||||
<Filter>Connector\Interface\Browser\Bridge\Selection</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "Active/File/Directory.h"
|
||||
#include "ConnectorResource.h"
|
||||
#include "Connector/Connector.h"
|
||||
#include "Connector/Interface/Browser/Bridge/Selection/SelectionChangeHandler.h"
|
||||
#include "Connector/Database/ModelCardDatabase.h"
|
||||
#include "Connector/Interface/ConnectorMenu.h"
|
||||
#include "Connector/Interface/ConnectorPalette.h"
|
||||
@@ -12,6 +13,7 @@ using namespace active::file;
|
||||
using namespace active::environment;
|
||||
using namespace connector;
|
||||
using namespace connector::database;
|
||||
using namespace connector::interfac::browser::bridge;
|
||||
using namespace speckle::database;
|
||||
using namespace speckle::environment;
|
||||
using namespace speckle::utility;
|
||||
|
||||
+36
-1
@@ -2,6 +2,14 @@
|
||||
|
||||
#include "Active/Serialise/Item/Wrapper/ValueWrap.h"
|
||||
#include "Active/Serialise/Package/Wrapper/PackageWrap.h"
|
||||
#include "Active/Serialise/Package/Wrapper/ContainerWrap.h"
|
||||
|
||||
#include "Connector/Connector.h"
|
||||
|
||||
#include "Speckle/Database/BIMElementDatabase.h"
|
||||
#include "Speckle/Environment/Project.h"
|
||||
#include "Speckle/Record/Element/Element.h"
|
||||
using namespace speckle::record::element;
|
||||
|
||||
#include <array>
|
||||
|
||||
@@ -12,16 +20,40 @@ namespace {
|
||||
|
||||
///Serialisation fields
|
||||
enum FieldIndex {
|
||||
selectedObjectIdsID,
|
||||
summaryID,
|
||||
};
|
||||
|
||||
///Serialisation field IDs
|
||||
static std::array fieldID = {
|
||||
Identity{"selectedObjectIds"},
|
||||
Identity{"summary"},
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
SelectionInfo::SelectionInfo() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
void SelectionInfo::initialize() {
|
||||
auto project = connector()->getActiveProject().lock();
|
||||
if (!project) {
|
||||
// TODO: handle
|
||||
}
|
||||
|
||||
auto elementDatabase = project->getElementDatabase();
|
||||
auto selected = elementDatabase->getSelection();
|
||||
|
||||
active::utility::String summary(selected.size());
|
||||
summary += " objects selected.";
|
||||
m_summary = summary;
|
||||
|
||||
for (const auto& link : selected) {
|
||||
m_selectedElementIds.push_back(link);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
Fill an inventory with the package items
|
||||
|
||||
@@ -33,6 +65,7 @@ bool SelectionInfo::fillInventory(Inventory& inventory) const {
|
||||
using enum Entry::Type;
|
||||
inventory.merge(Inventory{
|
||||
{
|
||||
{ fieldID[selectedObjectIdsID], selectedObjectIdsID, element },
|
||||
{ fieldID[summaryID], summaryID, element },
|
||||
},
|
||||
}.withType(&typeid(SelectionInfo)));
|
||||
@@ -52,8 +85,10 @@ Cargo::Unique SelectionInfo::getCargo(const Inventory::Item& item) const {
|
||||
return nullptr;
|
||||
using namespace active::serialise;
|
||||
switch (item.index) {
|
||||
case selectedObjectIdsID:
|
||||
return std::make_unique<ContainerWrap<std::vector<active::utility::Guid>>>(m_selectedElementIds);
|
||||
case summaryID:
|
||||
return std::make_unique<ValueWrap<active::utility::String>>(summary);
|
||||
return std::make_unique<ValueWrap<active::utility::String>>(m_summary);
|
||||
default:
|
||||
return nullptr; //Requested an unknown index
|
||||
}
|
||||
|
||||
@@ -21,10 +21,12 @@ namespace connector::interfac::browser::bridge {
|
||||
/*!
|
||||
Default constructor
|
||||
*/
|
||||
SelectionInfo() = default;
|
||||
SelectionInfo();
|
||||
|
||||
active::utility::String summary = "Nothing is selected";
|
||||
std::vector<active::utility::Guid> selectedElementIds;
|
||||
active::utility::String m_summary = "No objects selected";
|
||||
std::vector<active::utility::Guid> m_selectedElementIds;
|
||||
|
||||
void initialize();
|
||||
|
||||
// MARK: - Serialisation
|
||||
|
||||
|
||||
@@ -1,30 +1,10 @@
|
||||
#include "Connector/Interface/Browser/Bridge/Selection/GetSelection.h"
|
||||
|
||||
#include "Active/Serialise/CargoHold.h"
|
||||
#include "Active/Serialise/Package/Wrapper/PackageWrap.h"
|
||||
#include "Connector/Interface/Browser/Bridge/Selection/Arg/SelectionInfo.h"
|
||||
|
||||
#include "Connector/Connector.h"
|
||||
#include "Connector/Record/Collection/ProjectCollection.h"
|
||||
|
||||
#include "Speckle/Database/BIMElementDatabase.h"
|
||||
#include "Speckle/Environment/Project.h"
|
||||
#include "Speckle/Record/Element/Element.h"
|
||||
using namespace speckle::record::element;
|
||||
|
||||
#include <array>
|
||||
|
||||
using namespace active::serialise;
|
||||
using namespace connector::interfac::browser::bridge;
|
||||
using namespace speckle::utility;
|
||||
using namespace connector::record;
|
||||
|
||||
namespace {
|
||||
|
||||
///Return type for retrieving the current configuration
|
||||
using WrappedValue = CargoHold<PackageWrap, SelectionInfo>;
|
||||
|
||||
}
|
||||
/*--------------------------------------------------------------------
|
||||
Default constructor
|
||||
--------------------------------------------------------------------*/
|
||||
@@ -39,30 +19,6 @@ GetSelection::GetSelection() : BridgeMethod{"GetSelection", [&]() {
|
||||
modelCardID: The ID of the model to send
|
||||
--------------------------------------------------------------------*/
|
||||
std::unique_ptr<Cargo> GetSelection::run() const {
|
||||
|
||||
auto selectionInfo = std::make_unique<SelectionInfo>();
|
||||
|
||||
auto project = connector()->getActiveProject().lock();
|
||||
if (!project) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
//Build a collection from the selected elements
|
||||
auto collection = std::make_unique<ProjectCollection>(project);
|
||||
auto elementDatabase = project->getElementDatabase();
|
||||
auto selected = elementDatabase->getSelection();
|
||||
|
||||
active::utility::String summary(selected.size());
|
||||
summary += " objects selected.";
|
||||
|
||||
selectionInfo->summary = summary;
|
||||
|
||||
for (const auto& link : selected) {
|
||||
if (auto element = elementDatabase->getElement(link); element) {
|
||||
collection->addElement(*element);
|
||||
selectionInfo->selectedElementIds.push_back(element->getBIMID());
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_unique<WrappedValue>(std::move(selectionInfo));
|
||||
return std::make_unique<CargoHold<PackageWrap, SelectionInfo>>(std::move(selectionInfo));
|
||||
} //GetSelection::run
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "Connector/Interface/Browser/Bridge/Selection/SelectionBridge.h"
|
||||
|
||||
#include "Connector/Interface/Browser/Bridge/Selection/GetSelection.h"
|
||||
#include "Active/Serialise/CargoHold.h"
|
||||
#include "Connector/Interface/Browser/Bridge/Selection/Arg/SelectionInfo.h"
|
||||
|
||||
using namespace active::serialise;
|
||||
using namespace connector::interfac::browser::bridge;
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
@@ -11,3 +13,10 @@ SelectionBridge::SelectionBridge() : BrowserBridge{"selectionBinding"} {
|
||||
//Add bridge methods
|
||||
addMethod<GetSelection>();
|
||||
} //SelectionBridge::SelectionBridge
|
||||
|
||||
bool SelectionBridge::handle(const speckle::event::SelectionEvent& event) {
|
||||
auto selectionInfo = std::make_unique<SelectionInfo>();
|
||||
auto wrapped = std::make_unique<CargoHold<PackageWrap, SelectionInfo>>(std::move(selectionInfo));
|
||||
sendEvent("setSelection", std::move(wrapped));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2,13 +2,15 @@
|
||||
#define CONNECTOR_INTERFACE_BRIDGE_SELECTION_BRIDGE
|
||||
|
||||
#include "Speckle/Interface/Browser/Bridge/BrowserBridge.h"
|
||||
#include "Speckle/Event/Subscriber/SelectionSubscriber.h"
|
||||
#include "Speckle/Event/Type/SelectionEvent.h"
|
||||
|
||||
namespace connector::interfac::browser::bridge {
|
||||
|
||||
/*!
|
||||
A browser bridge to support sending model data to a Speckle server
|
||||
*/
|
||||
class SelectionBridge : public speckle::interfac::browser::bridge::BrowserBridge {
|
||||
class SelectionBridge : public speckle::interfac::browser::bridge::BrowserBridge, public speckle::event::SelectionSubscriber {
|
||||
public:
|
||||
|
||||
// MARK: - Types
|
||||
@@ -22,6 +24,10 @@ namespace connector::interfac::browser::bridge {
|
||||
Default constructor
|
||||
*/
|
||||
SelectionBridge();
|
||||
|
||||
protected:
|
||||
|
||||
bool handle(const speckle::event::SelectionEvent& event) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#include "Connector/Interface/Browser/Bridge/Selection/SelectionChangeHandler.h"
|
||||
|
||||
#include "Active/Event/Event.h"
|
||||
#include "Connector/ConnectorResource.h"
|
||||
#include "Connector/Event/ConnectorEventID.h"
|
||||
#include "Speckle/Environment/Addon.h"
|
||||
|
||||
using namespace connector::interfac::browser::bridge;
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
Default constructor
|
||||
--------------------------------------------------------------------*/
|
||||
SelectionChangeHandler::SelectionChangeHandler() {
|
||||
int i = 0;
|
||||
} //SelectionChangeHandler::SelectionChangeHandler
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
Handle the menu selection
|
||||
|
||||
event: The menu event
|
||||
|
||||
return: True if the event should be closed
|
||||
--------------------------------------------------------------------*/
|
||||
bool SelectionChangeHandler::handle(const speckle::event::SelectionEvent& event) {
|
||||
int i = 0;
|
||||
return true;
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#ifndef CONNECTOR_INTERFACE_BRIDGE_SELECTION_CHANGE_HANDLER
|
||||
#define CONNECTOR_INTERFACE_BRIDGE_SELECTION_CHANGE_HANDLER
|
||||
|
||||
#include "Speckle/Event/Subscriber/SelectionSubscriber.h"
|
||||
#include "Speckle/Event/Type/SelectionEvent.h"
|
||||
|
||||
namespace connector::interfac::browser::bridge {
|
||||
|
||||
/*!
|
||||
Configuration settings class
|
||||
*/
|
||||
class SelectionChangeHandler : public speckle::event::SelectionSubscriber {
|
||||
public:
|
||||
// MARK: - Constructors
|
||||
|
||||
/*!
|
||||
Default constructor
|
||||
*/
|
||||
SelectionChangeHandler();
|
||||
|
||||
|
||||
protected:
|
||||
bool handle(const speckle::event::SelectionEvent& event) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //CONNECTOR_INTERFACE_BRIDGE_SELECTION_CHANGE_HANDLER
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "Active/Utility/String.h"
|
||||
#include "Active/Serialise/JSON/JSONTransport.h"
|
||||
#include "Active/Utility/BufferOut.h"
|
||||
#include "Connector/Connector.h"
|
||||
#include "Connector/ConnectorResource.h"
|
||||
#include "Connector/Event/ConnectorEventID.h"
|
||||
#include "Connector/Interface/Browser/Bridge/Account/AccountBridge.h"
|
||||
@@ -77,9 +78,6 @@ namespace {
|
||||
virtual void PanelResized(const DG::PanelResizeEvent& ev) override;
|
||||
virtual void PanelCloseRequested(const DG::PanelCloseRequestEvent& ev, bool* accepted) override;
|
||||
|
||||
static GS::Array<BrowserPalette::ElementInfo> GetSelectedElements();
|
||||
static void ModifySelection(const GS::UniString& elemGuidStr, SelectionModification modification);
|
||||
|
||||
static GSErrCode __ACENV_CALL PaletteControlCallBack(Int32 paletteId, API_PaletteMessageID messageID, GS::IntPtr param);
|
||||
|
||||
static GS::Ref<BrowserPalette> instance;
|
||||
@@ -171,7 +169,12 @@ BrowserPalette::BrowserPalette() :
|
||||
install<BaseBridge>();
|
||||
install<ConfigBridge>();
|
||||
install<SendBridge>();
|
||||
install<SelectionBridge>();
|
||||
if (auto ref = install<SelectionBridge>(); ref) {
|
||||
if (auto selectionBridgeRef = std::dynamic_pointer_cast<SelectionBridge>(ref); selectionBridgeRef) {
|
||||
connector::connector()->addWeak(selectionBridgeRef);
|
||||
selectionBridgeRef->start();
|
||||
}
|
||||
}
|
||||
install<TestBridge>();
|
||||
InitBrowserControl();
|
||||
}
|
||||
@@ -245,31 +248,6 @@ void BrowserPalette::PanelCloseRequested(const DG::PanelCloseRequestEvent&, bool
|
||||
*accepted = true;
|
||||
}
|
||||
|
||||
GS::Array<BrowserPalette::ElementInfo> BrowserPalette::GetSelectedElements() {
|
||||
API_SelectionInfo selectionInfo;
|
||||
GS::Array<API_Neig> selNeigs;
|
||||
ACAPI_Selection_Get(&selectionInfo, &selNeigs, false, false);
|
||||
BMKillHandle((GSHandle*)&selectionInfo.marquee.coords);
|
||||
|
||||
GS::Array<BrowserPalette::ElementInfo> selectedElements;
|
||||
for(const API_Neig& neig : selNeigs) {
|
||||
API_Elem_Head elemHead = {};
|
||||
elemHead.guid = neig.guid;
|
||||
ACAPI_Element_GetHeader(&elemHead);
|
||||
|
||||
ElementInfo elemInfo;
|
||||
elemInfo.guidStr = APIGuidToString(elemHead.guid);
|
||||
ACAPI_Element_GetElemTypeName(elemHead.type, elemInfo.typeName);
|
||||
ACAPI_Element_GetElementInfoString(&elemHead.guid, &elemInfo.elemID);
|
||||
selectedElements.Push(elemInfo);
|
||||
}
|
||||
return selectedElements;
|
||||
}
|
||||
|
||||
void BrowserPalette::ModifySelection(const GS::UniString& elemGuidStr, BrowserPalette::SelectionModification modification) {
|
||||
ACAPI_Selection_Select({ API_Neig(APIGuidFromString(elemGuidStr.ToCStr().Get())) }, modification == AddToSelection);
|
||||
}
|
||||
|
||||
GSErrCode __ACENV_CALL BrowserPalette::PaletteControlCallBack(Int32, API_PaletteMessageID messageID, GS::IntPtr param) {
|
||||
switch(messageID) {
|
||||
case APIPalMsg_OpenPalette:
|
||||
|
||||
@@ -69,12 +69,18 @@ bool SelectionSubscriber::receive(const Event& event) {
|
||||
return: True if the participant is able to continue
|
||||
--------------------------------------------------------------------*/
|
||||
bool SelectionSubscriber::start() {
|
||||
if (m_isStarted)
|
||||
return true;
|
||||
m_isStarted = true;
|
||||
#ifdef ARCHICAD
|
||||
return (ACAPI_Notification_CatchSelectionChange(selectionCallback) == NoError);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
} //SelectionSubscriber::start
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
Stop participation (release resources etc)
|
||||
--------------------------------------------------------------------*/
|
||||
void SelectionSubscriber::stop() {
|
||||
#ifdef ARCHICAD
|
||||
ACAPI_Notification_CatchSelectionChange(nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace speckle::event {
|
||||
Get the event subscription list
|
||||
@return The subscription list (an empty list will put the subscriber into a suspended state)
|
||||
*/
|
||||
virtual Subscription subscription() const override;
|
||||
Subscription subscription() const override;
|
||||
|
||||
// MARK: - Functions (mutating)
|
||||
|
||||
@@ -44,14 +44,21 @@ namespace speckle::event {
|
||||
@param event The incoming event
|
||||
@return True if the event should be closed
|
||||
*/
|
||||
virtual bool receive(const active::event::Event& event) override;
|
||||
|
||||
protected:
|
||||
bool receive(const active::event::Event& event) override;
|
||||
|
||||
/*!
|
||||
Start the participant operation
|
||||
@return True if the participant is able to continue
|
||||
*/
|
||||
virtual bool start() override;
|
||||
|
||||
/*!
|
||||
Stop participation (release resources etc)
|
||||
*/
|
||||
void stop() override;
|
||||
|
||||
protected:
|
||||
|
||||
/*!
|
||||
Handle the menu selection
|
||||
@param event The menu event
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace speckle::event {
|
||||
Constructor
|
||||
@param selected A link to a selected element (nullopt if the selection is empty)
|
||||
*/
|
||||
SelectionEvent(speckle::database::BIMLink::Option selected) : m_selectedLink{selected} {}
|
||||
SelectionEvent(speckle::database::BIMLink::Option selected) : Event{ ID }, m_selectedLink{selected} {}
|
||||
/*!
|
||||
Copy constructor
|
||||
@param source The object to copy
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace speckle::interfac::browser {
|
||||
*/
|
||||
template<class Derived>
|
||||
explicit JSObject(const speckle::utility::String& name, const std::initializer_list<Derived>& items) : base{items}, m_name{name} {}
|
||||
|
||||
virtual ~JSObject() {}
|
||||
// MARK: - Functions (const)
|
||||
|
||||
/*!
|
||||
|
||||
@@ -48,14 +48,14 @@ namespace speckle::interfac::browser {
|
||||
@param object The object to install
|
||||
@return True if the object was successfully installed
|
||||
*/
|
||||
bool install(std::shared_ptr<JSObject<FunctionBinding>> object);
|
||||
std::shared_ptr<JSObject<FunctionBinding>> install(std::shared_ptr<JSObject<FunctionBinding>> object);
|
||||
/*!
|
||||
Install a JS function object
|
||||
@return True if the object was successfully installed
|
||||
@tparam T The type of object to install
|
||||
*/
|
||||
template<typename T> requires std::is_base_of_v<JSObject<FunctionBinding>, T>
|
||||
bool install() { return install(std::make_shared<T>()); }
|
||||
std::shared_ptr<JSObject<FunctionBinding>> install() { return install(std::make_shared<T>()); }
|
||||
|
||||
protected:
|
||||
#ifdef ARCHICAD
|
||||
@@ -101,12 +101,12 @@ namespace speckle::interfac::browser {
|
||||
return: True if the object was successfully installed
|
||||
--------------------------------------------------------------------*/
|
||||
template<typename FunctionBinding>
|
||||
bool JSPortal<FunctionBinding>::install(std::shared_ptr<JSObject<FunctionBinding>> object) {
|
||||
std::shared_ptr<JSObject<FunctionBinding>> JSPortal<FunctionBinding>::install(std::shared_ptr<JSObject<FunctionBinding>> object) {
|
||||
try {
|
||||
#ifdef ARCHICAD
|
||||
auto engine = getJSEngine();
|
||||
if (!engine)
|
||||
return false;
|
||||
return nullptr;
|
||||
//Define the JS object
|
||||
JS::Object* acObject = new JS::Object(object->getName());
|
||||
//Add all the functions supported by this object
|
||||
@@ -125,13 +125,13 @@ namespace speckle::interfac::browser {
|
||||
if (engine->RegisterAsynchJSObject(acObject)) {
|
||||
base::push_back(object);
|
||||
object->setPortal(*this);
|
||||
return true;
|
||||
return object;
|
||||
}
|
||||
#endif
|
||||
} catch(...) {
|
||||
///TODO: Need to discuss the best course of action to notify of a failure
|
||||
}
|
||||
return false;
|
||||
return nullptr;
|
||||
} //JSPortal<FunctionBinding>::install
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user