mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 21:43:03 +02:00
first cut at exposing clipboard support to JavaScript
This commit is contained in:
parent
866b3dbb63
commit
bf814410ac
6 changed files with 142 additions and 15 deletions
|
@ -62,6 +62,7 @@
|
||||||
#include <VoxelSceneStats.h>
|
#include <VoxelSceneStats.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
#include "ClipboardScriptingInterface.h"
|
||||||
#include "DataServerClient.h"
|
#include "DataServerClient.h"
|
||||||
#include "InterfaceVersion.h"
|
#include "InterfaceVersion.h"
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
|
@ -1686,6 +1687,10 @@ bool Application::sendVoxelsOperation(OctreeElement* element, void* extraData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::exportVoxels() {
|
void Application::exportVoxels() {
|
||||||
|
exportVoxels(_mouseVoxel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::exportVoxels(const VoxelDetail& sourceVoxel) {
|
||||||
QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
||||||
QString suggestedName = desktopLocation.append("/voxels.svo");
|
QString suggestedName = desktopLocation.append("/voxels.svo");
|
||||||
|
|
||||||
|
@ -1693,7 +1698,7 @@ void Application::exportVoxels() {
|
||||||
tr("Sparse Voxel Octree Files (*.svo)"));
|
tr("Sparse Voxel Octree Files (*.svo)"));
|
||||||
QByteArray fileNameAscii = fileNameString.toLocal8Bit();
|
QByteArray fileNameAscii = fileNameString.toLocal8Bit();
|
||||||
const char* fileName = fileNameAscii.data();
|
const char* fileName = fileNameAscii.data();
|
||||||
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);
|
||||||
if (selectedNode) {
|
if (selectedNode) {
|
||||||
VoxelTree exportTree;
|
VoxelTree exportTree;
|
||||||
_voxels.copySubTreeIntoNewTree(selectedNode, &exportTree, true);
|
_voxels.copySubTreeIntoNewTree(selectedNode, &exportTree, true);
|
||||||
|
@ -1721,11 +1726,19 @@ void Application::importVoxels() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::cutVoxels() {
|
void Application::cutVoxels() {
|
||||||
copyVoxels();
|
cutVoxels(_mouseVoxel);
|
||||||
deleteVoxelUnderCursor();
|
}
|
||||||
|
|
||||||
|
void Application::cutVoxels(const VoxelDetail& sourceVoxel) {
|
||||||
|
copyVoxels(sourceVoxel);
|
||||||
|
deleteVoxelAt(sourceVoxel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::copyVoxels() {
|
void Application::copyVoxels() {
|
||||||
|
copyVoxels(_mouseVoxel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::copyVoxels(const VoxelDetail& sourceVoxel) {
|
||||||
// switch to and clear the clipboard first...
|
// switch to and clear the clipboard first...
|
||||||
_sharedVoxelSystem.killLocalVoxels();
|
_sharedVoxelSystem.killLocalVoxels();
|
||||||
if (_sharedVoxelSystem.getTree() != &_clipboard) {
|
if (_sharedVoxelSystem.getTree() != &_clipboard) {
|
||||||
|
@ -1734,7 +1747,7 @@ void Application::copyVoxels() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// then copy onto it if there is something to copy
|
// then copy onto it if there is something to copy
|
||||||
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);
|
||||||
if (selectedNode) {
|
if (selectedNode) {
|
||||||
_voxels.copySubTreeIntoNewTree(selectedNode, &_sharedVoxelSystem, true);
|
_voxels.copySubTreeIntoNewTree(selectedNode, &_sharedVoxelSystem, true);
|
||||||
}
|
}
|
||||||
|
@ -1756,8 +1769,12 @@ void Application::pasteVoxelsToOctalCode(const unsigned char* octalCodeDestinati
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::pasteVoxels() {
|
void Application::pasteVoxels() {
|
||||||
|
pasteVoxels(_mouseVoxel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::pasteVoxels(const VoxelDetail& sourceVoxel) {
|
||||||
unsigned char* calculatedOctCode = NULL;
|
unsigned char* calculatedOctCode = NULL;
|
||||||
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);
|
||||||
|
|
||||||
// we only need the selected voxel to get the newBaseOctCode, which we can actually calculate from the
|
// we only need the selected voxel to get the newBaseOctCode, which we can actually calculate from the
|
||||||
// voxel size/position details. If we don't have an actual selectedNode then use the mouseVoxel to create a
|
// voxel size/position details. If we don't have an actual selectedNode then use the mouseVoxel to create a
|
||||||
|
@ -1766,7 +1783,7 @@ void Application::pasteVoxels() {
|
||||||
if (selectedNode) {
|
if (selectedNode) {
|
||||||
octalCodeDestination = selectedNode->getOctalCode();
|
octalCodeDestination = selectedNode->getOctalCode();
|
||||||
} else {
|
} else {
|
||||||
octalCodeDestination = calculatedOctCode = pointToVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
octalCodeDestination = calculatedOctCode = pointToVoxel(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);
|
||||||
}
|
}
|
||||||
|
|
||||||
pasteVoxelsToOctalCode(octalCodeDestination);
|
pasteVoxelsToOctalCode(octalCodeDestination);
|
||||||
|
@ -3789,18 +3806,27 @@ bool Application::maybeEditVoxelUnderCursor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::deleteVoxelUnderCursor() {
|
void Application::deleteVoxelUnderCursor() {
|
||||||
if (_mouseVoxel.s != 0) {
|
deleteVoxelAt(_mouseVoxel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::deleteVoxels(const VoxelDetail& voxel) {
|
||||||
|
deleteVoxelAt(voxel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::deleteVoxelAt(const VoxelDetail& voxel) {
|
||||||
|
if (voxel.s != 0) {
|
||||||
// sending delete to the server is sufficient, server will send new version so we see updates soon enough
|
// sending delete to the server is sufficient, server will send new version so we see updates soon enough
|
||||||
_voxelEditSender.sendVoxelEditMessage(PacketTypeVoxelErase, _mouseVoxel);
|
_voxelEditSender.sendVoxelEditMessage(PacketTypeVoxelErase, voxel);
|
||||||
|
|
||||||
// delete it locally to see the effect immediately (and in case no voxel server is present)
|
// delete it locally to see the effect immediately (and in case no voxel server is present)
|
||||||
_voxels.deleteVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
_voxels.deleteVoxelAt(voxel.x, voxel.y, voxel.z, voxel.s);
|
||||||
|
|
||||||
}
|
}
|
||||||
// remember the position for drag detection
|
// remember the position for drag detection
|
||||||
_justEditedVoxel = true;
|
_justEditedVoxel = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Application::eyedropperVoxelUnderCursor() {
|
void Application::eyedropperVoxelUnderCursor() {
|
||||||
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
||||||
if (selectedNode && selectedNode->isColored()) {
|
if (selectedNode && selectedNode->isColored()) {
|
||||||
|
@ -4138,6 +4164,10 @@ void Application::loadScript(const QString& fileNameString) {
|
||||||
scriptEngine->registerGlobalObject("Camera", cameraScriptable);
|
scriptEngine->registerGlobalObject("Camera", cameraScriptable);
|
||||||
connect(scriptEngine, SIGNAL(finished(const QString&)), cameraScriptable, SLOT(deleteLater()));
|
connect(scriptEngine, SIGNAL(finished(const QString&)), cameraScriptable, SLOT(deleteLater()));
|
||||||
|
|
||||||
|
ClipboardScriptingInterface* clipboardScriptable = new ClipboardScriptingInterface();
|
||||||
|
scriptEngine->registerGlobalObject("Clipboard", clipboardScriptable);
|
||||||
|
connect(scriptEngine, SIGNAL(finished(const QString&)), clipboardScriptable, SLOT(deleteLater()));
|
||||||
|
|
||||||
scriptEngine->registerGlobalObject("Overlays", &_overlays);
|
scriptEngine->registerGlobalObject("Overlays", &_overlays);
|
||||||
|
|
||||||
QThread* workerThread = new QThread(this);
|
QThread* workerThread = new QThread(this);
|
||||||
|
|
|
@ -222,13 +222,19 @@ public slots:
|
||||||
void nodeKilled(SharedNodePointer node);
|
void nodeKilled(SharedNodePointer node);
|
||||||
void packetSent(quint64 length);
|
void packetSent(quint64 length);
|
||||||
|
|
||||||
void exportVoxels();
|
|
||||||
void importVoxels();
|
|
||||||
void cutVoxels();
|
void cutVoxels();
|
||||||
void copyVoxels();
|
void copyVoxels();
|
||||||
void pasteVoxels();
|
void pasteVoxels();
|
||||||
void nudgeVoxels();
|
|
||||||
void deleteVoxels();
|
void deleteVoxels();
|
||||||
|
void exportVoxels();
|
||||||
|
void importVoxels();
|
||||||
|
void nudgeVoxels();
|
||||||
|
|
||||||
|
void cutVoxels(const VoxelDetail& sourceVoxel);
|
||||||
|
void copyVoxels(const VoxelDetail& sourceVoxel);
|
||||||
|
void pasteVoxels(const VoxelDetail& sourceVoxel);
|
||||||
|
void deleteVoxels(const VoxelDetail& sourceVoxel);
|
||||||
|
void exportVoxels(const VoxelDetail& sourceVoxel);
|
||||||
|
|
||||||
void setRenderVoxels(bool renderVoxels);
|
void setRenderVoxels(bool renderVoxels);
|
||||||
void doKillLocalVoxels();
|
void doKillLocalVoxels();
|
||||||
|
@ -322,6 +328,7 @@ private:
|
||||||
|
|
||||||
bool maybeEditVoxelUnderCursor();
|
bool maybeEditVoxelUnderCursor();
|
||||||
void deleteVoxelUnderCursor();
|
void deleteVoxelUnderCursor();
|
||||||
|
void deleteVoxelAt(const VoxelDetail& voxel);
|
||||||
void eyedropperVoxelUnderCursor();
|
void eyedropperVoxelUnderCursor();
|
||||||
|
|
||||||
void setMenuShortcutsEnabled(bool enabled);
|
void setMenuShortcutsEnabled(bool enabled);
|
||||||
|
|
59
interface/src/ClipboardScriptingInterface.cpp
Normal file
59
interface/src/ClipboardScriptingInterface.cpp
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
//
|
||||||
|
// ClipboardScriptingInterface.cpp
|
||||||
|
// interface
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Application.h"
|
||||||
|
#include "ClipboardScriptingInterface.h"
|
||||||
|
|
||||||
|
ClipboardScriptingInterface::ClipboardScriptingInterface() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClipboardScriptingInterface::cutVoxels(float x, float y, float z, float s) {
|
||||||
|
VoxelDetail sourceVoxel = { x / (float)TREE_SCALE,
|
||||||
|
y / (float)TREE_SCALE,
|
||||||
|
z / (float)TREE_SCALE,
|
||||||
|
s / (float)TREE_SCALE };
|
||||||
|
Application::getInstance()->cutVoxels(sourceVoxel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClipboardScriptingInterface::copyVoxels(float x, float y, float z, float s) {
|
||||||
|
VoxelDetail sourceVoxel = { x / (float)TREE_SCALE,
|
||||||
|
y / (float)TREE_SCALE,
|
||||||
|
z / (float)TREE_SCALE,
|
||||||
|
s / (float)TREE_SCALE };
|
||||||
|
Application::getInstance()->copyVoxels(sourceVoxel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClipboardScriptingInterface::pasteVoxels(float x, float y, float z, float s) {
|
||||||
|
VoxelDetail sourceVoxel = { x / (float)TREE_SCALE,
|
||||||
|
y / (float)TREE_SCALE,
|
||||||
|
z / (float)TREE_SCALE,
|
||||||
|
s / (float)TREE_SCALE };
|
||||||
|
|
||||||
|
Application::getInstance()->pasteVoxels(sourceVoxel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClipboardScriptingInterface::deleteVoxels(float x, float y, float z, float s) {
|
||||||
|
VoxelDetail sourceVoxel = { x / (float)TREE_SCALE,
|
||||||
|
y / (float)TREE_SCALE,
|
||||||
|
z / (float)TREE_SCALE,
|
||||||
|
s / (float)TREE_SCALE };
|
||||||
|
Application::getInstance()->deleteVoxels(sourceVoxel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClipboardScriptingInterface::exportVoxels(float x, float y, float z, float s) {
|
||||||
|
VoxelDetail sourceVoxel = { x / (float)TREE_SCALE,
|
||||||
|
y / (float)TREE_SCALE,
|
||||||
|
z / (float)TREE_SCALE,
|
||||||
|
s / (float)TREE_SCALE };
|
||||||
|
|
||||||
|
Application::getInstance()->exportVoxels(sourceVoxel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClipboardScriptingInterface::importVoxels() {
|
||||||
|
Application::getInstance()->importVoxels();
|
||||||
|
}
|
||||||
|
|
31
interface/src/ClipboardScriptingInterface.h
Normal file
31
interface/src/ClipboardScriptingInterface.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
//
|
||||||
|
// ClipboardScriptingInterface.h
|
||||||
|
// interface
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// Scriptable interface for the Application clipboard
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __interface__Clipboard__
|
||||||
|
#define __interface__Clipboard__
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <VoxelDetail.h>
|
||||||
|
|
||||||
|
class ClipboardScriptingInterface : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ClipboardScriptingInterface();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void cutVoxels(float x, float y, float z, float s);
|
||||||
|
void copyVoxels(float x, float y, float z, float s);
|
||||||
|
void pasteVoxels(float x, float y, float z, float s);
|
||||||
|
void deleteVoxels(float x, float y, float z, float s);
|
||||||
|
|
||||||
|
void exportVoxels(float x, float y, float z, float s);
|
||||||
|
void importVoxels();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __interface__Clipboard__
|
|
@ -22,7 +22,7 @@
|
||||||
/// PacketTypeVoxelSet, PacketTypeVoxelSetDestructive, or PacketTypeVoxelErase. The buffer is returned to caller becomes
|
/// PacketTypeVoxelSet, PacketTypeVoxelSetDestructive, or PacketTypeVoxelErase. The buffer is returned to caller becomes
|
||||||
/// responsibility of caller and MUST be deleted by caller.
|
/// responsibility of caller and MUST be deleted by caller.
|
||||||
bool createVoxelEditMessage(PacketType command, short int sequence,
|
bool createVoxelEditMessage(PacketType command, short int sequence,
|
||||||
int voxelCount, VoxelDetail* voxelDetails, unsigned char*& bufferOut, int& sizeOut) {
|
int voxelCount, const VoxelDetail* voxelDetails, unsigned char*& bufferOut, int& sizeOut) {
|
||||||
|
|
||||||
bool success = true; // assume the best
|
bool success = true; // assume the best
|
||||||
int messageSize = MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE; // just a guess for now
|
int messageSize = MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE; // just a guess for now
|
||||||
|
@ -102,7 +102,7 @@ bool encodeVoxelEditMessageDetails(PacketType, int voxelCount, VoxelDetail* voxe
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelEditPacketSender::sendVoxelEditMessage(PacketType type, VoxelDetail& detail) {
|
void VoxelEditPacketSender::sendVoxelEditMessage(PacketType type, const VoxelDetail& detail) {
|
||||||
// allows app to disable sending if for example voxels have been disabled
|
// allows app to disable sending if for example voxels have been disabled
|
||||||
if (!_shouldSend) {
|
if (!_shouldSend) {
|
||||||
return; // bail early
|
return; // bail early
|
||||||
|
|
|
@ -19,7 +19,7 @@ class VoxelEditPacketSender : public OctreeEditPacketSender {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
/// Send voxel edit message immediately
|
/// Send voxel edit message immediately
|
||||||
void sendVoxelEditMessage(PacketType type, VoxelDetail& detail);
|
void sendVoxelEditMessage(PacketType type, const VoxelDetail& detail);
|
||||||
|
|
||||||
/// Queues a single voxel edit message. Will potentially send a pending multi-command packet. Determines which voxel-server
|
/// Queues a single voxel edit message. Will potentially send a pending multi-command packet. Determines which voxel-server
|
||||||
/// node or nodes the packet should be sent to. Can be called even before voxel servers are known, in which case up to
|
/// node or nodes the packet should be sent to. Can be called even before voxel servers are known, in which case up to
|
||||||
|
|
Loading…
Reference in a new issue