From cb1408d26d4048c712522de54cdb776fb02fd0a3 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 16 Apr 2014 10:01:35 -0700 Subject: [PATCH] Update chat window to use new Frameless Dialog The new dialog class needed to be updated to handle windows in different positions and windows that don't delete on close. --- interface/src/Menu.cpp | 19 +- interface/src/ui/ChatWindow.cpp | 38 +-- interface/src/ui/ChatWindow.h | 16 +- interface/src/ui/FramelessDialog.cpp | 72 +++-- interface/src/ui/FramelessDialog.h | 10 +- interface/src/ui/PreferencesDialog.cpp | 2 +- interface/ui/chatWindow.ui | 387 ++++++++++++------------- 7 files changed, 267 insertions(+), 277 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 272dc39eb3..508eaf61c3 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1060,23 +1060,22 @@ void Menu::showMetavoxelEditor() { void Menu::showChat() { QMainWindow* mainWindow = Application::getInstance()->getWindow(); if (!_chatWindow) { - mainWindow->addDockWidget(Qt::RightDockWidgetArea, _chatWindow = new ChatWindow()); + _chatWindow = new ChatWindow(mainWindow); } - if (!_chatWindow->toggleViewAction()->isChecked()) { - const QRect& windowGeometry = mainWindow->geometry(); - _chatWindow->move(windowGeometry.topRight().x() - _chatWindow->width(), - windowGeometry.topRight().y() + (windowGeometry.height() / 2) - (_chatWindow->height() / 2)); - - _chatWindow->resize(0, _chatWindow->height()); - _chatWindow->toggleViewAction()->trigger(); + if (_chatWindow->isHidden()) { + _chatWindow->show(); } } void Menu::toggleChat() { #ifdef HAVE_QXMPP _chatAction->setEnabled(XmppClient::getInstance().getXMPPClient().isConnected()); - if (!_chatAction->isEnabled() && _chatWindow && _chatWindow->toggleViewAction()->isChecked()) { - _chatWindow->toggleViewAction()->trigger(); + if (!_chatAction->isEnabled() && _chatWindow) { + if (_chatWindow->isHidden()) { + _chatWindow->show(); + } else { + _chatWindow->hide(); + } } #endif } diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index c190169c43..1f0f884f30 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -12,12 +12,10 @@ #include #include #include -#include #include #include #include #include -#include #include "Application.h" #include "FlowLayout.h" @@ -32,18 +30,16 @@ const int NUM_MESSAGES_TO_TIME_STAMP = 20; const QRegularExpression regexLinks("((?:(?:ftp)|(?:https?))://\\S+)"); -ChatWindow::ChatWindow() : +ChatWindow::ChatWindow(QWidget* parent) : + FramelessDialog(parent, 0, POSITION_RIGHT), ui(new Ui::ChatWindow), numMessagesAfterLastTimeStamp(0), _mousePressed(false), _mouseStartPosition() { - ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose, false); - // remove the title bar (see the Qt docs on setTitleBarWidget), but we keep it for undocking - // - titleBar = titleBarWidget(); - setTitleBarWidget(new QWidget()); + ui->setupUi(this); FlowLayout* flowLayout = new FlowLayout(0, 4, 4); ui->usersWidget->setLayout(flowLayout); @@ -89,41 +85,23 @@ ChatWindow::~ChatWindow() { delete ui; } -void ChatWindow::mousePressEvent(QMouseEvent *e) { - if (e->button() == Qt::LeftButton && isFloating()) { - _mousePressed = true; - _mouseStartPosition = e->pos(); - } -} - -void ChatWindow::mouseMoveEvent(QMouseEvent *e) { - if (_mousePressed) { - move(mapToParent(e->pos() - _mouseStartPosition)); - } -} - -void ChatWindow::mouseReleaseEvent( QMouseEvent *e ) { - if ( e->button() == Qt::LeftButton ) { - _mousePressed = false; - } -} - void ChatWindow::keyPressEvent(QKeyEvent* event) { - QDockWidget::keyPressEvent(event); if (event->key() == Qt::Key_Escape) { hide(); + } else { + FramelessDialog::keyPressEvent(event); } } void ChatWindow::showEvent(QShowEvent* event) { - QDockWidget::showEvent(event); + FramelessDialog::showEvent(event); if (!event->spontaneous()) { - activateWindow(); ui->messagePlainTextEdit->setFocus(); } } bool ChatWindow::eventFilter(QObject* sender, QEvent* event) { + FramelessDialog::eventFilter(sender, event); if (sender == ui->messagePlainTextEdit) { if (event->type() != QEvent::KeyPress) { return false; diff --git a/interface/src/ui/ChatWindow.h b/interface/src/ui/ChatWindow.h index 536ac17799..399c9e917c 100644 --- a/interface/src/ui/ChatWindow.h +++ b/interface/src/ui/ChatWindow.h @@ -17,6 +17,7 @@ #include #include +#include "FramelessDialog.h" #ifdef HAVE_QXMPP @@ -29,23 +30,19 @@ namespace Ui { class ChatWindow; } -class ChatWindow : public QDockWidget { +class ChatWindow : public FramelessDialog { Q_OBJECT public: - ChatWindow(); + ChatWindow(QWidget* parent); ~ChatWindow(); - virtual void keyPressEvent(QKeyEvent *event); - virtual void showEvent(QShowEvent* event); - - virtual void mousePressEvent(QMouseEvent *e); - virtual void mouseMoveEvent(QMouseEvent *e); - virtual void mouseReleaseEvent(QMouseEvent *e); - protected: bool eventFilter(QObject* sender, QEvent* event); + virtual void keyPressEvent(QKeyEvent *event); + virtual void showEvent(QShowEvent* event); + private: #ifdef HAVE_QXMPP QString getParticipantName(const QString& participant); @@ -56,7 +53,6 @@ private: void scrollToBottom(); Ui::ChatWindow* ui; - QWidget* titleBar; int numMessagesAfterLastTimeStamp; QDateTime lastMessageStamp; bool _mousePressed; diff --git a/interface/src/ui/FramelessDialog.cpp b/interface/src/ui/FramelessDialog.cpp index 18e3bca89a..816c45b38a 100644 --- a/interface/src/ui/FramelessDialog.cpp +++ b/interface/src/ui/FramelessDialog.cpp @@ -14,8 +14,13 @@ const int RESIZE_HANDLE_WIDTH = 7; -FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags) : -QDialog(parent, flags | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint) { +FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags, Position position) : + QDialog(parent, flags | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint), + _position(position), + _selfHidden(false), + _isResizing(false), + _resizeInitialWidth(0) { + setAttribute(Qt::WA_DeleteOnClose); // handle rezize and move events @@ -29,29 +34,37 @@ bool FramelessDialog::eventFilter(QObject* sender, QEvent* event) { switch (event->type()) { case QEvent::Move: if (sender == parentWidget()) { - // move to upper left corner on app move - move(parentWidget()->geometry().topLeft()); + resizeAndPosition(false); } break; case QEvent::Resize: if (sender == parentWidget()) { - // keep full app height on resizing the app - setFixedHeight(parentWidget()->size().height()); + resizeAndPosition(false); } break; case QEvent::WindowStateChange: if (parentWidget()->isMinimized()) { - setHidden(true); - } else { + if (isVisible()) { + _selfHidden = true; + setHidden(true); + } + } else if (_selfHidden) { + _selfHidden = false; setHidden(false); } break; case QEvent::ApplicationDeactivate: // hide on minimize and focus lost - setHidden(true); + if (isVisible()) { + _selfHidden = true; + setHidden(true); + } break; case QEvent::ApplicationActivate: - setHidden(false); + if (_selfHidden) { + _selfHidden = false; + setHidden(false); + } break; default: break; @@ -70,21 +83,38 @@ void FramelessDialog::setStyleSheetFile(const QString& fileName) { } void FramelessDialog::showEvent(QShowEvent* event) { - // move to upper left corner - move(parentWidget()->geometry().topLeft()); + resizeAndPosition(); +} +void FramelessDialog::resizeAndPosition(bool resizeParent) { // keep full app height setFixedHeight(parentWidget()->size().height()); // resize parrent if width is smaller than this dialog - if (parentWidget()->size().width() < size().width()) { + if (resizeParent && parentWidget()->size().width() < size().width()) { parentWidget()->resize(size().width(), parentWidget()->size().height()); } + + if (_position == POSITION_LEFT) { + // move to upper left corner + move(parentWidget()->geometry().topLeft()); + } else if (_position == POSITION_RIGHT) { + // move to upper right corner + QPoint pos = parentWidget()->geometry().topRight(); + pos.setX(pos.x() - size().width()); + move(pos); + } } + void FramelessDialog::mousePressEvent(QMouseEvent* mouseEvent) { - if (abs(mouseEvent->pos().x() - size().width()) < RESIZE_HANDLE_WIDTH && mouseEvent->button() == Qt::LeftButton) { - _isResizing = true; - QApplication::setOverrideCursor(Qt::SizeHorCursor); + if (mouseEvent->button() == Qt::LeftButton) { + 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; + if (hitLeft || hitRight) { + _isResizing = true; + _resizeInitialWidth = size().width(); + QApplication::setOverrideCursor(Qt::SizeHorCursor); + } } } @@ -95,6 +125,14 @@ void FramelessDialog::mouseReleaseEvent(QMouseEvent* mouseEvent) { void FramelessDialog::mouseMoveEvent(QMouseEvent* mouseEvent) { if (_isResizing) { - resize(mouseEvent->pos().x(), size().height()); + if (_position == POSITION_LEFT) { + resize(mouseEvent->pos().x(), size().height()); + } else if (_position == POSITION_RIGHT) { + setUpdatesEnabled(false); + resize(_resizeInitialWidth - mouseEvent->pos().x(), size().height()); + resizeAndPosition(); + _resizeInitialWidth = size().width(); + setUpdatesEnabled(true); + } } } diff --git a/interface/src/ui/FramelessDialog.h b/interface/src/ui/FramelessDialog.h index db9f6dfd6c..22666cca63 100644 --- a/interface/src/ui/FramelessDialog.h +++ b/interface/src/ui/FramelessDialog.h @@ -19,7 +19,10 @@ class FramelessDialog : public QDialog { Q_OBJECT public: - FramelessDialog(QWidget* parent = 0, Qt::WindowFlags flags = 0); + enum Position { POSITION_LEFT, POSITION_RIGHT }; + + FramelessDialog(QWidget* parent = 0, Qt::WindowFlags flags = 0, + Position position = POSITION_LEFT); void setStyleSheetFile(const QString& fileName); protected: @@ -31,7 +34,12 @@ protected: bool eventFilter(QObject* sender, QEvent* event); private: + void resizeAndPosition(bool resizeParent = true); + bool _isResizing; + int _resizeInitialWidth; + bool _selfHidden; ///< true when the dialog itself because of a window event (deactivation or minimization) + Position _position; }; diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index a14e80e62f..cb998e783a 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -19,7 +19,7 @@ const int SCROLL_PANEL_BOTTOM_MARGIN = 30; const int OK_BUTTON_RIGHT_MARGIN = 30; const int BUTTONS_TOP_MARGIN = 24; -PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags flags) : FramelessDialog(parent, flags) { +PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags flags) : FramelessDialog(parent, flags, POSITION_LEFT) { ui.setupUi(this); setStyleSheetFile("styles/preferences.qss"); diff --git a/interface/ui/chatWindow.ui b/interface/ui/chatWindow.ui index 1d06a1e99b..78757ded38 100644 --- a/interface/ui/chatWindow.ui +++ b/interface/ui/chatWindow.ui @@ -1,13 +1,13 @@ ChatWindow - + 0 0 400 - 608 + 440 @@ -16,127 +16,95 @@ 238 - - font-family: Helvetica, Arial, sans-serif; - - - QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable - - - Qt::NoDockWidgetArea - Chat - - - - 0 - - - 8 - - - 8 - - - 8 - - - 8 - - - - - - 0 - 0 - - - - Connecting to XMPP... - - - Qt::AlignCenter - - - - - - - - - - 0 - 0 - - - - font-weight: bold; color: palette(shadow); margin-bottom: 4px; - - - online now: - - - - - - - - 0 - 0 - - - - - 16 - 16 - - - - Qt::NoFocus - - - - - - - ../resources/images/pin.svg - ../resources/images/pinned.svg../resources/images/pin.svg - - - true - - - true - - - false - - - true - - - - - - - - 0 - 0 - - - - - 16 - 16 - - - - Qt::NoFocus - - - QPushButton { + + font-family: Helvetica, Arial, sans-serif; + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 8 + + + 8 + + + 8 + + + 8 + + + + + + 0 + 0 + + + + Connecting to XMPP... + + + Qt::AlignCenter + + + + + + + + + + 0 + 0 + + + + font-weight: bold; color: palette(shadow); margin-bottom: 4px; + + + online now: + + + + + + + + 0 + 0 + + + + + 16 + 16 + + + + Qt::NoFocus + + + QPushButton { background-color: rgba( 0, 0, 0, 0% ); border: none; image: url(../resources/images/close.svg) @@ -148,102 +116,105 @@ QPushButton:pressed { border: none; image: url(../resources/images/close_down.svg) } - - - - - - true - - - - - - - - - - - - margin-top: 12px; - - - Qt::ScrollBarAlwaysOff - - - true - - - - - 0 - 0 - 382 - 16 - + + + + + + true + + + + + + + + + + + + margin-top: 12px; + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 382 + 16 + + + + + 0 + 0 + + + + margin-top: 0px; + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + - + 0 0 - - margin-top: 0px; + + + 0 + 60 + + + + border-color: palette(dark); border-style: solid; border-left-width: 1px; border-right-width: 1px; border-bottom-width: 1px; + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + QAbstractScrollArea::AdjustToContents + + + true - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - 0 - 0 - - - - - 0 - 60 - - - - border-color: palette(dark); border-style: solid; border-left-width: 1px; border-right-width: 1px; border-bottom-width: 1px; - - - QFrame::NoFrame - - - Qt::ScrollBarAlwaysOff - - - QAbstractScrollArea::AdjustToContents - - - true - - - - - + + + + + messagePlainTextEdit + dockWidgetContents messagePlainTextEdit