From 1d7cdff2bcaf18e3d4835e063002dfd224936205 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Mon, 1 Aug 2016 13:24:22 -0700 Subject: [PATCH 1/3] Snapshot button plus script Minor change to allow snapshots to not notify (though the old way with CTRL+S still does). Added button to do it, saves them to disk. The plan is for us to add UI to share (or not) the snapshot. That's why we are not going through the notifications. Also, the script makes sure to hide/unhide hud and overlays. Next we will upload the pick to AWS via data-web (if you are logged in), and _then_ make the share UI. --- interface/src/Application.cpp | 6 +- interface/src/Application.h | 4 +- .../scripting/WindowScriptingInterface.cpp | 7 ++ .../src/scripting/WindowScriptingInterface.h | 3 +- scripts/system/assets/images/tools/snap.svg | 109 ++++++++++++++++++ scripts/system/notifications.js | 12 +- scripts/system/snapshot.js | 66 +++++++++++ 7 files changed, 196 insertions(+), 11 deletions(-) create mode 100755 scripts/system/assets/images/tools/snap.svg create mode 100644 scripts/system/snapshot.js diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e294ae38ad..abc0b91b2d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2281,7 +2281,7 @@ void Application::keyPressEvent(QKeyEvent* event) { } else if (isOption && !isShifted && !isMeta) { Menu::getInstance()->triggerOption(MenuOption::ScriptEditor); } else if (!isOption && !isShifted && isMeta) { - takeSnapshot(); + takeSnapshot(true); } break; @@ -5070,7 +5070,7 @@ void Application::toggleLogDialog() { } } -void Application::takeSnapshot() { +void Application::takeSnapshot(bool notify) { QMediaPlayer* player = new QMediaPlayer(); QFileInfo inf = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav"); player->setMedia(QUrl::fromLocalFile(inf.absoluteFilePath())); @@ -5078,7 +5078,7 @@ void Application::takeSnapshot() { QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot()); - emit DependencyManager::get()->snapshotTaken(path); + emit DependencyManager::get()->snapshotTaken(path, notify); } float Application::getRenderResolutionScale() const { diff --git a/interface/src/Application.h b/interface/src/Application.h index 0af65f665f..ea6a117cfa 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -247,6 +247,8 @@ public: float getAvatarSimrate() const { return _avatarSimCounter.rate(); } float getAverageSimsPerSecond() const { return _simCounter.rate(); } + + void takeSnapshot(bool notify); signals: void svoImportRequested(const QString& url); @@ -373,8 +375,6 @@ private: int sendNackPackets(); - void takeSnapshot(); - MyAvatar* getMyAvatar() const; void checkSkeleton() const; diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index b165cda135..fb7be86096 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -199,3 +199,10 @@ void WindowScriptingInterface::copyToClipboard(const QString& text) { qDebug() << "Copying"; QApplication::clipboard()->setText(text); } + +void WindowScriptingInterface::takeSnapshot(bool notify) { + // only evil-doers call takeSnapshot from a random thread + qApp->postLambdaEvent([&] { + qApp->takeSnapshot(notify); + }); +} diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 9d73111333..1abcb9db35 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -54,12 +54,13 @@ public slots: QScriptValue browse(const QString& title = "", const QString& directory = "", const QString& nameFilter = ""); QScriptValue save(const QString& title = "", const QString& directory = "", const QString& nameFilter = ""); void copyToClipboard(const QString& text); + void takeSnapshot(bool notify); signals: void domainChanged(const QString& domainHostname); void svoImportRequested(const QString& url); void domainConnectionRefused(const QString& reasonMessage, int reasonCode); - void snapshotTaken(const QString& path); + void snapshotTaken(const QString& path, bool notify); private slots: WebWindowClass* doCreateWebWindow(const QString& title, const QString& url, int width, int height); diff --git a/scripts/system/assets/images/tools/snap.svg b/scripts/system/assets/images/tools/snap.svg new file mode 100755 index 0000000000..c540f307ae --- /dev/null +++ b/scripts/system/assets/images/tools/snap.svg @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/system/notifications.js b/scripts/system/notifications.js index 98a31d708c..34f9814d8a 100644 --- a/scripts/system/notifications.js +++ b/scripts/system/notifications.js @@ -527,12 +527,14 @@ function onDomainConnectionRefused(reason) { createNotification("Connection refused: " + reason, NotificationType.CONNECTION_REFUSED); } -function onSnapshotTaken(path) { - var imageProperties = { - path: Script.resolvePath("file:///" + path), - aspectRatio: Window.innerWidth / Window.innerHeight +function onSnapshotTaken(path, notify) { + if (notify) { + var imageProperties = { + path: Script.resolvePath("file:///" + path), + aspectRatio: Window.innerWidth / Window.innerHeight + } + createNotification(wordWrap("Snapshot saved to " + path), NotificationType.SNAPSHOT, imageProperties); } - createNotification(wordWrap("Snapshot saved to " + path), NotificationType.SNAPSHOT, imageProperties); } // handles mouse clicks on buttons diff --git a/scripts/system/snapshot.js b/scripts/system/snapshot.js new file mode 100644 index 0000000000..87ea3f29ec --- /dev/null +++ b/scripts/system/snapshot.js @@ -0,0 +1,66 @@ +// +// snapshot.js +// +// Created by David Kelly on 1 August 2016 +// Copyright 2016 High Fidelity, Inc +// +// Distributed under the Apache License, Version 2.0 +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +var SNAPSHOT_DELAY = 500; // 500ms +var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); +var resetOverlays; +var button = toolBar.addButton({ + objectName: "snapshot", + imageURL: Script.resolvePath("assets/images/tools/snap.svg"), + visible: true, + buttonState: 1, + defaultState: 1, + hoverState: 1, + alpha: 0.9, +}); + +function onClicked() { + // update button states + resetOverlays = Menu.isOptionChecked("Overlays"); + Window.snapshotTaken.connect(resetButtons); + + button.writeProperty("buttonState", 0); + button.writeProperty("defaultState", 0); + button.writeProperty("hoverState", 2); + + // hide overlays if they are on + if (resetOverlays) { + Menu.setIsOptionChecked("Overlays", false); + } + + // hide hud + toolBar.writeProperty("visible", false); + + // take snapshot (with no notification) + Script.setTimeout(function () { + Window.takeSnapshot(false); + }, SNAPSHOT_DELAY); +} + +function resetButtons(path, notify) { + // show overlays if they were on + if (resetOverlays) { + Menu.setIsOptionChecked("Overlays", true); + } + // show hud + toolBar.writeProperty("visible", true); + + // update button states + button.writeProperty("buttonState", 1); + button.writeProperty("defaultState", 1); + button.writeProperty("hoverState", 3); + Window.snapshotTaken.disconnect(resetButtons); +} + +button.clicked.connect(onClicked); + +Script.scriptEnding.connect(function () { + toolBar.removeButton("snapshot"); + button.clicked.disconnect(onClicked); +}); From fcd2947b19fbd50998fccfce979594e43d37b287 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Mon, 1 Aug 2016 18:37:22 -0700 Subject: [PATCH 2/3] Doh -- forgot to push this same logic as before to get a mono image in the HMD. --- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index e0c87fbbed..a4db2811e0 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -662,10 +662,15 @@ void OpenGLDisplayPlugin::withMainThreadContext(std::function f) const { QImage OpenGLDisplayPlugin::getScreenshot() const { using namespace oglplus; - QImage screenshot(_compositeFramebuffer->size.x, _compositeFramebuffer->size.y, QImage::Format_RGBA8888); + auto width = _compositeFramebuffer->size.x; + if (isHmd()) { + width /= 2; + } + + QImage screenshot(width, _compositeFramebuffer->size.y, QImage::Format_RGBA8888); withMainThreadContext([&] { Framebuffer::Bind(Framebuffer::Target::Read, _compositeFramebuffer->fbo); - Context::ReadPixels(0, 0, _compositeFramebuffer->size.x, _compositeFramebuffer->size.y, enums::PixelDataFormat::RGBA, enums::PixelDataType::UnsignedByte, screenshot.bits()); + Context::ReadPixels(0, 0, width, _compositeFramebuffer->size.y, enums::PixelDataFormat::RGBA, enums::PixelDataType::UnsignedByte, screenshot.bits()); }); return screenshot.mirrored(false, true); } From d34e72512bd4c6debee3957a715b3da7480b75e4 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 2 Aug 2016 15:13:48 -0700 Subject: [PATCH 3/3] Add snapshot.js to defaultScripts --- scripts/defaultScripts.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js index 817d63582d..2e707d95ce 100644 --- a/scripts/defaultScripts.js +++ b/scripts/defaultScripts.js @@ -27,3 +27,4 @@ Script.load("system/controllers/grab.js"); Script.load("system/controllers/teleport.js"); Script.load("system/dialTone.js"); Script.load("system/firstPersonHMD.js"); +Script.load("system/snapshot.js");