diff --git a/include/openspace/properties/propertyowner.h b/include/openspace/properties/propertyowner.h index 8844726c53..d7134b9c54 100644 --- a/include/openspace/properties/propertyowner.h +++ b/include/openspace/properties/propertyowner.h @@ -303,7 +303,6 @@ protected: /// The description for this PropertyOwner std::string _description; -private: /// The owner of this PropertyOwner PropertyOwner* _owner = nullptr; /// A list of all registered Property's diff --git a/modules/globebrowsing/globebrowsingmodule.cpp b/modules/globebrowsing/globebrowsingmodule.cpp index 081fedebdc..c1d976da57 100644 --- a/modules/globebrowsing/globebrowsingmodule.cpp +++ b/modules/globebrowsing/globebrowsingmodule.cpp @@ -385,6 +385,27 @@ scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const { "any of " + listLayerGroups + ". The third argument is the dictionary" "defining the layer." }, + { + "getLayers", + &globebrowsing::luascriptfunctions::getLayers, + {}, + "string, string", + "Returns the list of layers for the scene graph node specified in the first " + "parameter. The second parameter specifies which layer type should be " + "queried." + }, + { + "moveLayer", + &globebrowsing::luascriptfunctions::moveLayer, + {}, + "string, string, number, number", + "Rearranges the order of a single layer in a scene graph node. The first " + "parameter specifies the scene graph node, the second parameter specifies " + "the name of the layer group, the third parameter is the original position " + "of the layer that should be moved and the last parameter is the new " + "position. The new position may be -1 to place the layer at the top or any " + "large number bigger than the number of layers to place it at the bottom." + }, { "goToChunk", &globebrowsing::luascriptfunctions::goToChunk, diff --git a/modules/globebrowsing/globebrowsingmodule_lua.inl b/modules/globebrowsing/globebrowsingmodule_lua.inl index 0c6479b211..3c5d4677ff 100644 --- a/modules/globebrowsing/globebrowsingmodule_lua.inl +++ b/modules/globebrowsing/globebrowsingmodule_lua.inl @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -127,6 +128,77 @@ int deleteLayer(lua_State* L) { return 0; } +int getLayers(lua_State* L) { + ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::getLayers"); + + const std::string& globeIdentifier = ghoul::lua::value(L, 1); + const std::string& layer = ghoul::lua::value(L, 2); + lua_pop(L, 2); + + SceneGraphNode* n = sceneGraphNode(globeIdentifier); + if (!n) { + return ghoul::lua::luaError(L, "Unknown globe name: " + globeIdentifier); + } + + const RenderableGlobe* globe = dynamic_cast(n->renderable()); + if (!globe) { + return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe"); + } + + globebrowsing::layergroupid::GroupID group = + ghoul::from_string(layer); + if (group == globebrowsing::layergroupid::GroupID::Unknown) { + return ghoul::lua::luaError(L, "Unknown layer groupd: " + layer); + } + + const globebrowsing::LayerGroup& lg = globe->layerManager().layerGroup(group); + std::vector layers = lg.layers(); + + lua_newtable(L); + int key = 1; + for (globebrowsing::Layer* l : layers) { + ghoul::lua::push(L, key, l->identifier()); + lua_settable(L, -3); + key++; + } + return 1; +} + +int moveLayer(lua_State* L) { + ghoul::lua::checkArgumentsAndThrow(L, 4, "lua::moveLayer"); + + const std::string& globeIdentifier = ghoul::lua::value(L, 1); + const std::string& layer = ghoul::lua::value(L, 2); + int oldPosition = ghoul::lua::value(L, 3); + int newPosition = ghoul::lua::value(L, 4); + lua_pop(L, 4); + + if (oldPosition == newPosition) { + return 0; + } + + SceneGraphNode* n = sceneGraphNode(globeIdentifier); + if (!n) { + return ghoul::lua::luaError(L, "Unknown globe name: " + globeIdentifier); + } + + RenderableGlobe* globe = dynamic_cast(n->renderable()); + if (!globe) { + return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe"); + } + + globebrowsing::layergroupid::GroupID group = + ghoul::from_string(layer); + if (group == globebrowsing::layergroupid::GroupID::Unknown) { + return ghoul::lua::luaError(L, "Unknown layer groupd: " + layer); + } + + globebrowsing::LayerGroup& lg = globe->layerManager().layerGroup(group); + lg.moveLayers(oldPosition, newPosition); + + return 0; +} + int goToChunk(lua_State* L) { ghoul::lua::checkArgumentsAndThrow(L, 4, "lua::goToChunk"); diff --git a/modules/globebrowsing/src/layergroup.cpp b/modules/globebrowsing/src/layergroup.cpp index e0aff6f0af..df012f3a9f 100644 --- a/modules/globebrowsing/src/layergroup.cpp +++ b/modules/globebrowsing/src/layergroup.cpp @@ -155,6 +155,33 @@ void LayerGroup::deleteLayer(const std::string& layerName) { LERROR("Could not find layer " + layerName); } +void LayerGroup::moveLayers(int oldPosition, int newPosition) { + oldPosition = std::max(0, oldPosition); + newPosition = std::min(newPosition, static_cast(_layers.size())); + + // We need to adjust the new position as we first delete the old position, if this + // position is before the new position we have reduced the size of the vector by 1 and + // need to adapt where we want to put the value in + if (oldPosition < newPosition) { + newPosition -= 1; + } + + // There are two synchronous vectors that we have to update here. The _layers vector + // is used to determine the order while rendering, the _subowners is the order in + // which the layers are shown in the UI + auto oldPosLayers = _layers.begin() + oldPosition; + std::unique_ptr v = std::move(*oldPosLayers); + _layers.erase(oldPosLayers); + auto newPosLayers = _layers.begin() + newPosition; + _layers.insert(newPosLayers, std::move(v)); + + auto oldPosOwner = _subOwners.begin() + oldPosition; + PropertyOwner* owner = std::move(*oldPosOwner); + _subOwners.erase(oldPosOwner); + auto newPosOwner = _subOwners.begin() + newPosition; + _subOwners.insert(newPosOwner, std::move(owner)); +} + std::vector LayerGroup::layers() const { std::vector res; res.reserve(_layers.size()); diff --git a/modules/globebrowsing/src/layergroup.h b/modules/globebrowsing/src/layergroup.h index 7db9a718de..f02fd0d80a 100644 --- a/modules/globebrowsing/src/layergroup.h +++ b/modules/globebrowsing/src/layergroup.h @@ -53,6 +53,7 @@ struct LayerGroup : public properties::PropertyOwner { Layer* addLayer(const ghoul::Dictionary& layerDict); void deleteLayer(const std::string& layerName); + void moveLayers(int oldPosition, int newPosition); /// @returns const vector of all layers std::vector layers() const; diff --git a/modules/globebrowsing/src/layermanager.cpp b/modules/globebrowsing/src/layermanager.cpp index ae677ada58..825f465fa7 100644 --- a/modules/globebrowsing/src/layermanager.cpp +++ b/modules/globebrowsing/src/layermanager.cpp @@ -88,6 +88,10 @@ void LayerManager::deleteLayer(layergroupid::GroupID id, const std::string& laye _layerGroups[id]->deleteLayer(layerName); } +LayerGroup& LayerManager::layerGroup(layergroupid::GroupID groupId) { + return *_layerGroups[groupId]; +} + const LayerGroup& LayerManager::layerGroup(layergroupid::GroupID groupId) const { return *_layerGroups[groupId]; } diff --git a/modules/globebrowsing/src/layermanager.h b/modules/globebrowsing/src/layermanager.h index 36de309488..bd504210c1 100644 --- a/modules/globebrowsing/src/layermanager.h +++ b/modules/globebrowsing/src/layermanager.h @@ -57,6 +57,7 @@ public: const ghoul::Dictionary& layerDict); void deleteLayer(layergroupid::GroupID groupId, const std::string& layerName); + LayerGroup& layerGroup(layergroupid::GroupID); const LayerGroup& layerGroup(layergroupid::GroupID) const; bool hasAnyBlendingLayersEnabled() const;