mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 19:10:07 +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 "Application.h"
|
||||
#include "ClipboardScriptingInterface.h"
|
||||
#include "DataServerClient.h"
|
||||
#include "InterfaceVersion.h"
|
||||
#include "Menu.h"
|
||||
|
@ -1686,6 +1687,10 @@ bool Application::sendVoxelsOperation(OctreeElement* element, void* extraData) {
|
|||
}
|
||||
|
||||
void Application::exportVoxels() {
|
||||
exportVoxels(_mouseVoxel);
|
||||
}
|
||||
|
||||
void Application::exportVoxels(const VoxelDetail& sourceVoxel) {
|
||||
QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
||||
QString suggestedName = desktopLocation.append("/voxels.svo");
|
||||
|
||||
|
@ -1693,7 +1698,7 @@ void Application::exportVoxels() {
|
|||
tr("Sparse Voxel Octree Files (*.svo)"));
|
||||
QByteArray fileNameAscii = fileNameString.toLocal8Bit();
|
||||
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) {
|
||||
VoxelTree exportTree;
|
||||
_voxels.copySubTreeIntoNewTree(selectedNode, &exportTree, true);
|
||||
|
@ -1721,11 +1726,19 @@ void Application::importVoxels() {
|
|||
}
|
||||
|
||||
void Application::cutVoxels() {
|
||||
copyVoxels();
|
||||
deleteVoxelUnderCursor();
|
||||
cutVoxels(_mouseVoxel);
|
||||
}
|
||||
|
||||
void Application::cutVoxels(const VoxelDetail& sourceVoxel) {
|
||||
copyVoxels(sourceVoxel);
|
||||
deleteVoxelAt(sourceVoxel);
|
||||
}
|
||||
|
||||
void Application::copyVoxels() {
|
||||
copyVoxels(_mouseVoxel);
|
||||
}
|
||||
|
||||
void Application::copyVoxels(const VoxelDetail& sourceVoxel) {
|
||||
// switch to and clear the clipboard first...
|
||||
_sharedVoxelSystem.killLocalVoxels();
|
||||
if (_sharedVoxelSystem.getTree() != &_clipboard) {
|
||||
|
@ -1734,7 +1747,7 @@ void Application::copyVoxels() {
|
|||
}
|
||||
|
||||
// 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) {
|
||||
_voxels.copySubTreeIntoNewTree(selectedNode, &_sharedVoxelSystem, true);
|
||||
}
|
||||
|
@ -1756,8 +1769,12 @@ void Application::pasteVoxelsToOctalCode(const unsigned char* octalCodeDestinati
|
|||
}
|
||||
|
||||
void Application::pasteVoxels() {
|
||||
pasteVoxels(_mouseVoxel);
|
||||
}
|
||||
|
||||
void Application::pasteVoxels(const VoxelDetail& sourceVoxel) {
|
||||
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
|
||||
// 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) {
|
||||
octalCodeDestination = selectedNode->getOctalCode();
|
||||
} 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);
|
||||
|
@ -3789,18 +3806,27 @@ bool Application::maybeEditVoxelUnderCursor() {
|
|||
}
|
||||
|
||||
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
|
||||
_voxelEditSender.sendVoxelEditMessage(PacketTypeVoxelErase, _mouseVoxel);
|
||||
_voxelEditSender.sendVoxelEditMessage(PacketTypeVoxelErase, voxel);
|
||||
|
||||
// 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
|
||||
_justEditedVoxel = true;
|
||||
}
|
||||
|
||||
|
||||
void Application::eyedropperVoxelUnderCursor() {
|
||||
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
||||
if (selectedNode && selectedNode->isColored()) {
|
||||
|
@ -4138,6 +4164,10 @@ void Application::loadScript(const QString& fileNameString) {
|
|||
scriptEngine->registerGlobalObject("Camera", cameraScriptable);
|
||||
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);
|
||||
|
||||
QThread* workerThread = new QThread(this);
|
||||
|
|
|
@ -222,13 +222,19 @@ public slots:
|
|||
void nodeKilled(SharedNodePointer node);
|
||||
void packetSent(quint64 length);
|
||||
|
||||
void exportVoxels();
|
||||
void importVoxels();
|
||||
void cutVoxels();
|
||||
void copyVoxels();
|
||||
void pasteVoxels();
|
||||
void nudgeVoxels();
|
||||
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 doKillLocalVoxels();
|
||||
|
@ -322,6 +328,7 @@ private:
|
|||
|
||||
bool maybeEditVoxelUnderCursor();
|
||||
void deleteVoxelUnderCursor();
|
||||
void deleteVoxelAt(const VoxelDetail& voxel);
|
||||
void eyedropperVoxelUnderCursor();
|
||||
|
||||
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
|
||||
/// responsibility of caller and MUST be deleted by caller.
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
if (!_shouldSend) {
|
||||
return; // bail early
|
||||
|
|
|
@ -19,7 +19,7 @@ class VoxelEditPacketSender : public OctreeEditPacketSender {
|
|||
Q_OBJECT
|
||||
public:
|
||||
/// 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
|
||||
/// 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