Layout for running scripts

This commit is contained in:
Brad Davis 2016-01-11 22:04:05 -08:00
parent 55af5eaf06
commit 21534cbde0
15 changed files with 550 additions and 849 deletions

View file

@ -1,18 +1,17 @@
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtWebEngine 1.1
import "controls"
import "styles"
import "windows"
VrDialog {
Window {
id: root
HifiConstants { id: hifi }
title: "Browser"
resizable: true
contentImplicitWidth: clientArea.implicitWidth
contentImplicitHeight: clientArea.implicitHeight
backgroundColor: "#7f000000"
destroyOnInvisible: true
Component.onCompleted: {
enabled = true
@ -27,13 +26,8 @@ VrDialog {
}
Item {
id: clientArea
implicitHeight: 600
implicitWidth: 800
x: root.clientX
y: root.clientY
width: root.clientWidth
height: root.clientHeight
width: 800
height: 600
Rectangle {
anchors.left: parent.left

View file

@ -40,7 +40,8 @@ function getTopLevelWindows(item) {
for (var i = 0; i < desktop.children.length; ++i) {
var child = desktop.children[i];
if (Global.OFFSCREEN_WINDOW_OBJECT_NAME === child.objectName) {
if ((Global.OFFSCREEN_WINDOW_OBJECT_NAME === child.objectName) ||
child[Global.OFFSCREEN_WINDOW_OBJECT_NAME]) {
var windowId = child.toString();
currentWindows.push(child)
}

View file

@ -1,13 +1,12 @@
import Hifi 1.0
import QtQuick 2.5
import QtQuick.Controls 1.4
import "Global.js" as Global
// This is our primary 'window' object to which all dialogs and controls will
// be childed.
Root {
id: root
// This is our primary 'desktop' object to which all VR dialogs and
// windows will be childed.
Item {
id: desktop
objectName: Global.OFFSCREEN_ROOT_OBJECT_NAME
anchors.fill: parent;
property var windows: [];
@ -16,11 +15,14 @@ Root {
}
onChildrenChanged: {
windows = Global.getTopLevelWindows(root);
windows = Global.getTopLevelWindows(desktop);
}
onParentChanged: {
forceActiveFocus();
}
}
function raise(item) {
Global.raiseWindow(item);
}
}

View file

@ -0,0 +1,205 @@
import QtQuick 2.5
import QtQuick.Controls 1.4
import Qt.labs.settings 1.0
import "../styles" as Hifi
import "../controls" as HifiControls
import "../windows"
Window {
id: root
objectName: "RunningScripts"
title: "Running Scripts"
resizable: true
destroyOnInvisible: true
enabled: false
x: 40; y: 40
property var scripts: ScriptDiscoveryService;
property var scriptsModel: scripts.scriptsModelFilter
property var runningScriptsModel: ListModel { }
Settings {
category: "Overlay.RunningScripts"
property alias x: root.x
property alias y: root.y
}
Connections {
target: ScriptDiscoveryService
onScriptCountChanged: updateRunningScripts();
}
Component.onCompleted: updateRunningScripts()
function updateRunningScripts() {
var runningScripts = ScriptDiscoveryService.getRunning();
runningScriptsModel.clear()
for (var i = 0; i < runningScripts.length; ++i) {
runningScriptsModel.append(runningScripts[i]);
}
}
function loadScript(script) {
console.log("Load script " + script);
scripts.loadOneScript(script);
}
function reloadScript(script) {
console.log("Reload script " + script);
scripts.stopScript(script, true);
}
function stopScript(script) {
console.log("Stop script " + script);
scripts.stopScript(script);
}
function reloadAll() {
console.log("Reload all scripts");
scripts.reloadAllScripts();
}
function stopAll() {
console.log("Stop all scripts");
scripts.stopAllScripts();
}
Rectangle {
color: "white"
implicitWidth: 384; implicitHeight: 640
Item {
anchors { fill: parent; margins: 8 }
Text {
id: title
font.bold: true
font.pointSize: 16
color: "#0e7077"
text: "Currently Running"
}
Row {
id: allButtons
anchors.top: title.bottom
anchors.topMargin: 8
spacing: 8
Button { text: "Reload all"; onClicked: reloadAll() }
Button { text: "Stop all"; onClicked: stopAll() }
}
ListView {
clip: true
anchors {
top: allButtons.bottom;
left: parent.left;
right: parent.right;
topMargin: 8
bottom: row1.top
bottomMargin: 8
}
model: runningScriptsModel
delegate: Rectangle {
radius: 3
anchors { left: parent.left; right: parent.right }
height: scriptName.height + 12
color: index % 2 ? "#ddd" : "#eee"
Text {
anchors { left: parent.left; leftMargin: 4; verticalCenter: parent.verticalCenter }
id: scriptName
text: name
}
Row {
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 4
spacing: 4
HifiControls.FontAwesome {
text: "\uf021"; size: scriptName.height;
MouseArea {
anchors { fill: parent; margins: -2; }
onClicked: reloadScript(model.url)
}
}
HifiControls.FontAwesome {
size: scriptName.height; text: "\uf00d"
MouseArea {
anchors { fill: parent; margins: -2; }
onClicked: stopScript(model.url)
}
}
}
}
}
Text {
id: loadLabel
text: "Load Scripts"
font.bold: true
font.pointSize: 16
color: "#0e7077"
anchors.left: parent.left
anchors.leftMargin: 0
anchors.bottom: filterEdit.top
anchors.bottomMargin: 8
}
Row {
id: row1
spacing: 8
anchors.bottom: filterEdit.top
anchors.bottomMargin: 8
anchors.right: parent.right
Button { text: "from URL" }
Button { text: "from Disk" }
}
TextField {
id: filterEdit
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: treeView.top
anchors.bottomMargin: 8
placeholderText: "filter"
onTextChanged: scriptsModel.filterRegExp = new RegExp("^.*" + text + ".*$")
}
TreeView {
id: treeView
height: 128
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
headerVisible: false
focus: true
onClicked: {
console.log("treeview clicked " + scriptsModel.data(index, 0x100))
}
onDoubleClicked: {
console.log("treeview double clicked" + scriptsModel.data(index, 0x100))
isExpanded(index) ? collapse(index) : expand(index)
}
onActivated: {
console.log("treeview activated!" + index)
var path = scriptsModel.data(index, 0x100)
if (path) {
loadScript(path)
}
}
model: scriptsModel
TableViewColumn { title: "Name"; role: "display"; }
}
}
}
}

View file

@ -0,0 +1,93 @@
import QtQuick 2.5
import "."
import "../controls"
Frame {
id: root
anchors { margins: -16; topMargin: parent.closable ? -32 : -16; }
MouseArea {
id: controlsArea
anchors.fill: desktopControls
hoverEnabled: true
drag.target: root.parent
propagateComposedEvents: true
onClicked: {
root.raise()
mouse.accepted = false;
}
MouseArea {
id: sizeDrag
enabled: root.parent.resizable
property int startX
property int startY
anchors.right: parent.right
anchors.bottom: parent.bottom
width: 16
height: 16
z: 1000
hoverEnabled: true
onPressed: {
startX = mouseX
startY = mouseY
}
onPositionChanged: {
if (pressed) {
root.deltaSize((mouseX - startX), (mouseY - startY))
startX = mouseX
startY = mouseY
}
}
}
}
Rectangle {
id: desktopControls
// FIXME this doesn't work as expected
visible: root.parent.showFrame
anchors.fill: parent;
color: "#7f7f7f7f";
radius: 3;
Row {
anchors.right: parent.right
anchors.top: parent.top
anchors.rightMargin: 4
anchors.topMargin: 4
spacing: 4
FontAwesome {
visible: false
text: "\uf08d"
style: Text.Outline; styleColor: "white"
size: 16
rotation: !root.parent ? 90 : root.parent.pinned ? 0 : 90
color: root.pinned ? "red" : "black"
MouseArea {
anchors.fill: parent
propagateComposedEvents: true
onClicked: { root.pin(); mouse.accepted = false; }
}
}
FontAwesome {
visible: root.parent.closable
text: closeClickArea.containsMouse ? "\uf057" : "\uf05c"
style: Text.Outline;
styleColor: "white"
color: closeClickArea.containsMouse ? "red" : "black"
size: 16
MouseArea {
id: closeClickArea
anchors.fill: parent
hoverEnabled: true
onClicked: root.close();
}
}
}
}
}

View file

@ -0,0 +1,8 @@
import QtQuick 2.5
Item {
signal close()
signal pin()
signal raise()
signal deltaSize(real dx, real dy)
}

View file

@ -0,0 +1,181 @@
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtGraphicalEffects 1.0
import "."
import "../styles"
FocusScope {
id: window
objectName: "topLevelWindow"
HifiConstants { id: hifi }
implicitHeight: frame.height
implicitWidth: frame.width
property bool topLevelWindow: true
property string title
property bool showFrame: true
property bool closable: true
property bool destroyOnInvisible: false
property bool destroyOnCloseButton: true
property bool pinned: false
property bool resizable: false
property real minX: 320
property real minY: 240;
default property var content
property var frame: DefaultFrame { anchors.fill: content }
property var blur: FastBlur { anchors.fill: content; source: content; visible: false; radius: 0}
//property var hoverDetector: MouseArea { anchors.fill: frame; hoverEnabled: true; propagateComposedEvents: true; }
//property bool mouseInWindow: hoverDetector.containsMouse
children: [ frame, content, blur ]
signal windowDestroyed();
QtObject {
id: d
property vector2d minPosition: Qt.vector2d(0, 0);
property vector2d maxPosition: Qt.vector2d(100, 100);
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
function updateParentRect() {
// if (!frame) { return; }
// console.log(window.parent.width);
// console.log(frame.width);
// minPosition = Qt.vector2d(-frame.anchors.leftMargin, -frame.anchors.topMargin);
// maxPosition = Qt.vector2d(
// Math.max(minPosition.x, Desktop.width - frame.width + minPosition.x),
// Math.max(minPosition.y, Desktop.height - frame.height + minPosition.y))
// console.log(maxPosition);
}
function keepOnScreen() {
//window.x = clamp(x, minPosition.x, maxPosition.x);
//window.y = clamp(y, minPosition.y, maxPosition.y);
}
onMinPositionChanged: keepOnScreen();
onMaxPositionChanged: keepOnScreen();
}
Component.onCompleted: {
d.updateParentRect();
raise();
}
Component.onDestruction: {
console.log("Destroyed " + window);
windowDestroyed();
}
onParentChanged: {
d.updateParentRect();
raise();
}
onFrameChanged: d.updateParentRect();
onWidthChanged: d.updateParentRect();
onHeightChanged: d.updateParentRect();
onXChanged: d.keepOnScreen();
onYChanged: d.keepOnScreen();
Connections {
target: frame
onRaise: window.raise();
onClose: window.close();
onPin: window.pin();
onDeltaSize: {
console.log("deltaSize")
content.width = Math.max(content.width + dx, minX)
content.height = Math.max(content.height + dy, minY)
}
}
function raise() {
if (enabled && parent) {
Desktop.raise(window)
if (!focus) {
focus = true;
}
}
}
function pin() {
pinned = ! pinned
}
// our close function performs the same way as the OffscreenUI class:
// don't do anything but manipulate the enabled flag and let the other
// mechanisms decide if the window should be destroyed after the close
// animation completes
function close() {
if (destroyOnCloseButton) {
destroyOnInvisible = true
}
enabled = false;
}
onEnabledChanged: {
if (!enabled) {
if (blur) {
blur.visible = true;
}
if (content) {
content.visible = false;
}
}
opacity = enabled ? 1.0 : 0.0
// If the dialog is initially invisible, setting opacity doesn't
// trigger making it visible.
if (enabled) {
visible = true;
raise();
}
}
// The offscreen UI will enable an object, rather than manipulating it's
// visibility, so that we can do animations in both directions. Because
// visibility and enabled are boolean flags, they cannot be animated. So when
// enabled is change, we modify a property that can be animated, like scale or
// opacity, and then when the target animation value is reached, we can
// modify the visibility
// The actual animator
Behavior on opacity {
NumberAnimation {
duration: hifi.effects.fadeInDuration
easing.type: Easing.OutCubic
}
}
// Once we're transparent, disable the dialog's visibility
onOpacityChanged: {
visible = (opacity != 0.0);
if (opacity == 1.0) {
content.visible = true;
blur.visible = false;
}
}
// Some dialogs should be destroyed when they become
// invisible, so handle that
onVisibleChanged: {
if (!visible && destroyOnInvisible) {
console.log("Destroying " + window);
destroy();
}
}
Keys.onPressed: {
switch(event.key) {
case Qt.Key_W:
if (event.modifiers == Qt.ControlModifier) {
event.accepted = true
enabled = false
}
break;
}
}
}

View file

@ -1194,7 +1194,10 @@ void Application::initializeUi() {
offscreenUi->create(_offscreenContext->getContext());
offscreenUi->setProxyWindow(_window->windowHandle());
offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
offscreenUi->load("Root.qml");
// OffscreenUi is a subclass of OffscreenQmlSurface specifically designed to
// support the window management and scripting proxies for VR use
offscreenUi->createDesktop();
// FIXME either expose so that dialogs can set this themselves or
// do better detection in the offscreen UI of what has focus
offscreenUi->setNavigationFocused(false);
@ -1227,8 +1230,6 @@ void Application::initializeUi() {
#endif
rootContext->setContextProperty("Overlays", &_overlays);
rootContext->setContextProperty("Desktop", DependencyManager::get<DesktopScriptingInterface>().data());
rootContext->setContextProperty("Window", DependencyManager::get<WindowScriptingInterface>().data());
rootContext->setContextProperty("Menu", MenuScriptingInterface::getInstance());
rootContext->setContextProperty("Stats", Stats::getInstance());
@ -4530,18 +4531,20 @@ bool Application::displayAvatarAttachmentConfirmationDialog(const QString& name)
}
void Application::toggleRunningScriptsWidget() {
if (_runningScriptsWidget->isVisible()) {
if (_runningScriptsWidget->hasFocus()) {
_runningScriptsWidget->hide();
} else {
_runningScriptsWidget->raise();
setActiveWindow(_runningScriptsWidget);
_runningScriptsWidget->setFocus();
}
} else {
_runningScriptsWidget->show();
_runningScriptsWidget->setFocus();
}
static const QUrl url("dialogs/RunningScripts.qml");
DependencyManager::get<OffscreenUi>()->toggle(url, "RunningScripts");
//if (_runningScriptsWidget->isVisible()) {
// if (_runningScriptsWidget->hasFocus()) {
// _runningScriptsWidget->hide();
// } else {
// _runningScriptsWidget->raise();
// setActiveWindow(_runningScriptsWidget);
// _runningScriptsWidget->setFocus();
// }
//} else {
// _runningScriptsWidget->show();
// _runningScriptsWidget->setFocus();
//}
}
void Application::packageModel() {

View file

@ -61,7 +61,6 @@
#include "ui/OctreeStatsDialog.h"
#include "ui/OverlayConductor.h"
#include "ui/overlays/Overlays.h"
#include "ui/RunningScriptsWidget.h"
#include "ui/SnapshotShareDialog.h"
#include "ui/ToolWindow.h"
#include "UndoStackScriptingInterface.h"
@ -467,7 +466,6 @@ private:
TouchEvent _lastTouchEvent;
RunningScriptsWidget* _runningScriptsWidget { nullptr };
quint64 _lastNackTime;
quint64 _lastSendDownstreamAudioStats;

View file

@ -1,222 +0,0 @@
//
// RunningScriptsWidget.cpp
// interface/src/ui
//
// Created by Mohammed Nafees on 03/28/2014.
// Updated by Ryan Huffman on 05/13/2014.
// Copyright 2014 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
//
#include "ui_runningScriptsWidget.h"
#include "RunningScriptsWidget.h"
#include <QAbstractProxyModel>
#include <QFileInfo>
#include <QKeyEvent>
#include <QPainter>
#include <QScreen>
#include <QTableWidgetItem>
#include <QWindow>
#include <PathUtils.h>
#include <ScriptEngines.h>
#include "Application.h"
#include "MainWindow.h"
#include "Menu.h"
#include "ScriptsModel.h"
#include "UIUtil.h"
RunningScriptsWidget::RunningScriptsWidget(QWidget* parent) :
QWidget(parent, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint |
Qt::WindowCloseButtonHint),
ui(new Ui::RunningScriptsWidget),
_reloadSignalMapper(this),
_stopSignalMapper(this) {
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, false);
ui->filterLineEdit->installEventFilter(this);
auto scriptEngines = DependencyManager::get<ScriptEngines>().data();
connect(scriptEngines->scriptsModelFilter(), &QSortFilterProxyModel::modelReset,
this, &RunningScriptsWidget::selectFirstInList);
// FIXME: menu isn't prepared at this point.
//QString shortcutText = Menu::getInstance()->getActionForOption(MenuOption::ReloadAllScripts)->shortcut().toString(QKeySequence::NativeText);
//ui->tipLabel->setText("Tip: Use " + shortcutText + " to reload all scripts.");
ui->scriptTreeView->setModel(scriptEngines->scriptsModelFilter());
connect(ui->filterLineEdit, &QLineEdit::textChanged, this, &RunningScriptsWidget::updateFileFilter);
connect(ui->scriptTreeView, &QTreeView::doubleClicked, this, &RunningScriptsWidget::loadScriptFromList);
connect(ui->reloadAllButton, &QPushButton::clicked, scriptEngines, &ScriptEngines::reloadAllScripts);
connect(ui->stopAllButton, &QPushButton::clicked, scriptEngines, &ScriptEngines::stopAllScripts);
connect(ui->loadScriptFromDiskButton, &QPushButton::clicked, qApp, &Application::loadDialog);
connect(ui->loadScriptFromURLButton, &QPushButton::clicked, qApp, &Application::loadScriptURLDialog);
connect(&_reloadSignalMapper, static_cast<void(QSignalMapper::*)(const QString&)>(&QSignalMapper::mapped),
[scriptEngines](const QString& scriptName) { scriptEngines->stopScript(scriptName, true); });
connect(&_stopSignalMapper, static_cast<void(QSignalMapper::*)(const QString&)>(&QSignalMapper::mapped),
[scriptEngines](const QString& scriptName) { scriptEngines->stopScript(scriptName); });
setRunningScripts(scriptEngines->getRunningScripts());
connect(scriptEngines, &ScriptEngines::scriptCountChanged, scriptEngines, [this, scriptEngines] {
setRunningScripts(scriptEngines->getRunningScripts());
}, Qt::QueuedConnection);
UIUtil::scaleWidgetFontSizes(this);
}
RunningScriptsWidget::~RunningScriptsWidget() {
delete ui;
}
void RunningScriptsWidget::updateFileFilter(const QString& filter) {
QRegExp regex("^.*" + QRegExp::escape(filter) + ".*$", Qt::CaseInsensitive);
DependencyManager::get<ScriptEngines>()->scriptsModelFilter()->setFilterRegExp(regex);
selectFirstInList();
}
void RunningScriptsWidget::loadScriptFromList(const QModelIndex& index) {
auto scriptEngines = DependencyManager::get<ScriptEngines>();
QVariant scriptFile = scriptEngines->scriptsModelFilter()->data(index, ScriptsModel::ScriptPath);
scriptEngines->loadScript(scriptFile.toString());
}
void RunningScriptsWidget::loadSelectedScript() {
QModelIndex selectedIndex = ui->scriptTreeView->currentIndex();
if (selectedIndex.isValid()) {
loadScriptFromList(selectedIndex);
}
}
void RunningScriptsWidget::setRunningScripts(const QStringList& list) {
setUpdatesEnabled(false);
QLayoutItem* widget;
while ((widget = ui->scriptListWidget->layout()->takeAt(0)) != NULL) {
delete widget->widget();
delete widget;
}
QHash<QString, int> hash;
const int CLOSE_ICON_HEIGHT = 12;
for (int i = 0; i < list.size(); i++) {
if (!hash.contains(list.at(i))) {
hash.insert(list.at(i), 1);
}
QWidget* row = new QWidget(ui->scriptListWidget);
row->setFont(ui->scriptListWidget->font());
row->setLayout(new QHBoxLayout(row));
QUrl url = QUrl(list.at(i));
QLabel* name = new QLabel(url.fileName(), row);
if (hash.find(list.at(i)).value() != 1) {
name->setText(name->text() + "(" + QString::number(hash.find(list.at(i)).value()) + ")");
}
++hash[list.at(i)];
QPushButton* reloadButton = new QPushButton(row);
reloadButton->setFlat(true);
reloadButton->setIcon(
QIcon(QPixmap(PathUtils::resourcesPath() + "images/reload-script.svg").scaledToHeight(CLOSE_ICON_HEIGHT)));
reloadButton->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred));
reloadButton->setStyleSheet("border: 0;");
reloadButton->setCursor(Qt::PointingHandCursor);
connect(reloadButton, SIGNAL(clicked()), &_reloadSignalMapper, SLOT(map()));
_reloadSignalMapper.setMapping(reloadButton, url.toString());
QPushButton* closeButton = new QPushButton(row);
closeButton->setFlat(true);
closeButton->setIcon(
QIcon(QPixmap(PathUtils::resourcesPath() + "images/kill-script.svg").scaledToHeight(CLOSE_ICON_HEIGHT)));
closeButton->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred));
closeButton->setStyleSheet("border: 0;");
closeButton->setCursor(Qt::PointingHandCursor);
connect(closeButton, SIGNAL(clicked()), &_stopSignalMapper, SLOT(map()));
_stopSignalMapper.setMapping(closeButton, url.toString());
row->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
row->layout()->setContentsMargins(4, 4, 4, 4);
row->layout()->setSpacing(0);
row->layout()->addWidget(name);
row->layout()->addWidget(reloadButton);
row->layout()->addWidget(closeButton);
row->setToolTip(url.toString());
QFrame* line = new QFrame(row);
line->setFrameShape(QFrame::HLine);
line->setStyleSheet("color: #E1E1E1; margin-left: 6px; margin-right: 6px;");
ui->scriptListWidget->layout()->addWidget(row);
ui->scriptListWidget->layout()->addWidget(line);
}
ui->noRunningScriptsLabel->setVisible(list.isEmpty());
ui->reloadAllButton->setVisible(!list.isEmpty());
ui->stopAllButton->setVisible(!list.isEmpty());
ui->scriptListWidget->updateGeometry();
setUpdatesEnabled(true);
Application::processEvents();
repaint();
}
void RunningScriptsWidget::showEvent(QShowEvent* event) {
if (!event->spontaneous()) {
ui->filterLineEdit->setFocus();
}
QRect parentGeometry = qApp->getDesirableApplicationGeometry();
int titleBarHeight = UIUtil::getWindowTitleBarHeight(this);
int topMargin = titleBarHeight;
setGeometry(parentGeometry.topLeft().x(), parentGeometry.topLeft().y() + topMargin,
size().width(), parentWidget()->height() - topMargin);
QWidget::showEvent(event);
}
void RunningScriptsWidget::selectFirstInList() {
auto model = DependencyManager::get<ScriptEngines>()->scriptsModelFilter();
if (model->rowCount() > 0) {
ui->scriptTreeView->setCurrentIndex(model->index(0, 0));
}
}
bool RunningScriptsWidget::eventFilter(QObject* sender, QEvent* event) {
if (sender == ui->filterLineEdit) {
if (event->type() != QEvent::KeyPress) {
return false;
}
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
QModelIndex selectedIndex = ui->scriptTreeView->currentIndex();
if (selectedIndex.isValid()) {
loadScriptFromList(selectedIndex);
}
event->accept();
return true;
}
return false;
}
return QWidget::eventFilter(sender, event);
}
void RunningScriptsWidget::keyPressEvent(QKeyEvent *keyEvent) {
if (keyEvent->key() == Qt::Key_Escape) {
return;
} else {
QWidget::keyPressEvent(keyEvent);
}
}
void RunningScriptsWidget::allScriptsStopped() {
DependencyManager::get<ScriptEngines>()->stopAllScripts();
}

View file

@ -1,56 +0,0 @@
//
// RunningScriptsWidget.h
// interface/src/ui
//
// Created by Mohammed Nafees on 03/28/2014.
// Updated by Ryan Huffman on 05/13/2014.
// Copyright 2014 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
//
#ifndef hifi_RunningScriptsWidget_h
#define hifi_RunningScriptsWidget_h
#include <QFileSystemModel>
#include <QSignalMapper>
#include <QSortFilterProxyModel>
#include "ScriptsModel.h"
#include "ScriptsModelFilter.h"
#include "ScriptsTableWidget.h"
namespace Ui {
class RunningScriptsWidget;
}
class RunningScriptsWidget : public QWidget {
Q_OBJECT
public:
explicit RunningScriptsWidget(QWidget* parent = NULL);
~RunningScriptsWidget();
void setRunningScripts(const QStringList& list);
protected:
virtual bool eventFilter(QObject* sender, QEvent* event);
virtual void keyPressEvent(QKeyEvent* event);
virtual void showEvent(QShowEvent* event);
private slots:
void allScriptsStopped();
void updateFileFilter(const QString& filter);
void loadScriptFromList(const QModelIndex& index);
void loadSelectedScript();
void selectFirstInList();
private:
Ui::RunningScriptsWidget* ui;
QSignalMapper _reloadSignalMapper;
QSignalMapper _stopSignalMapper;
QVariantList getPublicChildNodes(TreeNodeFolder* parent);
};
#endif // hifi_RunningScriptsWidget_h

View file

@ -1,511 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RunningScriptsWidget</class>
<widget class="QWidget" name="RunningScriptsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>364</width>
<height>728</height>
</rect>
</property>
<property name="font">
<font>
<family>Helvetica,Arial,sans-serif</family>
<pointsize>13</pointsize>
</font>
</property>
<property name="windowTitle">
<string>Running Scripts</string>
</property>
<property name="styleSheet">
<string notr="true">* { font-family: Helvetica, Arial, sans-serif; }</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="3,2">
<item>
<widget class="QWidget" name="runningScriptsArea" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>141</height>
</size>
</property>
<property name="font">
<font>
<family>Helvetica,Arial,sans-serif</family>
<pointsize>13</pointsize>
</font>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="widget_3" native="true">
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="currentlyRunningLabel">
<property name="font">
<font>
<family>Helvetica,Arial,sans-serif</family>
<pointsize>16</pointsize>
<weight>75</weight>
<italic>false</italic>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">color: #0e7077;
font: bold 16pt;
</string>
</property>
<property name="text">
<string>Currently Running</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>4</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="reloadStopButtonArea" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Helvetica,Arial,sans-serif</family>
<pointsize>13</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">reloadStopButtonArea { padding: 0 }</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="reloadAllButton">
<property name="font">
<font>
<family>Helvetica,Arial,sans-serif</family>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>Reload all</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stopAllButton">
<property name="font">
<font>
<family>Helvetica,Arial,sans-serif</family>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>Stop all</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_4" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Helvetica,Arial,sans-serif</family>
<pointsize>13</pointsize>
</font>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="noRunningScriptsLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Helvetica,Arial,sans-serif</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">color: #5f5f5f; margin: 2px;</string>
</property>
<property name="text">
<string>There are no scripts running.</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="runningScriptsList">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Helvetica,Arial,sans-serif</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>328</width>
<height>18</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Helvetica,Arial,sans-serif</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="scriptListWidget" native="true">
<property name="font">
<font>
<family>Helvetica,Arial,sans-serif</family>
<pointsize>14</pointsize>
</font>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="quickLoadArea" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="styleSheet">
<string notr="true">color: #0e7077;
font: bold 16pt;</string>
</property>
<property name="text">
<string>Load Scripts</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="loadScriptFromURLButton">
<property name="text">
<string>from URL</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="loadScriptFromDiskButton">
<property name="text">
<string>from Disk</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLineEdit" name="filterLineEdit">
<property name="text">
<string/>
</property>
<property name="placeholderText">
<string>filter</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTreeView" name="scriptTreeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="rootIsDecorated">
<bool>true</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -16,19 +16,14 @@
#include <AbstractUriHandler.h>
#include <AccountManager.h>
#include "ErrorDialog.h"
#include "MessageDialog.h"
class OffscreenUiRoot : public QQuickItem {
Q_OBJECT
public:
OffscreenUiRoot(QQuickItem* parent = 0);
Q_INVOKABLE void information(const QString& title, const QString& text);
Q_INVOKABLE void loadChild(const QUrl& url) {
DependencyManager::get<OffscreenUi>()->load(url);
}
};
// Needs to match the constants in resources/qml/Global.js
static const QString OFFSCREEN_ROOT_OBJECT_NAME = "desktopRoot";
static const QString OFFSCREEN_WINDOW_OBJECT_NAME = "topLevelWindow";
static QQuickItem* _desktop { nullptr };
class OffscreenFlags : public QObject {
Q_OBJECT
@ -105,15 +100,7 @@ bool OffscreenUi::shouldSwallowShortcut(QEvent* event) {
return false;
}
OffscreenUiRoot::OffscreenUiRoot(QQuickItem* parent) : QQuickItem(parent) {
}
void OffscreenUiRoot::information(const QString& title, const QString& text) {
OffscreenUi::information(title, text);
}
OffscreenUi::OffscreenUi() {
::qmlRegisterType<OffscreenUiRoot>("Hifi", 1, 0, "Root");
}
void OffscreenUi::create(QOpenGLContext* context) {
@ -258,4 +245,13 @@ void OffscreenUi::setNavigationFocused(bool focused) {
offscreenFlags->setNavigationFocused(focused);
}
void OffscreenUi::createDesktop() {
if (_desktop) {
qDebug() << "Desktop already created";
}
_desktop = dynamic_cast<QQuickItem*>(load("Root.qml"));
Q_ASSERT(_desktop);
getRootContext()->setContextProperty("Desktop", _desktop);
}
#include "OffscreenUi.moc"

View file

@ -26,6 +26,7 @@ class OffscreenUi : public OffscreenQmlSurface, public Dependency {
public:
OffscreenUi();
virtual void create(QOpenGLContext* context) override;
void createDesktop();
void show(const QUrl& url, const QString& name, std::function<void(QQmlContext*, QObject*)> f = [](QQmlContext*, QObject*) {});
void toggle(const QUrl& url, const QString& name, std::function<void(QQmlContext*, QObject*)> f = [](QQmlContext*, QObject*) {});
bool shouldSwallowShortcut(QEvent* event);

View file

@ -91,7 +91,7 @@ QScriptValue QmlWindowClass::internalConstructor(const QString& qmlSource,
const auto argumentCount = context->argumentCount();
QString url;
QString title;
int width = 100, height = 100;
int width = -1, height = -1;
bool visible = true;
if (argumentCount > 1) {
@ -131,13 +131,19 @@ QScriptValue QmlWindowClass::internalConstructor(const QString& qmlSource,
url = QUrl::fromLocalFile(url).toString();
}
width = std::max(100, std::min(1280, width));
height = std::max(100, std::min(720, height));
if (width != -1 || height != -1) {
width = std::max(100, std::min(1280, width));
height = std::max(100, std::min(720, height));
}
QmlWindowClass* retVal{ nullptr };
auto offscreenUi = DependencyManager::get<OffscreenUi>();
qDebug() << "Clearing component cache";
offscreenUi->getRootContext()->engine()->clearComponentCache();
// Build the event bridge and wrapper on the main thread
QMetaObject::invokeMethod(DependencyManager::get<OffscreenUi>().data(), "load", Qt::BlockingQueuedConnection,
QMetaObject::invokeMethod(offscreenUi.data(), "load", Qt::BlockingQueuedConnection,
Q_ARG(const QString&, qmlSource),
Q_ARG(std::function<void(QQmlContext*, QObject*)>, [&](QQmlContext* context, QObject* object) {
setupServer();
@ -147,7 +153,9 @@ QScriptValue QmlWindowClass::internalConstructor(const QString& qmlSource,
if (!title.isEmpty()) {
retVal->setTitle(title);
}
retVal->setSize(width, height);
if (width != -1 && height != -1) {
retVal->setSize(width, height);
}
object->setProperty(SOURCE_PROPERTY, url);
if (visible) {
object->setProperty("enabled", true);