diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 48b395339e..6c4426b2c6 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -4,22 +4,22 @@ Application - + Export Voxels - + Sparse Voxel Octree Files (*.svo) - + Open Script - + JavaScript Files (*.js) @@ -113,18 +113,18 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file @@ -271,4 +271,57 @@ + + RunningScriptsWidget + + + + Form + + + + + + <html><head/><body><p><span style=" font-size:18pt;">Running Scripts</span></p></body></html> + + + + + + <html><head/><body><p><span style=" font-weight:600;">Currently running</span></p></body></html> + + + + + + Reload all + Reload All + + + + + + Stop all + Stop All + + + + + + <html><head/><body><p><span style=" font-weight:600;">Recently loaded</span></p></body></html> + + + + + + (click a script or use the 1-9 keys to load and run it) + + + + + + There are no scripts currently running. + + + diff --git a/interface/resources/images/plus-white.svg b/interface/resources/images/plus-white.svg new file mode 100644 index 0000000000..8bd089881e --- /dev/null +++ b/interface/resources/images/plus-white.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7019788811..9be14edb0f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -132,7 +131,7 @@ QString& Application::resourcesPath() { Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : QApplication(argc, argv), - _window(new QMainWindow(desktop())), + _window(new MainWindow(desktop())), _glWidget(new GLCanvas()), _nodeThread(new QThread(this)), _datagramProcessor(), @@ -164,7 +163,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _packetsPerSecond(0), _bytesPerSecond(0), _previousScriptLocation(), - _logger(new FileLogger(this)) + _logger(new FileLogger(this)), + _runningScriptsWidget(new RunningScriptsWidget(_window)), + _runningScriptsWidgetWasVisible(false) { // init GnuTLS for DTLS with domain-servers DTLSClientSession::globalInit(); @@ -334,7 +335,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : LocalVoxelsList::getInstance()->addPersistantTree(DOMAIN_TREE_NAME, _voxels.getTree()); LocalVoxelsList::getInstance()->addPersistantTree(CLIPBOARD_TREE_NAME, &_clipboard); - _window->addDockWidget(Qt::NoDockWidgetArea, _runningScriptsWidget = new RunningScriptsWidget()); _runningScriptsWidget->setRunningScripts(getRunningScripts()); connect(_runningScriptsWidget, &RunningScriptsWidget::stopScriptName, this, &Application::stopScript); @@ -355,6 +355,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : QMutexLocker locker(&_settingsMutex); _previousScriptLocation = _settings->value("LastScriptLocation", QVariant("")).toString(); } + + connect(_window, &MainWindow::windowGeometryChanged, + _runningScriptsWidget, &RunningScriptsWidget::setBoundary); + + //When -url in command line, teleport to location + urlGoTo(argc, constArgv); } Application::~Application() { @@ -2631,7 +2637,6 @@ void Application::displayOverlay() { if (audioLevel > AUDIO_METER_SCALE_WIDTH) { audioLevel = AUDIO_METER_SCALE_WIDTH; } - bool isClipping = ((_audio.getTimeSinceLastClip() > 0.f) && (_audio.getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME)); if ((_audio.getTimeSinceLastClip() > 0.f) && (_audio.getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME)) { @@ -3326,31 +3331,23 @@ void Application::reloadAllScripts() { } } -void Application::toggleRunningScriptsWidget() -{ - if (!_runningScriptsWidget->toggleViewAction()->isChecked()) { - _runningScriptsWidget->move(_window->geometry().topLeft().x(), _window->geometry().topLeft().y()); - _runningScriptsWidget->resize(0, _window->height()); - _runningScriptsWidget->toggleViewAction()->trigger(); - _runningScriptsWidget->grabKeyboard(); +void Application::manageRunningScriptsWidgetVisibility(bool shown) { + if (_runningScriptsWidgetWasVisible && shown) { + _runningScriptsWidget->show(); + } else if (_runningScriptsWidgetWasVisible && !shown) { + _runningScriptsWidget->hide(); + } +} - QPropertyAnimation* slideAnimation = new QPropertyAnimation(_runningScriptsWidget, "geometry", _runningScriptsWidget); - slideAnimation->setStartValue(_runningScriptsWidget->geometry()); - slideAnimation->setEndValue(QRect(_window->geometry().topLeft().x(), _window->geometry().topLeft().y(), - 310, _runningScriptsWidget->height())); - slideAnimation->setDuration(250); - slideAnimation->start(QAbstractAnimation::DeleteWhenStopped); +void Application::toggleRunningScriptsWidget() { + if (_runningScriptsWidgetWasVisible) { + _runningScriptsWidget->hide(); + _runningScriptsWidgetWasVisible = false; } else { - _runningScriptsWidget->releaseKeyboard(); - - QPropertyAnimation* slideAnimation = new QPropertyAnimation(_runningScriptsWidget, "geometry", _runningScriptsWidget); - slideAnimation->setStartValue(_runningScriptsWidget->geometry()); - slideAnimation->setEndValue(QRect(_window->geometry().topLeft().x(), _window->geometry().topLeft().y(), - 0, _runningScriptsWidget->height())); - slideAnimation->setDuration(250); - slideAnimation->start(QAbstractAnimation::DeleteWhenStopped); - - QTimer::singleShot(260, _runningScriptsWidget->toggleViewAction(), SLOT(trigger())); + _runningScriptsWidget->setBoundary(QRect(_window->geometry().topLeft(), + _window->size())); + _runningScriptsWidget->show(); + _runningScriptsWidgetWasVisible = true; } } diff --git a/interface/src/Application.h b/interface/src/Application.h index 09971990b8..fb15019c19 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,7 @@ #include #include +#include "MainWindow.h" #include "Audio.h" #include "AudioReflector.h" #include "BuckyBalls.h" @@ -85,7 +87,6 @@ class QAction; class QActionGroup; class QGLWidget; class QKeyEvent; -class QMainWindow; class QMouseEvent; class QNetworkAccessManager; class QSettings; @@ -138,6 +139,7 @@ public: void keyReleaseEvent(QKeyEvent* event); void focusOutEvent(QFocusEvent* event); + void focusInEvent(QFocusEvent* event); void mouseMoveEvent(QMouseEvent* event); void mousePressEvent(QMouseEvent* event); @@ -194,10 +196,10 @@ public: /// if you need to access the application settings, use lockSettings()/unlockSettings() QSettings* lockSettings() { _settingsMutex.lock(); return _settings; } void unlockSettings() { _settingsMutex.unlock(); } - + void saveSettings(); - QMainWindow* getWindow() { return _window; } + MainWindow* getWindow() { return _window; } NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; } void lockOctreeSceneStats() { _octreeSceneStatsLock.lockForRead(); } void unlockOctreeSceneStats() { _octreeSceneStatsLock.unlock(); } @@ -314,6 +316,8 @@ private slots: void parseVersionXml(); + void manageRunningScriptsWidgetVisibility(bool shown); + private: void resetCamerasOnResizeGL(Camera& camera, int width, int height); void updateProjectionMatrix(); @@ -374,7 +378,7 @@ private: void displayRearMirrorTools(); - QMainWindow* _window; + MainWindow* _window; GLCanvas* _glWidget; // our GLCanvas has a couple extra features BandwidthMeter _bandwidthMeter; @@ -388,7 +392,7 @@ private: int _numChangedSettings; QUndoStack _undoStack; - + glm::vec3 _gravity; // Frame Rate Measurement @@ -433,7 +437,7 @@ private: Faceplus _faceplus; Faceshift _faceshift; Visage _visage; - + SixenseManager _sixenseManager; Camera _myCamera; // My view onto the world @@ -521,9 +525,11 @@ private: TouchEvent _lastTouchEvent; Overlays _overlays; + AudioReflector _audioReflector; RunningScriptsWidget* _runningScriptsWidget; QHash _scriptEnginesHash; + bool _runningScriptsWidgetWasVisible; }; #endif // hifi_Application_h diff --git a/interface/src/GLCanvas.cpp b/interface/src/GLCanvas.cpp index 9f1bf303fa..49085e63df 100644 --- a/interface/src/GLCanvas.cpp +++ b/interface/src/GLCanvas.cpp @@ -24,8 +24,8 @@ GLCanvas::GLCanvas() : QGLWidget(QGLFormat(QGL::NoDepthBuffer)), { } -bool GLCanvas::isThrottleRendering() const { - return _throttleRendering || Application::getInstance()->getWindow()->isMinimized(); +bool GLCanvas::isThrottleRendering() const { + return _throttleRendering || Application::getInstance()->getWindow()->isMinimized(); } void GLCanvas::initializeGL() { @@ -34,7 +34,7 @@ void GLCanvas::initializeGL() { setAcceptDrops(true); connect(Application::getInstance(), SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(activeChanged(Qt::ApplicationState))); connect(&_frameTimer, SIGNAL(timeout()), this, SLOT(throttleRender())); - + // Note, we *DO NOT* want Qt to automatically swap buffers for us. This results in the "ringing" bug mentioned in WL#19514 when we're throttling the framerate. setAutoBufferSwap(false); } @@ -81,14 +81,14 @@ void GLCanvas::activeChanged(Qt::ApplicationState state) { _frameTimer.stop(); _throttleRendering = false; break; - + case Qt::ApplicationSuspended: case Qt::ApplicationHidden: // If we're hidden or are about to suspend, don't render anything. _throttleRendering = false; _frameTimer.stop(); break; - + default: // Otherwise, throttle. if (!_throttleRendering) { diff --git a/interface/src/GLCanvas.h b/interface/src/GLCanvas.h index 73b70de19e..024cd615ae 100644 --- a/interface/src/GLCanvas.h +++ b/interface/src/GLCanvas.h @@ -22,31 +22,31 @@ public: GLCanvas(); bool isThrottleRendering() const; protected: - + QTimer _frameTimer; bool _throttleRendering; int _idleRenderInterval; - + virtual void initializeGL(); virtual void paintGL(); virtual void resizeGL(int width, int height); - + virtual void keyPressEvent(QKeyEvent* event); virtual void keyReleaseEvent(QKeyEvent* event); - + virtual void focusOutEvent(QFocusEvent* event); - + virtual void mouseMoveEvent(QMouseEvent* event); virtual void mousePressEvent(QMouseEvent* event); virtual void mouseReleaseEvent(QMouseEvent* event); - + virtual bool event(QEvent* event); - + virtual void wheelEvent(QWheelEvent* event); virtual void dragEnterEvent(QDragEnterEvent *event); virtual void dropEvent(QDropEvent* event); - + private slots: void activeChanged(Qt::ApplicationState state); void throttleRender(); diff --git a/interface/src/MainWindow.cpp b/interface/src/MainWindow.cpp new file mode 100644 index 0000000000..7fddbfffa3 --- /dev/null +++ b/interface/src/MainWindow.cpp @@ -0,0 +1,67 @@ +// +// MainWindow.cpp +// interface +// +// Created by Mohammed Nafees on 04/06/2014. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "MainWindow.h" + +#include +#include +#include +#include +#include +#include + +MainWindow::MainWindow(QWidget* parent) : + QMainWindow(parent) { +} + +void MainWindow::moveEvent(QMoveEvent* event) { + emit windowGeometryChanged(QRect(event->pos(), size())); + QMainWindow::moveEvent(event); +} + +void MainWindow::resizeEvent(QResizeEvent* event) { + emit windowGeometryChanged(QRect(QPoint(x(), y()), event->size())); + QMainWindow::resizeEvent(event); +} + +void MainWindow::showEvent(QShowEvent* event) { + if (event->spontaneous()) { + emit windowShown(true); + } + QMainWindow::showEvent(event); +} + +void MainWindow::hideEvent(QHideEvent* event) { + if (event->spontaneous()) { + emit windowShown(false); + } + QMainWindow::hideEvent(event); +} + +void MainWindow::changeEvent(QEvent* event) { + if (event->type() == QEvent::WindowStateChange) { + QWindowStateChangeEvent* stateChangeEvent = static_cast(event); + if ((stateChangeEvent->oldState() == Qt::WindowNoState || + stateChangeEvent->oldState() == Qt::WindowMaximized) && + windowState() == Qt::WindowMinimized) { + emit windowShown(false); + } else { + emit windowShown(true); + } + } else if (event->type() == QEvent::ActivationChange) { + if (isActiveWindow()) { + emit windowShown(true); + } else { + emit windowShown(false); + } + } + QMainWindow::changeEvent(event); +} diff --git a/interface/src/MainWindow.h b/interface/src/MainWindow.h new file mode 100644 index 0000000000..603194e9be --- /dev/null +++ b/interface/src/MainWindow.h @@ -0,0 +1,35 @@ +// +// MainWindow.h +// interface +// +// Created by Mohammed Nafees on 04/06/2014. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// +// 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__MainWindow__ +#define __hifi__MainWindow__ + +#include + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + explicit MainWindow(QWidget* parent = NULL); + +signals: + void windowGeometryChanged(QRect geometry); + void windowShown(bool shown); + +protected: + virtual void moveEvent(QMoveEvent* event); + virtual void resizeEvent(QResizeEvent* event); + virtual void showEvent(QShowEvent* event); + virtual void hideEvent(QHideEvent* event); + virtual void changeEvent(QEvent* event); +}; + +#endif /* defined(__hifi__MainWindow__) */ diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 59da23dc88..e194734928 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -170,12 +170,12 @@ Menu::Menu() : QMenu* editMenu = addMenu("Edit"); - + QUndoStack* undoStack = Application::getInstance()->getUndoStack(); QAction* undoAction = undoStack->createUndoAction(editMenu); undoAction->setShortcut(Qt::CTRL | Qt::Key_Z); addActionToQMenuAndActionHash(editMenu, undoAction); - + QAction* redoAction = undoStack->createRedoAction(editMenu); redoAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_Z); addActionToQMenuAndActionHash(editMenu, redoAction); @@ -321,7 +321,7 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Visage, 0, true, appInstance->getVisage(), SLOT(updateEnabled())); #endif - + addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::GlowWhenSpeaking, 0, true); addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::ChatCircling, 0, false); @@ -724,31 +724,31 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu, QAction::MenuRole role, int menuItemLocation) { QAction* actionBefore = NULL; - + if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) { actionBefore = destinationMenu->actions()[menuItemLocation]; } - + if (!actionName.isEmpty()) { action->setText(actionName); } - + if (shortcut != 0) { action->setShortcut(shortcut); } - + if (role != QAction::NoRole) { action->setMenuRole(role); } - + if (!actionBefore) { destinationMenu->addAction(action); } else { destinationMenu->insertAction(actionBefore, action); } - + _actionHash.insert(action->text(), action); - + return action; } @@ -814,7 +814,6 @@ void sendFakeEnterEvent() { QCoreApplication::sendEvent(glWidget, &enterEvent); } -const int QLINE_MINIMUM_WIDTH = 400; const float DIALOG_RATIO_OF_WINDOW = 0.30f; void Menu::loginForCurrentDomain() { @@ -920,7 +919,7 @@ void Menu::goTo() { QString orientation = urlParts.count() > 2 ? urlParts[2] : QString(); goToDomain(domain); - + // goto either @user, #place, or x-xx,y-yy,z-zz // style co-ordinate. goTo(destination); @@ -1246,7 +1245,7 @@ void Menu::autoAdjustLOD(float currentFPS) { _avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE); } } - + bool changed = false; quint64 elapsed = now - _lastAdjust; diff --git a/interface/src/Menu.h b/interface/src/Menu.h index bbd3aa13ae..967312dca9 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -30,7 +30,7 @@ const float ADJUST_LOD_DOWN_FPS = 40.0; const float ADJUST_LOD_UP_FPS = 55.0; -const float DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS = 30.0f; +const float DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS = 30.0f; const quint64 ADJUST_LOD_DOWN_DELAY = 1000 * 1000 * 5; const quint64 ADJUST_LOD_UP_DELAY = ADJUST_LOD_DOWN_DELAY * 2; @@ -79,7 +79,7 @@ public: void triggerOption(const QString& menuOption); QAction* getActionForOption(const QString& menuOption); - + float getAudioJitterBufferSamples() const { return _audioJitterBufferSamples; } void setAudioJitterBufferSamples(float audioJitterBufferSamples) { _audioJitterBufferSamples = audioJitterBufferSamples; } float getFieldOfView() const { return _fieldOfView; } @@ -133,7 +133,7 @@ public: const QKeySequence& shortcut = 0, QAction::MenuRole role = QAction::NoRole, int menuItemLocation = UNSPECIFIED_POSITION); - + void removeAction(QMenu* menu, const QString& actionName); bool static goToDestination(QString destination); @@ -276,8 +276,8 @@ namespace MenuOption { const QString AudioSpatialProcessingWithDiffusions = "With Diffusions"; const QString AudioSpatialProcessingDontDistanceAttenuate = "Don't calculate distance attenuation"; const QString AudioSpatialProcessingAlternateDistanceAttenuate = "Alternate distance attenuation"; - - + + const QString Avatars = "Avatars"; const QString Bandwidth = "Bandwidth Display"; diff --git a/interface/src/ui/FramelessDialog.cpp b/interface/src/ui/FramelessDialog.cpp index 71c58078d2..22a0233d76 100644 --- a/interface/src/ui/FramelessDialog.cpp +++ b/interface/src/ui/FramelessDialog.cpp @@ -16,6 +16,7 @@ const int RESIZE_HANDLE_WIDTH = 7; FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags, Position position) : QDialog(parent, flags | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint), + _allowResize(true), _isResizing(false), _resizeInitialWidth(0), _selfHidden(false), @@ -114,7 +115,7 @@ void FramelessDialog::resizeAndPosition(bool resizeParent) { } void FramelessDialog::mousePressEvent(QMouseEvent* mouseEvent) { - if (mouseEvent->button() == Qt::LeftButton) { + if (_allowResize && mouseEvent->button() == Qt::LeftButton) { if (_position == POSITION_LEFT || _position == POSITION_RIGHT) { bool hitLeft = (_position == POSITION_LEFT) && (abs(mouseEvent->pos().x() - size().width()) < RESIZE_HANDLE_WIDTH); bool hitRight = (_position == POSITION_RIGHT) && (mouseEvent->pos().x() < RESIZE_HANDLE_WIDTH); diff --git a/interface/src/ui/FramelessDialog.h b/interface/src/ui/FramelessDialog.h index 2265f3c9e4..32451f746d 100644 --- a/interface/src/ui/FramelessDialog.h +++ b/interface/src/ui/FramelessDialog.h @@ -23,8 +23,10 @@ public: FramelessDialog(QWidget* parent, Qt::WindowFlags flags = 0, Position position = POSITION_LEFT); void setStyleSheetFile(const QString& fileName); - void setHideOnBlur(bool hideOnBlur) { _hideOnBlur = hideOnBlur; }; - bool getHideOnBlur() { return _hideOnBlur; }; + void setAllowResize(bool allowResize) { _allowResize = allowResize; } + bool getAllowResize() { return _allowResize; } + void setHideOnBlur(bool hideOnBlur) { _hideOnBlur = hideOnBlur; } + bool getHideOnBlur() { return _hideOnBlur; } void resizeAndPosition(bool resizeParent = true); protected: @@ -36,6 +38,7 @@ protected: bool eventFilter(QObject* sender, QEvent* event); private: + bool _allowResize; bool _isResizing; int _resizeInitialWidth; bool _selfHidden; ///< true when the dialog itself because of a window event (deactivation or minimization) diff --git a/interface/src/ui/RunningScriptsWidget.cpp b/interface/src/ui/RunningScriptsWidget.cpp index 9a9a1c7486..61241f71fb 100644 --- a/interface/src/ui/RunningScriptsWidget.cpp +++ b/interface/src/ui/RunningScriptsWidget.cpp @@ -12,39 +12,35 @@ #include "ui_runningScriptsWidget.h" #include "RunningScriptsWidget.h" +#include #include +#include #include #include "Application.h" -RunningScriptsWidget::RunningScriptsWidget(QDockWidget *parent) : - QDockWidget(parent), - ui(new Ui::RunningScriptsWidget) -{ +RunningScriptsWidget::RunningScriptsWidget(QWidget* parent) : + FramelessDialog(parent, 0, POSITION_LEFT), + ui(new Ui::RunningScriptsWidget) { ui->setupUi(this); - // remove the title bar (see the Qt docs on setTitleBarWidget) - setTitleBarWidget(new QWidget()); + setAllowResize(false); - ui->runningScriptsTableWidget->setColumnCount(2); - ui->runningScriptsTableWidget->verticalHeader()->setVisible(false); - ui->runningScriptsTableWidget->horizontalHeader()->setVisible(false); - ui->runningScriptsTableWidget->setSelectionMode(QAbstractItemView::NoSelection); - ui->runningScriptsTableWidget->setShowGrid(false); - ui->runningScriptsTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); - ui->runningScriptsTableWidget->setColumnWidth(0, 235); - ui->runningScriptsTableWidget->setColumnWidth(1, 25); - connect(ui->runningScriptsTableWidget, &QTableWidget::cellClicked, this, &RunningScriptsWidget::stopScript); + ui->hideWidgetButton->setIcon(QIcon(Application::resourcesPath() + "images/close.svg")); + ui->reloadAllButton->setIcon(QIcon(Application::resourcesPath() + "images/reload.svg")); + ui->stopAllButton->setIcon(QIcon(Application::resourcesPath() + "images/stop.svg")); + ui->loadScriptButton->setIcon(QIcon(Application::resourcesPath() + "images/plus-white.svg")); - ui->recentlyLoadedScriptsTableWidget->setColumnCount(2); - ui->recentlyLoadedScriptsTableWidget->verticalHeader()->setVisible(false); - ui->recentlyLoadedScriptsTableWidget->horizontalHeader()->setVisible(false); - ui->recentlyLoadedScriptsTableWidget->setSelectionMode(QAbstractItemView::NoSelection); - ui->recentlyLoadedScriptsTableWidget->setShowGrid(false); - ui->recentlyLoadedScriptsTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); - ui->recentlyLoadedScriptsTableWidget->setColumnWidth(0, 25); - ui->recentlyLoadedScriptsTableWidget->setColumnWidth(1, 235); - connect(ui->recentlyLoadedScriptsTableWidget, &QTableWidget::cellClicked, + _runningScriptsTable = new ScriptsTableWidget(ui->runningScriptsTableWidget); + _runningScriptsTable->setColumnCount(2); + _runningScriptsTable->setColumnWidth(0, 245); + _runningScriptsTable->setColumnWidth(1, 22); + connect(_runningScriptsTable, &QTableWidget::cellClicked, this, &RunningScriptsWidget::stopScript); + + _recentlyLoadedScriptsTable = new ScriptsTableWidget(ui->recentlyLoadedScriptsTableWidget); + _recentlyLoadedScriptsTable->setColumnCount(1); + _recentlyLoadedScriptsTable->setColumnWidth(0, 265); + connect(_recentlyLoadedScriptsTable, &QTableWidget::cellClicked, this, &RunningScriptsWidget::loadScript); connect(ui->hideWidgetButton, &QPushButton::clicked, @@ -53,118 +49,126 @@ RunningScriptsWidget::RunningScriptsWidget(QDockWidget *parent) : Application::getInstance(), &Application::reloadAllScripts); connect(ui->stopAllButton, &QPushButton::clicked, this, &RunningScriptsWidget::allScriptsStopped); + connect(ui->loadScriptButton, &QPushButton::clicked, + Application::getInstance(), &Application::loadDialog); } -RunningScriptsWidget::~RunningScriptsWidget() -{ +RunningScriptsWidget::~RunningScriptsWidget() { delete ui; } -void RunningScriptsWidget::setRunningScripts(const QStringList& list) -{ - ui->runningScriptsTableWidget->setRowCount(list.size()); +void RunningScriptsWidget::setBoundary(const QRect& rect) { + _boundary = rect; +} + +void RunningScriptsWidget::setRunningScripts(const QStringList& list) { + _runningScriptsTable->setRowCount(list.size()); ui->noRunningScriptsLabel->setVisible(list.isEmpty()); ui->currentlyRunningLabel->setVisible(!list.isEmpty()); - ui->line1->setVisible(!list.isEmpty()); ui->runningScriptsTableWidget->setVisible(!list.isEmpty()); ui->reloadAllButton->setVisible(!list.isEmpty()); ui->stopAllButton->setVisible(!list.isEmpty()); + const int CLOSE_ICON_HEIGHT = 12; + for (int i = 0; i < list.size(); ++i) { QTableWidgetItem *scriptName = new QTableWidgetItem; - scriptName->setText(list.at(i)); + scriptName->setText(QFileInfo(list.at(i)).fileName()); scriptName->setToolTip(list.at(i)); - scriptName->setTextAlignment(Qt::AlignCenter); + scriptName->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); QTableWidgetItem *closeIcon = new QTableWidgetItem; - closeIcon->setIcon(QIcon(Application::resourcesPath() + "/images/kill-script.svg")); + closeIcon->setIcon(QIcon(QPixmap(Application::resourcesPath() + "images/kill-script.svg").scaledToHeight(CLOSE_ICON_HEIGHT))); - ui->runningScriptsTableWidget->setItem(i, 0, scriptName); - ui->runningScriptsTableWidget->setItem(i, 1, closeIcon); + _runningScriptsTable->setItem(i, 0, scriptName); + _runningScriptsTable->setItem(i, 1, closeIcon); } + const int RUNNING_SCRIPTS_TABLE_LEFT_MARGIN = 12; + const int RECENTLY_LOADED_TOP_MARGIN = 61; + const int RECENTLY_LOADED_LABEL_TOP_MARGIN = 19; + + int y = ui->runningScriptsTableWidget->y() + RUNNING_SCRIPTS_TABLE_LEFT_MARGIN; + for (int i = 0; i < _runningScriptsTable->rowCount(); ++i) { + y += _runningScriptsTable->rowHeight(i); + } + + ui->runningScriptsTableWidget->resize(ui->runningScriptsTableWidget->width(), y - RUNNING_SCRIPTS_TABLE_LEFT_MARGIN); + _runningScriptsTable->resize(_runningScriptsTable->width(), y - RUNNING_SCRIPTS_TABLE_LEFT_MARGIN); + ui->reloadAllButton->move(ui->reloadAllButton->x(), y); + ui->stopAllButton->move(ui->stopAllButton->x(), y); + ui->recentlyLoadedLabel->move(ui->recentlyLoadedLabel->x(), + ui->stopAllButton->y() + ui->stopAllButton->height() + RECENTLY_LOADED_TOP_MARGIN); + ui->recentlyLoadedScriptsTableWidget->move(ui->recentlyLoadedScriptsTableWidget->x(), + ui->recentlyLoadedLabel->y() + RECENTLY_LOADED_LABEL_TOP_MARGIN); + + createRecentlyLoadedScriptsTable(); } -void RunningScriptsWidget::keyPressEvent(QKeyEvent *e) +void RunningScriptsWidget::keyPressEvent(QKeyEvent* event) { - switch(e->key()) { + int loadScriptNumber = -1; + switch(event->key()) { case Qt::Key_Escape: Application::getInstance()->toggleRunningScriptsWidget(); break; case Qt::Key_1: - if (_recentlyLoadedScripts.size() > 0) { - Application::getInstance()->loadScript(_recentlyLoadedScripts.at(0)); - } - break; - case Qt::Key_2: - if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 2) { - Application::getInstance()->loadScript(_recentlyLoadedScripts.at(1)); - } - break; - case Qt::Key_3: - if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 3) { - Application::getInstance()->loadScript(_recentlyLoadedScripts.at(2)); - } - break; - case Qt::Key_4: - if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 4) { - Application::getInstance()->loadScript(_recentlyLoadedScripts.at(3)); - } - break; case Qt::Key_5: - if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 5) { - Application::getInstance()->loadScript(_recentlyLoadedScripts.at(4)); - } - break; - case Qt::Key_6: - if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 6) { - Application::getInstance()->loadScript(_recentlyLoadedScripts.at(5)); - } - break; - case Qt::Key_7: - if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 7) { - Application::getInstance()->loadScript(_recentlyLoadedScripts.at(6)); - } - break; case Qt::Key_8: - if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 8) { - Application::getInstance()->loadScript(_recentlyLoadedScripts.at(7)); - } - break; - case Qt::Key_9: - if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 9) { - Application::getInstance()->loadScript(_recentlyLoadedScripts.at(8)); - } + loadScriptNumber = event->key() - Qt::Key_1; break; default: break; } + if (loadScriptNumber >= 0) { + if (_recentlyLoadedScripts.size() > loadScriptNumber) { + Application::getInstance()->loadScript(_recentlyLoadedScripts.at(loadScriptNumber)); + } + } + + FramelessDialog::keyPressEvent(event); } -void RunningScriptsWidget::stopScript(int row, int column) -{ +void RunningScriptsWidget::paintEvent(QPaintEvent* event) { + QPainter painter(this); + painter.setPen(QColor::fromRgb(225, 225, 225)); // #e1e1e1 + + if (ui->currentlyRunningLabel->isVisible()) { + // line below the 'Currently Running' label + painter.drawLine(36, ui->currentlyRunningLabel->y() + ui->currentlyRunningLabel->height(), + 300, ui->currentlyRunningLabel->y() + ui->currentlyRunningLabel->height()); + } + + if (ui->recentlyLoadedLabel->isVisible()) { + // line below the 'Recently loaded' label + painter.drawLine(36, ui->recentlyLoadedLabel->y() + ui->recentlyLoadedLabel->height(), + 300, ui->recentlyLoadedLabel->y() + ui->recentlyLoadedLabel->height()); + } + + painter.end(); +} + +void RunningScriptsWidget::stopScript(int row, int column) { if (column == 1) { // make sure the user has clicked on the close icon - _lastStoppedScript = ui->runningScriptsTableWidget->item(row, 0)->text(); - emit stopScriptName(ui->runningScriptsTableWidget->item(row, 0)->text()); + _lastStoppedScript = _runningScriptsTable->item(row, 0)->toolTip(); + emit stopScriptName(_runningScriptsTable->item(row, 0)->toolTip()); } } -void RunningScriptsWidget::loadScript(int row, int column) -{ - Application::getInstance()->loadScript(ui->recentlyLoadedScriptsTableWidget->item(row, column)->text()); +void RunningScriptsWidget::loadScript(int row, int column) { + Application::getInstance()->loadScript(_recentlyLoadedScriptsTable->item(row, column)->toolTip()); } -void RunningScriptsWidget::allScriptsStopped() -{ +void RunningScriptsWidget::allScriptsStopped() { QStringList list = Application::getInstance()->getRunningScripts(); for (int i = 0; i < list.size(); ++i) { _recentlyLoadedScripts.prepend(list.at(i)); @@ -173,8 +177,7 @@ void RunningScriptsWidget::allScriptsStopped() Application::getInstance()->stopAllScripts(); } -void RunningScriptsWidget::createRecentlyLoadedScriptsTable() -{ +void RunningScriptsWidget::createRecentlyLoadedScriptsTable() { if (!_recentlyLoadedScripts.contains(_lastStoppedScript) && !_lastStoppedScript.isEmpty()) { _recentlyLoadedScripts.prepend(_lastStoppedScript); _lastStoppedScript = ""; @@ -187,21 +190,28 @@ void RunningScriptsWidget::createRecentlyLoadedScriptsTable() } ui->recentlyLoadedLabel->setVisible(!_recentlyLoadedScripts.isEmpty()); - ui->line2->setVisible(!_recentlyLoadedScripts.isEmpty()); ui->recentlyLoadedScriptsTableWidget->setVisible(!_recentlyLoadedScripts.isEmpty()); ui->recentlyLoadedInstruction->setVisible(!_recentlyLoadedScripts.isEmpty()); int limit = _recentlyLoadedScripts.size() > 9 ? 9 : _recentlyLoadedScripts.size(); - ui->recentlyLoadedScriptsTableWidget->setRowCount(limit); - for (int i = 0; i < limit; ++i) { + _recentlyLoadedScriptsTable->setRowCount(limit); + for (int i = 0; i < limit; i++) { QTableWidgetItem *scriptName = new QTableWidgetItem; - scriptName->setText(_recentlyLoadedScripts.at(i)); + scriptName->setText(QString::number(i + 1) + ". " + QFileInfo(_recentlyLoadedScripts.at(i)).fileName()); scriptName->setToolTip(_recentlyLoadedScripts.at(i)); - scriptName->setTextAlignment(Qt::AlignCenter); - QTableWidgetItem *number = new QTableWidgetItem; - number->setText(QString::number(i+1) + "."); + scriptName->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); - ui->recentlyLoadedScriptsTableWidget->setItem(i, 0, number); - ui->recentlyLoadedScriptsTableWidget->setItem(i, 1, scriptName); + _recentlyLoadedScriptsTable->setItem(i, 0, scriptName); } + + int y = ui->recentlyLoadedScriptsTableWidget->y() + 15; + for (int i = 0; i < _recentlyLoadedScriptsTable->rowCount(); ++i) { + y += _recentlyLoadedScriptsTable->rowHeight(i); + } + + ui->recentlyLoadedInstruction->setGeometry(36, y, + ui->recentlyLoadedInstruction->width(), + ui->recentlyLoadedInstruction->height()); + + repaint(); } diff --git a/interface/src/ui/RunningScriptsWidget.h b/interface/src/ui/RunningScriptsWidget.h index c4e1316e15..ad310c4ed4 100644 --- a/interface/src/ui/RunningScriptsWidget.h +++ b/interface/src/ui/RunningScriptsWidget.h @@ -12,18 +12,18 @@ #ifndef hifi_RunningScriptsWidget_h #define hifi_RunningScriptsWidget_h -// Qt -#include +#include "FramelessDialog.h" +#include "ScriptsTableWidget.h" namespace Ui { class RunningScriptsWidget; } -class RunningScriptsWidget : public QDockWidget +class RunningScriptsWidget : public FramelessDialog { Q_OBJECT public: - explicit RunningScriptsWidget(QDockWidget *parent = 0); + explicit RunningScriptsWidget(QWidget* parent = NULL); ~RunningScriptsWidget(); void setRunningScripts(const QStringList& list); @@ -32,7 +32,11 @@ signals: void stopScriptName(const QString& name); protected: - void keyPressEvent(QKeyEvent *e); + virtual void keyPressEvent(QKeyEvent* event); + virtual void paintEvent(QPaintEvent* event); + +public slots: + void setBoundary(const QRect& rect); private slots: void stopScript(int row, int column); @@ -40,9 +44,12 @@ private slots: void allScriptsStopped(); private: - Ui::RunningScriptsWidget *ui; + Ui::RunningScriptsWidget* ui; + ScriptsTableWidget* _runningScriptsTable; + ScriptsTableWidget* _recentlyLoadedScriptsTable; QStringList _recentlyLoadedScripts; QString _lastStoppedScript; + QRect _boundary; void createRecentlyLoadedScriptsTable(); }; diff --git a/interface/src/ui/ScriptsTableWidget.cpp b/interface/src/ui/ScriptsTableWidget.cpp new file mode 100644 index 0000000000..95acca052c --- /dev/null +++ b/interface/src/ui/ScriptsTableWidget.cpp @@ -0,0 +1,49 @@ +// +// ScriptsTableWidget.cpp +// interface +// +// Created by Mohammed Nafees on 04/03/2014. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include +#include +#include + +#include "ScriptsTableWidget.h" + +ScriptsTableWidget::ScriptsTableWidget(QWidget* parent) : + QTableWidget(parent) { + verticalHeader()->setVisible(false); + horizontalHeader()->setVisible(false); + setShowGrid(false); + setSelectionMode(QAbstractItemView::NoSelection); + setEditTriggers(QAbstractItemView::NoEditTriggers); + setStyleSheet("QTableWidget { background: transparent; color: #333333; } QToolTip { color: #000000; background: #f9f6e4; padding: 2px; }"); + setToolTipDuration(200); + setWordWrap(true); + setGeometry(0, 0, parent->width(), parent->height()); +} + +void ScriptsTableWidget::paintEvent(QPaintEvent* event) { + QPainter painter(viewport()); + painter.setPen(QColor::fromRgb(225, 225, 225)); // #e1e1e1 + + int y = 0; + for (int i = 0; i < rowCount(); i++) { + painter.drawLine(5, rowHeight(i) + y, width(), rowHeight(i) + y); + y += rowHeight(i); + } + painter.end(); + + QTableWidget::paintEvent(event); +} + +void ScriptsTableWidget::keyPressEvent(QKeyEvent* event) { + // Ignore keys so they will propagate correctly + event->ignore(); +} diff --git a/interface/src/ui/ScriptsTableWidget.h b/interface/src/ui/ScriptsTableWidget.h new file mode 100644 index 0000000000..4b54130e82 --- /dev/null +++ b/interface/src/ui/ScriptsTableWidget.h @@ -0,0 +1,28 @@ +// +// ScriptsTableWidget.h +// interface +// +// Created by Mohammed Nafees on 04/03/2014. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// +// 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__ScriptsTableWidget_h +#define hifi__ScriptsTableWidget_h + +#include +#include + +class ScriptsTableWidget : public QTableWidget { + Q_OBJECT +public: + explicit ScriptsTableWidget(QWidget* parent); + +protected: + virtual void paintEvent(QPaintEvent* event); + virtual void keyPressEvent(QKeyEvent* event); +}; + +#endif // hifi__ScriptsTableWidget_h diff --git a/interface/ui/runningScriptsWidget.ui b/interface/ui/runningScriptsWidget.ui index c7fc9e43e8..6abd0f2d5a 100644 --- a/interface/ui/runningScriptsWidget.ui +++ b/interface/ui/runningScriptsWidget.ui @@ -6,44 +6,58 @@ 0 0 - 310 - 651 + 323 + 894 Form - background: #f7f7f7; -font-family: Helvetica, Arial, "DejaVu Sans"; + * { + font-family: Helvetica, Arial, sans-serif; +} +QWidget { + background: #f7f7f7; +} - 20 - 10 - 221 - 31 + 37 + 29 + 251 + 20 - color: #0e7077; + color: #0e7077; +font-size: 20pt; +background: transparent; <html><head/><body><p><span style=" font-size:18pt;">Running Scripts</span></p></body></html> + + 0 + + + -1 + - 20 - 40 - 301 + 36 + 110 + 270 20 - color: #0e7077; + color: #0e7077; +font: bold 14pt; +background: transparent; <html><head/><body><p><span style=" font-weight:600;">Currently running</span></p></body></html> @@ -52,22 +66,27 @@ font-family: Helvetica, Arial, "DejaVu Sans"; - 40 - 230 + 36 + 270 111 - 31 + 35 PointingHandCursor + + false + background: #0e7077; color: #fff; -border-radius: 6px; +border-radius: 4px; +font: bold 14pt; +padding-top: 3px; - Reload All + Reload all @@ -78,9 +97,9 @@ border-radius: 6px; 160 - 230 - 101 - 31 + 270 + 93 + 35 @@ -89,10 +108,12 @@ border-radius: 6px; background: #0e7077; color: #fff; -border-radius: 6px; +border-radius: 4px; +font: bold 14pt; +padding-top: 3px; - Stop All + Stop all @@ -102,46 +123,32 @@ border-radius: 6px; - 20 - 280 - 301 + 36 + 320 + 265 20 - color: #0e7077; + color: #0e7077; +font: bold 14pt; <html><head/><body><p><span style=" font-weight:600;">Recently loaded</span></p></body></html> - - - - 20 - 300 - 271 - 8 - - - - - - - Qt::Horizontal - - - 20 - 590 - 271 + 36 + 630 + 211 41 - color: #95a5a6; + color: #95a5a6; +font-size: 14pt; (click a script or use the 1-9 keys to load and run it) @@ -153,10 +160,10 @@ border-radius: 6px; - 270 - 10 - 31 - 31 + 285 + 29 + 16 + 16 @@ -165,81 +172,101 @@ border-radius: 6px; - - - ../resources/images/close.svg../resources/images/close.svg - - 20 - 20 + 16 + 16 true - - - - 20 - 70 - 271 - 141 - - - - background: transparent; - - - - - - 20 - 60 - 271 - 8 - - - - - - - Qt::Horizontal - - - - - - 20 - 310 - 271 - 281 - - - - background: transparent; - - - 20 - 40 + 36 + 110 271 51 - font: 14px; + font: 14pt; There are no scripts currently running. - Qt::AlignCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + 30 + 340 + 272 + 280 + + + + background: transparent; +font-size: 14pt; + + + + + + 30 + 128 + 272 + 161 + + + + background: transparent; +font-size: 14pt; + + + + + + 36 + 70 + 111 + 35 + + + + PointingHandCursor + + + background: #0e7077; +color: #fff; +border-radius: 4px; +font: bold 14pt; +padding-top: 3px; + + + Load script + + + + ../resources/images/plus.svg../resources/images/plus.svg + + + widgetTitle + currentlyRunningLabel + recentlyLoadedLabel + recentlyLoadedInstruction + hideWidgetButton + recentlyLoadedScriptsTableWidget + runningScriptsTableWidget + noRunningScriptsLabel + reloadAllButton + stopAllButton + loadScriptButton diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index b8b755e099..a31e6fcddc 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -166,7 +166,7 @@ void ScriptEngine::setAvatarData(AvatarData* avatarData, const QString& objectNa void ScriptEngine::setAvatarHashMap(AvatarHashMap* avatarHashMap, const QString& objectName) { // remove the old Avatar property, if it exists _engine.globalObject().setProperty(objectName, QScriptValue()); - + // give the script engine the new avatar hash map registerGlobalObject(objectName, avatarHashMap); } @@ -228,7 +228,7 @@ void ScriptEngine::init() { registerGlobalObject("Vec3", &_vec3Library); registerGlobalObject("Uuid", &_uuidLibrary); registerGlobalObject("AnimationCache", &_animationCache); - + registerGlobalObject("Voxels", &_voxelsScriptingInterface); // constants