Add the ability to query and rearrange globebrowsing layers at runtime

This commit is contained in:
Alexander Bock
2019-07-30 14:28:23 +02:00
parent f7fafa5255
commit 4a070c939f
7 changed files with 126 additions and 1 deletions

View File

@@ -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

View File

@@ -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,

View File

@@ -25,6 +25,7 @@
#include <modules/globebrowsing/src/renderableglobe.h>
#include <modules/globebrowsing/src/layer.h>
#include <modules/globebrowsing/src/layergroup.h>
#include <modules/globebrowsing/src/layermanager.h>
#include <openspace/engine/globals.h>
#include <openspace/engine/moduleengine.h>
@@ -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<std::string>(L, 1);
const std::string& layer = ghoul::lua::value<std::string>(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<const RenderableGlobe*>(n->renderable());
if (!globe) {
return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
}
globebrowsing::layergroupid::GroupID group =
ghoul::from_string<globebrowsing::layergroupid::GroupID>(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<globebrowsing::Layer*> 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<std::string>(L, 1);
const std::string& layer = ghoul::lua::value<std::string>(L, 2);
int oldPosition = ghoul::lua::value<int>(L, 3);
int newPosition = ghoul::lua::value<int>(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<RenderableGlobe*>(n->renderable());
if (!globe) {
return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
}
globebrowsing::layergroupid::GroupID group =
ghoul::from_string<globebrowsing::layergroupid::GroupID>(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");

View File

@@ -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<int>(_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<Layer> 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<Layer*> LayerGroup::layers() const {
std::vector<Layer*> res;
res.reserve(_layers.size());

View File

@@ -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<Layer*> layers() const;

View File

@@ -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];
}

View File

@@ -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;