started to move WebEntityAPIHelper from RenderableWebEntityItem to OffscreenQmlSurface

This commit is contained in:
Seth Alves 2016-09-09 11:23:37 -07:00
parent ef8c2a2888
commit 02dba2fe49
4 changed files with 83 additions and 79 deletions

View file

@ -53,20 +53,14 @@ RenderableWebEntityItem::RenderableWebEntityItem(const EntityItemID& entityItemI
_touchDevice.setName("RenderableWebEntityItemTouchDevice");
_touchDevice.setMaximumTouchPoints(4);
_webEntityAPIHelper = new WebEntityAPIHelper;
_webEntityAPIHelper->setRenderableWebEntityItem(this);
_webEntityAPIHelper->moveToThread(qApp->thread());
// forward web events to EntityScriptingInterface
auto entities = DependencyManager::get<EntityScriptingInterface>();
QObject::connect(_webEntityAPIHelper, &WebEntityAPIHelper::webEventReceived, [=](const QVariant& message) {
QObject::connect(_webSurface->_webEntityAPIHelper, &WebEntityAPIHelper::webEventReceived, [=](const QVariant& message) {
emit entities->webEventReceived(entityItemID, message);
});
}
RenderableWebEntityItem::~RenderableWebEntityItem() {
_webEntityAPIHelper->setRenderableWebEntityItem(nullptr);
_webEntityAPIHelper->deleteLater();
destroyWebSurface();
qDebug() << "Destroyed web entity " << getID();
}
@ -103,10 +97,8 @@ bool RenderableWebEntityItem::buildWebSurface(EntityTreeRenderer* renderer) {
context->setContextProperty("eventBridgeJavaScriptToInject", QVariant(javaScriptToInject));
});
_webSurface->resume();
_webSurface->getRootItem()->setProperty("eventBridge", QVariant::fromValue(_webEntityAPIHelper));
_webSurface->getRootItem()->setProperty("url", _sourceUrl);
_webSurface->getRootContext()->setContextProperty("desktop", QVariant());
_webSurface->getRootContext()->setContextProperty("webEntity", _webEntityAPIHelper);
_connection = QObject::connect(_webSurface, &OffscreenQmlSurface::textureUpdated, [&](GLuint textureId) {
_texture = textureId;
});
@ -343,62 +335,6 @@ bool RenderableWebEntityItem::isTransparent() {
return fadeRatio < OPAQUE_ALPHA_THRESHOLD;
}
// UTF-8 encoded symbols
static const uint8_t UPWARDS_WHITE_ARROW_FROM_BAR[] = { 0xE2, 0x87, 0xAA, 0x00 }; // shift
static const uint8_t LEFT_ARROW[] = { 0xE2, 0x86, 0x90, 0x00 }; // backspace
static const uint8_t LEFTWARD_WHITE_ARROW[] = { 0xE2, 0x87, 0xA6, 0x00 }; // left arrow
static const uint8_t RIGHTWARD_WHITE_ARROW[] = { 0xE2, 0x87, 0xA8, 0x00 }; // right arrow
static const uint8_t ASTERISIM[] = { 0xE2, 0x81, 0x82, 0x00 }; // symbols
static const uint8_t RETURN_SYMBOL[] = { 0xE2, 0x8F, 0x8E, 0x00 }; // return
static const char PUNCTUATION_STRING[] = "&123";
static const char ALPHABET_STRING[] = "abc";
static bool equals(const QByteArray& byteArray, const uint8_t* ptr) {
int i;
for (i = 0; i < byteArray.size(); i++) {
if ((char)ptr[i] != byteArray[i]) {
return false;
}
}
return ptr[i] == 0x00;
}
void RenderableWebEntityItem::synthesizeKeyPress(QString key) {
auto utf8Key = key.toUtf8();
int scanCode = (int)utf8Key[0];
QString keyString = key;
if (equals(utf8Key, UPWARDS_WHITE_ARROW_FROM_BAR) || equals(utf8Key, ASTERISIM) ||
equals(utf8Key, (uint8_t*)PUNCTUATION_STRING) || equals(utf8Key, (uint8_t*)ALPHABET_STRING)) {
return; // ignore
} else if (equals(utf8Key, LEFT_ARROW)) {
scanCode = Qt::Key_Backspace;
keyString = "\x08";
} else if (equals(utf8Key, RETURN_SYMBOL)) {
scanCode = Qt::Key_Return;
keyString = "\x0d";
} else if (equals(utf8Key, LEFTWARD_WHITE_ARROW)) {
scanCode = Qt::Key_Left;
keyString = "";
} else if (equals(utf8Key, RIGHTWARD_WHITE_ARROW)) {
scanCode = Qt::Key_Right;
keyString = "";
}
QKeyEvent* pressEvent = new QKeyEvent(QEvent::KeyPress, scanCode, Qt::NoModifier, keyString);
QKeyEvent* releaseEvent = new QKeyEvent(QEvent::KeyRelease, scanCode, Qt::NoModifier, keyString);
QCoreApplication::postEvent(getEventHandler(), pressEvent);
QCoreApplication::postEvent(getEventHandler(), releaseEvent);
}
void RenderableWebEntityItem::emitScriptEvent(const QVariant& message) {
_webEntityAPIHelper->emitScriptEvent(message);
}
void RenderableWebEntityItem::setKeyboardRaised(bool raised) {
// raise the keyboard only while in HMD mode and it's being requested.
bool value = AbstractViewStateInterface::instance()->isHMDMode() && raised;
_webSurface->getRootItem()->setProperty("keyboardRaised", QVariant(value));
_webSurface->_webEntityAPIHelper->emitScriptEvent(message);
}

View file

@ -46,15 +46,11 @@ public:
bool needsToCallUpdate() const override { return _webSurface != nullptr; }
virtual void emitScriptEvent(const QVariant& message) override;
void setKeyboardRaised(bool raised);
SIMPLE_RENDERABLE();
virtual bool isTransparent() override;
public:
void synthesizeKeyPress(QString key);
private:
bool buildWebSurface(EntityTreeRenderer* renderer);
void destroyWebSurface();

View file

@ -419,6 +419,9 @@ bool OffscreenQmlRenderThread::allowNewFrame(uint8_t fps) {
}
OffscreenQmlSurface::OffscreenQmlSurface() {
_webEntityAPIHelper = new WebEntityAPIHelper;
_webEntityAPIHelper->setOffscreenQmlSurface(this);
_webEntityAPIHelper->moveToThread(qApp->thread());
}
static const uint64_t MAX_SHUTDOWN_WAIT_SECS = 2;
@ -432,6 +435,9 @@ OffscreenQmlSurface::~OffscreenQmlSurface() {
qWarning() << "Failed to shut down the QML Renderer Thread";
}
_webEntityAPIHelper->setOffscreenQmlSurface(nullptr);
_webEntityAPIHelper->deleteLater();
delete _rootItem;
delete _renderer;
delete _qmlComponent;
@ -754,6 +760,9 @@ void OffscreenQmlSurface::pause() {
void OffscreenQmlSurface::resume() {
_paused = false;
requestRender();
getRootItem()->setProperty("eventBridge", QVariant::fromValue(_webEntityAPIHelper));
getRootContext()->setContextProperty("webEntity", _webEntityAPIHelper);
}
bool OffscreenQmlSurface::isPaused() const {
@ -829,10 +838,68 @@ void OffscreenQmlSurface::setFocusText(bool newFocusText) {
}
}
// UTF-8 encoded symbols
static const uint8_t UPWARDS_WHITE_ARROW_FROM_BAR[] = { 0xE2, 0x87, 0xAA, 0x00 }; // shift
static const uint8_t LEFT_ARROW[] = { 0xE2, 0x86, 0x90, 0x00 }; // backspace
static const uint8_t LEFTWARD_WHITE_ARROW[] = { 0xE2, 0x87, 0xA6, 0x00 }; // left arrow
static const uint8_t RIGHTWARD_WHITE_ARROW[] = { 0xE2, 0x87, 0xA8, 0x00 }; // right arrow
static const uint8_t ASTERISIM[] = { 0xE2, 0x81, 0x82, 0x00 }; // symbols
static const uint8_t RETURN_SYMBOL[] = { 0xE2, 0x8F, 0x8E, 0x00 }; // return
static const char PUNCTUATION_STRING[] = "&123";
static const char ALPHABET_STRING[] = "abc";
static bool equals(const QByteArray& byteArray, const uint8_t* ptr) {
int i;
for (i = 0; i < byteArray.size(); i++) {
if ((char)ptr[i] != byteArray[i]) {
return false;
}
}
return ptr[i] == 0x00;
}
void OffscreenQmlSurface::synthesizeKeyPress(QString key) {
auto utf8Key = key.toUtf8();
int scanCode = (int)utf8Key[0];
QString keyString = key;
if (equals(utf8Key, UPWARDS_WHITE_ARROW_FROM_BAR) || equals(utf8Key, ASTERISIM) ||
equals(utf8Key, (uint8_t*)PUNCTUATION_STRING) || equals(utf8Key, (uint8_t*)ALPHABET_STRING)) {
return; // ignore
} else if (equals(utf8Key, LEFT_ARROW)) {
scanCode = Qt::Key_Backspace;
keyString = "\x08";
} else if (equals(utf8Key, RETURN_SYMBOL)) {
scanCode = Qt::Key_Return;
keyString = "\x0d";
} else if (equals(utf8Key, LEFTWARD_WHITE_ARROW)) {
scanCode = Qt::Key_Left;
keyString = "";
} else if (equals(utf8Key, RIGHTWARD_WHITE_ARROW)) {
scanCode = Qt::Key_Right;
keyString = "";
}
QKeyEvent* pressEvent = new QKeyEvent(QEvent::KeyPress, scanCode, Qt::NoModifier, keyString);
QKeyEvent* releaseEvent = new QKeyEvent(QEvent::KeyRelease, scanCode, Qt::NoModifier, keyString);
QCoreApplication::postEvent(getEventHandler(), pressEvent);
QCoreApplication::postEvent(getEventHandler(), releaseEvent);
}
void OffscreenQmlSurface::setKeyboardRaised(bool raised) {
// raise the keyboard only while in HMD mode and it's being requested.
// XXX
// bool value = AbstractViewStateInterface::instance()->isHMDMode() && raised;
// getRootItem()->setProperty("keyboardRaised", QVariant(value));
getRootItem()->setProperty("keyboardRaised", QVariant(raised));
}
void WebEntityAPIHelper::synthesizeKeyPress(QString key) {
if (_renderableWebEntityItem) {
_renderableWebEntityItem->synthesizeKeyPress(key);
if (_offscreenQmlSurface) {
_offscreenQmlSurface->synthesizeKeyPress(key);
}
}
@ -849,10 +916,10 @@ void WebEntityAPIHelper::emitWebEvent(const QVariant& message) {
QMetaObject::invokeMethod(this, "emitWebEvent", Qt::QueuedConnection, Q_ARG(QVariant, message));
} else {
// special case to handle raising and lowering the virtual keyboard
if (message.type() == QVariant::String && message.toString() == "_RAISE_KEYBOARD" && _renderableWebEntityItem) {
_renderableWebEntityItem->setKeyboardRaised(true);
} else if (message.type() == QVariant::String && message.toString() == "_LOWER_KEYBOARD" && _renderableWebEntityItem) {
_renderableWebEntityItem->setKeyboardRaised(false);
if (message.type() == QVariant::String && message.toString() == "_RAISE_KEYBOARD" && _offscreenQmlSurface) {
_offscreenQmlSurface->setKeyboardRaised(true);
} else if (message.type() == QVariant::String && message.toString() == "_LOWER_KEYBOARD" && _offscreenQmlSurface) {
_offscreenQmlSurface->setKeyboardRaised(false);
} else {
emit webEventReceived(message);
}

View file

@ -27,13 +27,14 @@ class QQuickWindow;
class QQuickItem;
class OffscreenQmlRenderThread;
class OffscreenQmlSurface;
class WebEntityAPIHelper : public QObject {
Q_OBJECT
public:
void setRenderableWebEntityItem(RenderableWebEntityItem* renderableWebEntityItem) {
_renderableWebEntityItem = renderableWebEntityItem;
void setOffscreenQmlSurface(OffscreenQmlSurface* renderableWebEntityItem) {
_offscreenQmlSurface = renderableWebEntityItem;
}
Q_INVOKABLE void synthesizeKeyPress(QString key);
@ -46,7 +47,7 @@ signals:
void webEventReceived(const QVariant& message);
protected:
RenderableWebEntityItem* _renderableWebEntityItem{ nullptr };
OffscreenQmlSurface* _offscreenQmlSurface{ nullptr };
};
@ -91,6 +92,10 @@ public:
QPointF mapToVirtualScreen(const QPointF& originalPoint, QObject* originalWidget);
bool eventFilter(QObject* originalDestination, QEvent* event) override;
void setKeyboardRaised(bool raised);
void synthesizeKeyPress(QString key);
// XXX make private
WebEntityAPIHelper* _webEntityAPIHelper;