diff --git a/interface/resources/styles/Inconsolata.otf b/interface/resources/styles/Inconsolata.otf new file mode 100644 index 0000000000..348889828d Binary files /dev/null and b/interface/resources/styles/Inconsolata.otf differ diff --git a/interface/resources/styles/log_dialog.qss b/interface/resources/styles/log_dialog.qss new file mode 100644 index 0000000000..5fe6e1ba66 --- /dev/null +++ b/interface/resources/styles/log_dialog.qss @@ -0,0 +1,10 @@ +QWidget { + background-color: none; +} + +QPlainTextEdit { + font-family: Inconsolata, Lucida Console, Andale Mono, Monaco; + font-size: 16px; + padding: 28px; + color: #333333; +} diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f12cd94578..ce68c0d4a4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -86,7 +86,7 @@ const float MIRROR_REARVIEW_BODY_DISTANCE = 1.f; void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message) { fprintf(stdout, "%s", message.toLocal8Bit().constData()); - LogDisplay::instance.addMessage(message.toLocal8Bit().constData()); + Menu::getInstance()->appendLogLine(message.toLocal8Bit().constData()); } Application::Application(int& argc, char** argv, timeval &startup_time) : @@ -142,10 +142,21 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _pasteMode(false) { _applicationStartupTime = startup_time; + +#ifdef Q_OS_MAC + QString resourcesPath = QCoreApplication::applicationDirPath() + "/../Resources"; +#else + QString resourcesPath = QCoreApplication::applicationDirPath() + "/resources"; +#endif + + QFontDatabase::addApplicationFont(resourcesPath + "/styles/Inconsolata.otf"); _window->setWindowTitle("Interface"); + // call Menu getInstance static method to set up the menu + _window->setMenuBar(Menu::getInstance()); + qInstallMessageHandler(messageHandler); - + unsigned int listenPort = 0; // bind to an ephemeral port by default const char** constArgv = const_cast(argv); const char* portStr = getCmdOption(argc, constArgv, "--listenPort"); @@ -170,14 +181,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : // network receive thread and voxel parsing thread are both controlled by the --nonblocking command line _enableProcessVoxelsThread = _enableNetworkThread = !cmdOptionExists(argc, constArgv, "--nonblocking"); - - // setup QSettings -#ifdef Q_OS_MAC - QString resourcesPath = QCoreApplication::applicationDirPath() + "/../Resources"; -#else - QString resourcesPath = QCoreApplication::applicationDirPath() + "/resources"; -#endif - + // read the ApplicationInfo.ini file for Name/Version/Domain information QSettings applicationInfo(resourcesPath + "/info/ApplicationInfo.ini", QSettings::IniFormat); @@ -190,9 +194,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : setOrganizationDomain(applicationInfo.value("organizationDomain").toString()); _settings = new QSettings(this); - - // call Menu getInstance static method to set up the menu - _window->setMenuBar(Menu::getInstance()); // Check to see if the user passed in a command line option for loading a local // Voxel File. @@ -243,6 +244,9 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : } Application::~Application() { + + qInstallMessageHandler(NULL); + // make sure we don't call the idle timer any more delete idleTimer; @@ -3323,11 +3327,6 @@ void Application::displayOverlay() { if (Menu::getInstance()->isOptionChecked(MenuOption::CoverageMap)) { renderCoverageMap(); } - - - if (Menu::getInstance()->isOptionChecked(MenuOption::Log)) { - LogDisplay::instance.render(_glWidget->width(), _glWidget->height()); - } // Show chat entry field if (_chatEntryOn) { diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 13510067cd..83fb70cee3 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -69,7 +69,8 @@ Menu::Menu() : _maxVoxels(DEFAULT_MAX_VOXELS_PER_SYSTEM), _voxelSizeScale(DEFAULT_OCTREE_SIZE_SCALE), _boundaryLevelAdjust(0), - _maxVoxelPacketsPerSecond(DEFAULT_MAX_VOXEL_PPS) + _maxVoxelPacketsPerSecond(DEFAULT_MAX_VOXEL_PPS), + _logDialog(NULL) { Application *appInstance = Application::getInstance(); @@ -261,7 +262,7 @@ Menu::Menu() : addDisabledActionAndSeparator(viewMenu, "Stats"); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L); + addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L, this, SLOT(showLogDialog())); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Oscilloscope, 0, true); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Bandwidth, 0, true); addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, this, SLOT(bandwidthDetails())); @@ -1007,6 +1008,29 @@ void Menu::pasteToVoxel() { sendFakeEnterEvent(); } +void Menu::appendLogLine(QString logLine) { + if (_logDialog) { + _logDialog->appendLogLine(logLine); + } +} + +void Menu::showLogDialog() { + if (! _logDialog) { + _logDialog = new LogDialog(Application::getInstance()->getGLWidget()); + connect(_logDialog, SIGNAL(closed()), SLOT(logDialogClosed())); + + _logDialog->show(); + } + _logDialog->raise(); +} + +void Menu::logDialogClosed() { + if (_logDialog) { + delete _logDialog; + _logDialog = NULL; + } +} + void Menu::bandwidthDetails() { if (! _bandwidthDialog) { _bandwidthDialog = new BandwidthDialog(Application::getInstance()->getGLWidget(), diff --git a/interface/src/Menu.h b/interface/src/Menu.h index aa3b925517..0ef507ca8b 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -13,6 +13,8 @@ #include #include +#include "ui/LogDialog.h" + enum FrustumDrawMode { FRUSTUM_DRAW_MODE_ALL, FRUSTUM_DRAW_MODE_VECTORS, @@ -47,6 +49,7 @@ public: void triggerOption(const QString& menuOption); QAction* getActionForOption(const QString& menuOption); bool isVoxelModeActionChecked(); + void appendLogLine(QString logLine); float getAudioJitterBufferSamples() const { return _audioJitterBufferSamples; } float getFieldOfView() const { return _fieldOfView; } @@ -81,6 +84,7 @@ public slots: void exportSettings(); void goToUser(); void pasteToVoxel(); + void showLogDialog(); private slots: void aboutApp(); @@ -96,6 +100,7 @@ private slots: void chooseVoxelPaintColor(); void runTests(); void resetSwatchColors(); + void logDialogClosed(); private: static Menu* _instance; @@ -141,6 +146,7 @@ private: int _boundaryLevelAdjust; QAction* _useVoxelShader; int _maxVoxelPacketsPerSecond; + LogDialog* _logDialog; }; namespace MenuOption { diff --git a/interface/src/ui/LogDialog.cpp b/interface/src/ui/LogDialog.cpp new file mode 100644 index 0000000000..7edffd2f83 --- /dev/null +++ b/interface/src/ui/LogDialog.cpp @@ -0,0 +1,70 @@ +// +// LogDialog.cpp +// interface +// +// Created by Stojce Slavkovski on 12/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#include +#include +#include + +#include "SharedUtil.h" +#include "ui/LogDialog.h" + +#define INITIAL_WIDTH_RATIO 0.3 +#define INITIAL_HEIGHT_RATIO 0.6 + +int cursorMeta = qRegisterMetaType("QTextCursor"); +int blockMeta = qRegisterMetaType("QTextBlock"); + +LogDialog::LogDialog(QWidget* parent) : + QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) { + + setWindowTitle("Log"); + + _logTextBox = new QPlainTextEdit(this); + _logTextBox->setReadOnly(true); + _logTextBox->show(); + + switchToResourcesParentIfRequired(); + QFile styleSheet("resources/styles/log_dialog.qss"); + + if (styleSheet.open(QIODevice::ReadOnly)) { + setStyleSheet(styleSheet.readAll()); + } + + QDesktopWidget* desktop = new QDesktopWidget(); + QRect screen = desktop->screenGeometry(); + resize((int)(screen.width() * INITIAL_WIDTH_RATIO), (int)(screen.height() * INITIAL_HEIGHT_RATIO)); + move(screen.center() - rect().center()); + delete desktop; +} + +LogDialog::~LogDialog() { + delete _logTextBox; +} + +void LogDialog::showEvent(QShowEvent *e) { + _logTextBox->clear(); +} + +void LogDialog::resizeEvent(QResizeEvent *e) { + _logTextBox->resize(width(), height()); +} + +void LogDialog::appendLogLine(QString logLine) { + if (isVisible()) { + _logTextBox->appendPlainText(logLine.simplified()); + _logTextBox->ensureCursorVisible(); + } +} + +void LogDialog::reject() { + this->QDialog::close(); +} + +void LogDialog::closeEvent(QCloseEvent* event) { + emit closed(); +} diff --git a/interface/src/ui/LogDialog.h b/interface/src/ui/LogDialog.h new file mode 100644 index 0000000000..6b847cd66f --- /dev/null +++ b/interface/src/ui/LogDialog.h @@ -0,0 +1,41 @@ +// +// LogDialog.h +// interface +// +// Created by Stojce Slavkovski on 12/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __interface__LogDialog__ +#define __interface__LogDialog__ + +#include +#include + +class LogDialog : public QDialog { + Q_OBJECT + +public: + LogDialog(QWidget* parent); + ~LogDialog(); + void appendLogLine(QString logLine); + +signals: + void closed(); + +public slots: + void reject(); + +protected: + // Emits a 'closed' signal when this dialog is closed. + void closeEvent(QCloseEvent* e); + void resizeEvent(QResizeEvent* e); + void showEvent(QShowEvent* e); + +private: + QPlainTextEdit* _logTextBox; + +}; + +#endif +