mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-05 11:09:37 -06:00
Update the structure of the renderable sky browser to inherit fronm renderable plane and wwtcommuicator
This commit is contained in:
@@ -39,12 +39,11 @@ local browser = {
|
||||
|
||||
asset.onInitialize(function ()
|
||||
openspace.addSceneGraphNode(browser)
|
||||
openspace.skybrowser.addToSkyBrowserModule(browserId)
|
||||
openspace.skybrowser.add3dBrowserToSkyBrowserModule(browserId)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function ()
|
||||
openspace.removeScreenSpaceRenderable(browserId)
|
||||
openspace.removeScreenSpaceRenderable(targetId)
|
||||
openspace.removeSceneGraphNode(browserId)
|
||||
end)
|
||||
|
||||
asset.export("browser", {browser})
|
||||
|
||||
@@ -30,11 +30,11 @@ set(HEADER_FILES
|
||||
include/screenspaceskytarget.h
|
||||
include/wwtdatahandler.h
|
||||
include/utility.h
|
||||
include/renderableskybrowser.h
|
||||
include/pair.h
|
||||
include/wwtcommunicator.h
|
||||
include/browser.h
|
||||
include/screenspaceskybrowser.h
|
||||
include/renderableskybrowser.h
|
||||
ext/tinyxml2/tinyxml2.h
|
||||
|
||||
)
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
#define __OPENSPACE_MODULE_SKYBROWSER___RENDERABLESKYBROWSER___H__
|
||||
|
||||
#include <modules/skybrowser/include/wwtdatahandler.h>
|
||||
#include <modules/webbrowser/include/webrenderhandler.h>
|
||||
#include <modules/webbrowser/include/browserinstance.h>
|
||||
#include <modules/webbrowser/include/webkeyboardhandler.h>
|
||||
#include <modules/skybrowser/include/wwtcommunicator.h>
|
||||
#include <modules/base/rendering/renderableplane.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/properties/vector/vec2property.h>
|
||||
@@ -35,72 +33,32 @@ namespace ghoul::opengl { class Texture; }
|
||||
|
||||
namespace openspace::documentation { struct Documentation; }
|
||||
|
||||
#pragma optimize("", off)
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class RenderableSkyBrowser : public RenderablePlane
|
||||
class RenderableSkyBrowser : public RenderablePlane, public WwtCommunicator
|
||||
{
|
||||
public:
|
||||
static constexpr const char* KeyIdentifier = "Identifier";
|
||||
|
||||
RenderableSkyBrowser(const ghoul::Dictionary& dictionary);
|
||||
virtual ~RenderableSkyBrowser() = default;
|
||||
~RenderableSkyBrowser();
|
||||
|
||||
// Inherited from RenderablePlane
|
||||
void initializeGL() override;
|
||||
void deinitializeGL() override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
// Web page communication
|
||||
void executeJavascript(std::string script) const;
|
||||
void setIdInBrowser(std::string id);
|
||||
|
||||
// WorldWide Telescope communication
|
||||
void displayImage(const ImageData& image, const int i);
|
||||
void removeSelectedImage(const ImageData& image, const int i);
|
||||
void sendMessageToWwt(const ghoul::Dictionary& msg);
|
||||
void syncWwtView();
|
||||
// Set up initialization with wwt
|
||||
void stopSyncingWwtView();
|
||||
void setIdInBrowser();
|
||||
|
||||
// Place
|
||||
void placeAt3dPosition(const ImageData& image);
|
||||
|
||||
// Getters
|
||||
float verticalFov() const;
|
||||
std::deque<int>& getSelectedImages();
|
||||
|
||||
// Setters
|
||||
void setImageLayerOrder(int i, int order);
|
||||
|
||||
private:
|
||||
// Properties
|
||||
properties::Vec2Property _dimensions;
|
||||
properties::StringProperty _url;
|
||||
properties::TriggerProperty _reload;
|
||||
|
||||
class ScreenSpaceRenderHandler : public WebRenderHandler {
|
||||
public:
|
||||
void draw() override;
|
||||
void render() override;
|
||||
|
||||
void setTexture(GLuint t);
|
||||
};
|
||||
|
||||
void bindTexture() override;
|
||||
|
||||
// Browser variables
|
||||
std::unique_ptr<BrowserInstance> _browserInstance;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _texture;
|
||||
CefRefPtr<ScreenSpaceRenderHandler> _renderHandler;
|
||||
CefRefPtr<WebKeyboardHandler> _keyboardHandler;
|
||||
|
||||
// Flags
|
||||
bool _isUrlDirty = false;
|
||||
bool _isDimensionsDirty = false;
|
||||
bool _isSyncedWithWwt;
|
||||
|
||||
float _verticalFov;
|
||||
std::thread _threadWwtMessages;
|
||||
std::deque<int> _selectedImages;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -470,15 +470,15 @@ void SkyBrowserModule::setSelectedObject()
|
||||
|
||||
// Find and save what mouse is currently hovering on
|
||||
auto it = std::find_if(std::begin(_targetsBrowsers), std::end(_targetsBrowsers),
|
||||
[&] (Pair &pair) {
|
||||
bool onBrowser = pair.getBrowser()->coordIsInsideCornersScreenSpace(
|
||||
[&] (const std::unique_ptr<Pair> &pair) {
|
||||
bool onBrowser = pair->getBrowser()->coordIsInsideCornersScreenSpace(
|
||||
_mousePosition
|
||||
);
|
||||
bool onTarget = pair.getTarget()->coordIsInsideCornersScreenSpace(
|
||||
bool onTarget = pair->getTarget()->coordIsInsideCornersScreenSpace(
|
||||
_mousePosition
|
||||
);
|
||||
if (onBrowser) {
|
||||
_selectedBrowser = pair.getBrowser()->identifier();
|
||||
_selectedBrowser = pair->getBrowser()->identifier();
|
||||
}
|
||||
_isBrowser = onBrowser;
|
||||
|
||||
@@ -489,7 +489,7 @@ void SkyBrowserModule::setSelectedObject()
|
||||
_mouseOnPair = nullptr;
|
||||
}
|
||||
else {
|
||||
_mouseOnPair = &(*it);
|
||||
_mouseOnPair = it->get();
|
||||
}
|
||||
|
||||
// Selection has changed
|
||||
@@ -518,8 +518,7 @@ void SkyBrowserModule::addTargetBrowserPair(std::string targetId, std::string br
|
||||
|
||||
// Assert pair to have both target and browser
|
||||
if (browser && target) {
|
||||
Pair newPair(browser, target);
|
||||
_targetsBrowsers.push_back(newPair);
|
||||
_targetsBrowsers.push_back(std::make_unique<Pair>(browser, target));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -584,9 +583,11 @@ void SkyBrowserModule::removeTargetBrowserPair(std::string& id) {
|
||||
if (!found) {
|
||||
return;
|
||||
}
|
||||
auto it = std::remove(std::begin(_targetsBrowsers), std::end(_targetsBrowsers),
|
||||
*found);
|
||||
|
||||
auto it = std::remove_if(std::begin(_targetsBrowsers), std::end(_targetsBrowsers),
|
||||
[&](const std::unique_ptr<Pair>& pair) {
|
||||
return *found == *(pair.get());
|
||||
});
|
||||
|
||||
std::string targetId = found->getTarget()->identifier();
|
||||
// Remove from engine
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
@@ -644,7 +645,7 @@ void SkyBrowserModule::selectImage3dBrowser(int i)
|
||||
_browser3dNode->renderable());
|
||||
if (renderable) {
|
||||
const ImageData& image = _dataHandler->getImage(i);
|
||||
renderable->displayImage(image, i);
|
||||
renderable->displayImage(image.imageUrl, i);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -698,13 +699,11 @@ void SkyBrowserModule::add2dSelectedImagesTo3d(const std::string& pairId)
|
||||
|
||||
if (pair && get3dBrowser()) {
|
||||
|
||||
// Empty 3D browser selection
|
||||
get3dBrowser()->getSelectedImages().clear();
|
||||
// Copy 2D selection of images to 3D browser
|
||||
const std::deque<int> images = pair->getSelectedImages();
|
||||
std::for_each(std::begin(images), std::end(images), [&](const int i) {
|
||||
const ImageData& image = _dataHandler->getImage(i);
|
||||
get3dBrowser()->displayImage(image, i);
|
||||
get3dBrowser()->displayImage(image.imageUrl, i);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -713,7 +712,7 @@ const std::unique_ptr<WwtDataHandler>& SkyBrowserModule::getWWTDataHandler() {
|
||||
return _dataHandler;
|
||||
}
|
||||
|
||||
std::vector<Pair>& SkyBrowserModule::getPairs()
|
||||
std::vector<std::unique_ptr<Pair>>& SkyBrowserModule::getPairs()
|
||||
{
|
||||
return _targetsBrowsers;
|
||||
}
|
||||
@@ -721,12 +720,17 @@ std::vector<Pair>& SkyBrowserModule::getPairs()
|
||||
Pair* SkyBrowserModule::getPair(const std::string& id)
|
||||
{
|
||||
auto it = std::find_if(std::begin(_targetsBrowsers), std::end(_targetsBrowsers),
|
||||
[&](Pair& pair) {
|
||||
bool foundBrowser = pair.browserId() == id;
|
||||
bool foundTarget = pair.targetId() == id;
|
||||
[&](const std::unique_ptr<Pair>& pair) {
|
||||
bool foundBrowser = pair->browserId() == id;
|
||||
bool foundTarget = pair->targetId() == id;
|
||||
return foundBrowser || foundTarget;
|
||||
});
|
||||
return &(*it);
|
||||
if (it == std::end(_targetsBrowsers)) {
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
return it->get();
|
||||
}
|
||||
}
|
||||
|
||||
SceneGraphNode* SkyBrowserModule::get3dBrowserNode() {
|
||||
@@ -776,7 +780,7 @@ void SkyBrowserModule::place3dBrowser(const ImageData& image, const int i)
|
||||
{
|
||||
// If the image has a 3D position, add it to the scene graph
|
||||
if (image.has3dCoords && get3dBrowser()) {
|
||||
get3dBrowser()->displayImage(image, i);
|
||||
get3dBrowser()->displayImage(image.imageUrl, i);
|
||||
get3dBrowser()->placeAt3dPosition(image);
|
||||
}
|
||||
else {
|
||||
@@ -829,14 +833,14 @@ void SkyBrowserModule::incrementallyFadeBrowserTargets(Transparency goal, float
|
||||
}(goal);
|
||||
|
||||
bool isAllFinished{ false };
|
||||
for (Pair& pair : _targetsBrowsers) {
|
||||
if (pair.isEnabled()) {
|
||||
bool isPairFinished = pair.hasFinishedFading(transparency);
|
||||
for (std::unique_ptr<Pair>& pair : _targetsBrowsers) {
|
||||
if (pair->isEnabled()) {
|
||||
bool isPairFinished = pair->hasFinishedFading(transparency);
|
||||
if (!isPairFinished) {
|
||||
pair.incrementallyFade(transparency, _fadingTime, deltaTime);
|
||||
pair->incrementallyFade(transparency, _fadingTime, deltaTime);
|
||||
}
|
||||
else if (isPairFinished && goal == Transparency::Transparent) {
|
||||
pair.disable();
|
||||
pair->disable();
|
||||
}
|
||||
isAllFinished &= isPairFinished;
|
||||
}
|
||||
@@ -850,9 +854,9 @@ void SkyBrowserModule::incrementallyFadeBrowserTargets(Transparency goal, float
|
||||
|
||||
void SkyBrowserModule::incrementallyAnimateTargets(double deltaTime)
|
||||
{
|
||||
for (Pair& pair : _targetsBrowsers) {
|
||||
if (pair.isEnabled()) {
|
||||
pair.incrementallyAnimateToCoordinate(deltaTime);
|
||||
for (std::unique_ptr<Pair>& pair : _targetsBrowsers) {
|
||||
if (pair->isEnabled()) {
|
||||
pair->incrementallyAnimateToCoordinate(deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
virtual ~SkyBrowserModule();
|
||||
|
||||
// Getters
|
||||
std::vector<Pair>& getPairs();
|
||||
std::vector<std::unique_ptr<Pair>>& getPairs();
|
||||
Pair* getPair(const std::string& id);
|
||||
SceneGraphNode* get3dBrowserNode();
|
||||
RenderableSkyBrowser* get3dBrowser();
|
||||
@@ -108,7 +108,7 @@ private:
|
||||
|
||||
void startRotatingCamera(glm::dvec3 endAnimation); // Pass in galactic coordinate
|
||||
// The browsers and targets
|
||||
std::vector<Pair> _targetsBrowsers;
|
||||
std::vector<std::unique_ptr<Pair>> _targetsBrowsers;
|
||||
Pair* _mouseOnPair{ nullptr };
|
||||
Pair* _selectedPair{ nullptr };
|
||||
bool _isBrowser{ false };
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include <modules/skybrowser/include/renderableskybrowser.h>
|
||||
|
||||
#include <modules/skybrowser/include/utility.h>
|
||||
#include <modules/webbrowser/webbrowsermodule.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/util/distanceconstants.h>
|
||||
@@ -49,27 +47,11 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
void RenderableSkyBrowser::ScreenSpaceRenderHandler::draw() {}
|
||||
|
||||
void RenderableSkyBrowser::ScreenSpaceRenderHandler::render() {}
|
||||
|
||||
void RenderableSkyBrowser::ScreenSpaceRenderHandler::setTexture(GLuint t) {
|
||||
_texture = t;
|
||||
}
|
||||
|
||||
|
||||
RenderableSkyBrowser::RenderableSkyBrowser(const ghoul::Dictionary& dictionary)
|
||||
: RenderablePlane(dictionary)
|
||||
, _url(UrlInfo)
|
||||
, _dimensions(DimensionsInfo, glm::vec2(0.f), glm::vec2(0.f), glm::vec2(3000.f))
|
||||
, _reload(ReloadInfo)
|
||||
, _verticalFov(70.f)
|
||||
, _isSyncedWithWwt(false)
|
||||
: RenderablePlane(dictionary),
|
||||
WwtCommunicator(dictionary)
|
||||
{
|
||||
// Handle target dimension property
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
_url = p.url.value_or(_url);
|
||||
|
||||
std::string identifier;
|
||||
if (dictionary.hasValue<std::string>(KeyIdentifier)) {
|
||||
identifier = dictionary.value<std::string>(KeyIdentifier);
|
||||
@@ -79,179 +61,51 @@ namespace openspace {
|
||||
}
|
||||
setIdentifier(identifier);
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
_url = p.url.value_or(_url);
|
||||
|
||||
// Ensure the texture is a square for now
|
||||
// Maybe change later
|
||||
glm::vec2 windowDimensions = global::windowDelegate->currentSubwindowSize();
|
||||
float maxDimension = std::max(windowDimensions.x, windowDimensions.y);
|
||||
_dimensions = { maxDimension, maxDimension };
|
||||
|
||||
// Create browser and render handler
|
||||
_renderHandler = new ScreenSpaceRenderHandler();
|
||||
_keyboardHandler = new WebKeyboardHandler();
|
||||
_browserInstance = std::make_unique<BrowserInstance>(
|
||||
_renderHandler,
|
||||
_keyboardHandler
|
||||
);
|
||||
|
||||
_url.onChange([this]() { _isUrlDirty = true; });
|
||||
_dimensions.onChange([this]() { _isDimensionsDirty = true; });
|
||||
_reload.onChange([this]() { _browserInstance->reloadBrowser(); });
|
||||
|
||||
addProperty(_url);
|
||||
addProperty(_dimensions);
|
||||
addProperty(_reload);
|
||||
addProperty(_verticalFov);
|
||||
addProperty(_borderColor);
|
||||
addProperty(_equatorialAim);
|
||||
}
|
||||
|
||||
RenderableSkyBrowser::~RenderableSkyBrowser() {
|
||||
|
||||
WebBrowserModule* webBrowser = global::moduleEngine->module<WebBrowserModule>();
|
||||
if (webBrowser) {
|
||||
webBrowser->addBrowser(_browserInstance.get());
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::initializeGL() {
|
||||
Browser::initializeGL();
|
||||
RenderablePlane::initializeGL();
|
||||
_texture = std::make_unique<ghoul::opengl::Texture>(
|
||||
glm::uvec3(_dimensions.value(), 1.0f)
|
||||
);
|
||||
_texture->setDimensions(glm::ivec3(_dimensions.value(), 1));
|
||||
|
||||
_renderHandler->setTexture(*_texture);
|
||||
// The browser gets by default the size of the OpenSpace window, so it needs to
|
||||
// be resized
|
||||
_browserInstance->initialize();
|
||||
_browserInstance->loadUrl(_url);
|
||||
_browserInstance->reshape(_dimensions.value());
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::deinitializeGL() {
|
||||
|
||||
RenderablePlane::deinitializeGL();
|
||||
_renderHandler->setTexture(0);
|
||||
_texture = nullptr;
|
||||
|
||||
std::string urlString;
|
||||
_url.getStringValue(urlString);
|
||||
LDEBUG(fmt::format("Deinitializing RenderableSkyBrowser: {}", urlString));
|
||||
|
||||
_browserInstance->close(true);
|
||||
|
||||
WebBrowserModule* webBrowser = global::moduleEngine->module<WebBrowserModule>();
|
||||
if (webBrowser) {
|
||||
webBrowser->removeBrowser(_browserInstance.get());
|
||||
_browserInstance.reset();
|
||||
}
|
||||
else {
|
||||
LWARNING("Could not find WebBrowserModule");
|
||||
}
|
||||
|
||||
RenderablePlane::deinitializeGL();
|
||||
Browser::deinitializeGL();
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::update(const UpdateData& data) {
|
||||
Browser::update();
|
||||
RenderablePlane::update(data);
|
||||
_renderHandler->updateTexture();
|
||||
|
||||
if (_isUrlDirty) {
|
||||
_browserInstance->loadUrl(_url);
|
||||
_isUrlDirty = false;
|
||||
}
|
||||
|
||||
if (_isDimensionsDirty) {
|
||||
_browserInstance->reshape(_dimensions.value());
|
||||
_isDimensionsDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::bindTexture() {
|
||||
if (_texture) {
|
||||
_texture->bind();
|
||||
}
|
||||
else {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
void RenderableSkyBrowser::stopSyncingWwtView()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::executeJavascript(std::string script) const {
|
||||
//LINFOC(_loggerCat, "Executing javascript " + script);
|
||||
const bool isBrowserReady = _browserInstance && _browserInstance->getBrowser();
|
||||
const bool isMainFrameReady = _browserInstance->getBrowser()->GetMainFrame();
|
||||
if (isBrowserReady && isMainFrameReady) {
|
||||
CefRefPtr<CefFrame> frame = _browserInstance->getBrowser()->GetMainFrame();
|
||||
frame->ExecuteJavaScript(script, frame->GetURL(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::sendMessageToWwt(const ghoul::Dictionary& msg) {
|
||||
std::string script = "sendMessageToWWT(" + ghoul::formatJson(msg) + ");";
|
||||
executeJavascript(script);
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::displayImage(const ImageData& image, const int i) {
|
||||
ghoul::Dictionary msg = wwtmessage::moveCamera(
|
||||
image.equatorialSpherical,
|
||||
image.fov,
|
||||
0.0
|
||||
);
|
||||
sendMessageToWwt(msg);
|
||||
_verticalFov = image.fov;
|
||||
// Add to selected images if there are no duplicates
|
||||
auto it = std::find(std::begin(_selectedImages), std::end(_selectedImages), i);
|
||||
if (it == std::end(_selectedImages)) {
|
||||
// Push newly selected image to front
|
||||
_selectedImages.push_front(i);
|
||||
// Create image layer and center WWT app on the image
|
||||
sendMessageToWwt(wwtmessage::addImage(std::to_string(i), image.imageUrl));
|
||||
LINFO("Image has been loaded to " + identifier());
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::removeSelectedImage(const ImageData& image, const int i) {
|
||||
// Remove from selected list
|
||||
auto it = std::find(std::begin(_selectedImages), std::end(_selectedImages), i);
|
||||
if (it != std::end(_selectedImages)) {
|
||||
_selectedImages.erase(it);
|
||||
sendMessageToWwt(wwtmessage::removeImage(std::to_string(i)));
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::setIdInBrowser(std::string id) {
|
||||
// Send ID to it's browser
|
||||
executeJavascript("setId('" + id + "')");
|
||||
}
|
||||
|
||||
float RenderableSkyBrowser::verticalFov() const {
|
||||
return _verticalFov;
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::syncWwtView() {
|
||||
// If the camera is already synced, the browser is already initialized
|
||||
if (!_isSyncedWithWwt) {
|
||||
_isSyncedWithWwt = true;
|
||||
// Start a thread to enable user interaction while sending the calls to WWT
|
||||
_threadWwtMessages = std::thread([&] {
|
||||
while (_isSyncedWithWwt) {
|
||||
|
||||
glm::dvec2 aim{ 0.0 };
|
||||
// Send a message just to establish contact
|
||||
ghoul::Dictionary msg = wwtmessage::moveCamera(
|
||||
aim,
|
||||
_verticalFov,
|
||||
0.0
|
||||
);
|
||||
sendMessageToWwt(msg);
|
||||
|
||||
// Sleep so we don't bombard WWT with too many messages
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::stopSyncingWwtView() {
|
||||
_isSyncedWithWwt = false;
|
||||
|
||||
if (_threadWwtMessages.joinable()) {
|
||||
_threadWwtMessages.join();
|
||||
}
|
||||
void RenderableSkyBrowser::setIdInBrowser()
|
||||
{
|
||||
WwtCommunicator::setIdInBrowser(identifier());
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::placeAt3dPosition(const ImageData& image)
|
||||
@@ -301,32 +155,4 @@ namespace openspace {
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
|
||||
std::deque<int>& RenderableSkyBrowser::getSelectedImages() {
|
||||
return _selectedImages;
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::setImageLayerOrder(int i, int order) {
|
||||
// Remove from selected list
|
||||
auto current = std::find(
|
||||
std::begin(_selectedImages),
|
||||
std::end(_selectedImages),
|
||||
i
|
||||
);
|
||||
auto target = std::begin(_selectedImages) + order;
|
||||
|
||||
// Make sure the image was found in the list
|
||||
if (current != std::end(_selectedImages) && target != std::end(_selectedImages)) {
|
||||
// Swap the two images
|
||||
std::iter_swap(current, target);
|
||||
}
|
||||
|
||||
int reverseOrder = _selectedImages.size() - order - 1;
|
||||
ghoul::Dictionary message = wwtmessage::setLayerOrder(std::to_string(i),
|
||||
reverseOrder);
|
||||
sendMessageToWwt(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user