mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 18:55:01 +02:00
Merge pull request #2660 from huffman/19554
19554 Continue refining Chat
This commit is contained in:
commit
f61d72fcf0
7 changed files with 255 additions and 28 deletions
79
interface/resources/images/close_down.svg
Normal file
79
interface/resources/images/close_down.svg
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="44px"
|
||||
height="44px"
|
||||
viewBox="0 0 44 44"
|
||||
version="1.1"
|
||||
id="svg3085"
|
||||
inkscape:version="0.48.2 r9819"
|
||||
sodipodi:docname="close_hover.svg">
|
||||
<metadata
|
||||
id="metadata3099">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Slice 1</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="814"
|
||||
inkscape:window-height="783"
|
||||
id="namedview3097"
|
||||
showgrid="false"
|
||||
inkscape:zoom="10.727273"
|
||||
inkscape:cx="14.784087"
|
||||
inkscape:cy="19.379049"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="Page-1" />
|
||||
<title
|
||||
id="title3087">Slice 1</title>
|
||||
<description
|
||||
id="description3089">Created with Sketch (http://www.bohemiancoding.com/sketch)</description>
|
||||
<defs
|
||||
id="defs3091" />
|
||||
<g
|
||||
id="Page-1"
|
||||
sketch:type="MSPage"
|
||||
stroke-width="1"
|
||||
stroke="none"
|
||||
fill-rule="evenodd"
|
||||
fill="none">
|
||||
<g
|
||||
id="close"
|
||||
sketch:type="MSLayerGroup"
|
||||
fill="#CCCCCC">
|
||||
<path
|
||||
d="M0.286382588,32.6200761 L32.6200759,0.286382745 C33.0019275,-0.0954590326 33.6210173,-0.0954590326 34.0028688,0.286382745 L43.380667,9.66418097 C43.7625088,10.0460227 43.7625088,10.6651125 43.380667,11.0469543 L43.380667,11.0469543 L11.0469639,43.3806574 C10.6651221,43.7624992 10.0460226,43.7624992 9.66418081,43.3806574 L0.286382588,34.0028592 C-0.0954591894,33.6210076 -0.0954591894,33.0019179 0.286382588,32.6200761 L0.286382588,32.6200761 L0.286382588,32.6200761 Z"
|
||||
id="path16"
|
||||
sketch:type="MSShapeGroup"
|
||||
style="fill:#e6e6e6" />
|
||||
<path
|
||||
d="M32.6200759,43.3806574 L0.286382588,11.0469543 C-0.0954591894,10.6651125 -0.0954591894,10.0460227 0.286382588,9.66418097 L9.66418081,0.286382745 C10.0460226,-0.0954590326 10.6651221,-0.0954590326 11.0469639,0.286382745 L43.380667,32.6200761 C43.7625088,33.0019179 43.7625088,33.6210076 43.380667,34.0028592 L34.0028688,43.3806574 C33.6210173,43.7624992 33.0019275,43.7624992 32.6200759,43.3806574 L32.6200759,43.3806574 Z"
|
||||
id="path18"
|
||||
sketch:type="MSShapeGroup"
|
||||
style="fill:#e6e6e6" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3 KiB |
|
@ -1063,18 +1063,12 @@ void Menu::showChat() {
|
|||
mainWindow->addDockWidget(Qt::RightDockWidgetArea, _chatWindow = new ChatWindow());
|
||||
}
|
||||
if (!_chatWindow->toggleViewAction()->isChecked()) {
|
||||
int width = _chatWindow->width();
|
||||
int y = qMax((mainWindow->height() - _chatWindow->height()) / 2, 0);
|
||||
_chatWindow->move(mainWindow->width(), y);
|
||||
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();
|
||||
|
||||
QPropertyAnimation* slideAnimation = new QPropertyAnimation(_chatWindow, "geometry", _chatWindow);
|
||||
slideAnimation->setStartValue(_chatWindow->geometry());
|
||||
slideAnimation->setEndValue(QRect(mainWindow->width() - width, _chatWindow->y(),
|
||||
width, _chatWindow->height()));
|
||||
slideAnimation->setDuration(250);
|
||||
slideAnimation->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
44
interface/src/ui/ChatMessageArea.cpp
Normal file
44
interface/src/ui/ChatMessageArea.cpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// ChatMessageArea.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Ryan Huffman on 4/11/14.
|
||||
// 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 "ChatMessageArea.h"
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QWheelEvent>
|
||||
|
||||
ChatMessageArea::ChatMessageArea() : QTextBrowser() {
|
||||
connect(document()->documentLayout(), &QAbstractTextDocumentLayout::documentSizeChanged,
|
||||
this, &ChatMessageArea::updateLayout);
|
||||
}
|
||||
|
||||
void ChatMessageArea::setHtml(const QString& html) {
|
||||
// Create format with updated line height
|
||||
QTextBlockFormat format;
|
||||
format.setLineHeight(CHAT_MESSAGE_LINE_HEIGHT, QTextBlockFormat::ProportionalHeight);
|
||||
|
||||
// Possibly a bug in QT, the format won't take effect if `insertHtml` is used first. Inserting a space and deleting
|
||||
// it after ensures the format is applied.
|
||||
QTextCursor cursor = textCursor();
|
||||
cursor.setBlockFormat(format);
|
||||
cursor.insertText(" ");
|
||||
cursor.insertHtml(html);
|
||||
cursor.setPosition(0);
|
||||
cursor.deleteChar();
|
||||
}
|
||||
|
||||
void ChatMessageArea::updateLayout() {
|
||||
setFixedHeight(document()->size().height());
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void ChatMessageArea::wheelEvent(QWheelEvent* event) {
|
||||
// Capture wheel events to stop Ctrl-WheelUp/Down zooming
|
||||
event->ignore();
|
||||
}
|
33
interface/src/ui/ChatMessageArea.h
Normal file
33
interface/src/ui/ChatMessageArea.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// ChatMessageArea.h
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Ryan Huffman on 4/11/14.
|
||||
// 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_ChatMessageArea_h
|
||||
#define hifi_ChatMessageArea_h
|
||||
|
||||
#include <QTextBrowser>
|
||||
|
||||
const int CHAT_MESSAGE_LINE_HEIGHT = 130;
|
||||
|
||||
class ChatMessageArea : public QTextBrowser {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ChatMessageArea();
|
||||
virtual void setHtml(const QString& html);
|
||||
|
||||
public slots:
|
||||
void updateLayout();
|
||||
|
||||
protected:
|
||||
virtual void wheelEvent(QWheelEvent* event);
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_ChatMessageArea_h
|
|
@ -24,6 +24,7 @@
|
|||
#include "qtimespan.h"
|
||||
#include "ui_chatWindow.h"
|
||||
#include "XmppClient.h"
|
||||
#include "ChatMessageArea.h"
|
||||
|
||||
#include "ChatWindow.h"
|
||||
|
||||
|
@ -33,7 +34,9 @@ const QRegularExpression regexLinks("((?:(?:ftp)|(?:https?))://\\S+)");
|
|||
|
||||
ChatWindow::ChatWindow() :
|
||||
ui(new Ui::ChatWindow),
|
||||
numMessagesAfterLastTimeStamp(0)
|
||||
numMessagesAfterLastTimeStamp(0),
|
||||
_mousePressed(false),
|
||||
_mouseStartPosition()
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
@ -86,6 +89,25 @@ 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) {
|
||||
|
@ -158,8 +180,18 @@ void ChatWindow::addTimeStamp() {
|
|||
"padding: 4px;");
|
||||
timeLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
timeLabel->setAlignment(Qt::AlignHCenter);
|
||||
|
||||
bool atBottom = isAtBottom();
|
||||
|
||||
ui->messagesGridLayout->addWidget(timeLabel, ui->messagesGridLayout->rowCount(), 0, 1, 2);
|
||||
ui->messagesGridLayout->parentWidget()->updateGeometry();
|
||||
|
||||
Application::processEvents();
|
||||
numMessagesAfterLastTimeStamp = 0;
|
||||
|
||||
if (atBottom) {
|
||||
scrollToBottom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,25 +267,41 @@ void ChatWindow::messageReceived(const QXmppMessage& message) {
|
|||
userLabel->setStyleSheet("padding: 2px; font-weight: bold");
|
||||
userLabel->setAlignment(Qt::AlignTop | Qt::AlignRight);
|
||||
|
||||
QLabel* messageLabel = new QLabel(message.body().replace(regexLinks, "<a href=\"\\1\">\\1</a>"));
|
||||
messageLabel->setWordWrap(true);
|
||||
messageLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
messageLabel->setOpenExternalLinks(true);
|
||||
messageLabel->setStyleSheet("padding-bottom: 2px; padding-left: 2px; padding-top: 2px; padding-right: 20px");
|
||||
messageLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
ChatMessageArea* messageArea = new ChatMessageArea();
|
||||
|
||||
if (getParticipantName(message.from()) == AccountManager::getInstance().getUsername()) {
|
||||
messageArea->setOpenLinks(true);
|
||||
messageArea->setOpenExternalLinks(true);
|
||||
messageArea->setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
|
||||
messageArea->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
messageArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
messageArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
messageArea->setReadOnly(true);
|
||||
|
||||
messageArea->setStyleSheet("padding-bottom: 2px;"
|
||||
"padding-left: 2px;"
|
||||
"padding-top: 2px;"
|
||||
"padding-right: 20px;"
|
||||
"background-color: rgba(0, 0, 0, 0%);"
|
||||
"border: 0;");
|
||||
|
||||
bool fromSelf = getParticipantName(message.from()) == AccountManager::getInstance().getUsername();
|
||||
if (fromSelf) {
|
||||
userLabel->setStyleSheet(userLabel->styleSheet() + "; background-color: #e1e8ea");
|
||||
messageLabel->setStyleSheet(messageLabel->styleSheet() + "; background-color: #e1e8ea");
|
||||
messageArea->setStyleSheet(messageArea->styleSheet() + "; background-color: #e1e8ea");
|
||||
}
|
||||
|
||||
messageArea->setHtml(message.body().replace(regexLinks, "<a href=\"\\1\">\\1</a>"));
|
||||
|
||||
bool atBottom = isAtBottom();
|
||||
ui->messagesGridLayout->addWidget(userLabel, ui->messagesGridLayout->rowCount(), 0);
|
||||
ui->messagesGridLayout->addWidget(messageLabel, ui->messagesGridLayout->rowCount() - 1, 1);
|
||||
ui->messagesGridLayout->addWidget(messageArea, ui->messagesGridLayout->rowCount() - 1, 1);
|
||||
|
||||
ui->messagesGridLayout->parentWidget()->updateGeometry();
|
||||
Application::processEvents();
|
||||
QScrollBar* verticalScrollBar = ui->messagesScrollArea->verticalScrollBar();
|
||||
verticalScrollBar->setSliderPosition(verticalScrollBar->maximum());
|
||||
messageLabel->updateGeometry();
|
||||
|
||||
if (atBottom || fromSelf) {
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
++numMessagesAfterLastTimeStamp;
|
||||
if (message.stamp().isValid()) {
|
||||
|
@ -265,6 +313,17 @@ void ChatWindow::messageReceived(const QXmppMessage& message) {
|
|||
|
||||
#endif
|
||||
|
||||
bool ChatWindow::isAtBottom() {
|
||||
QScrollBar* verticalScrollBar = ui->messagesScrollArea->verticalScrollBar();
|
||||
return verticalScrollBar->sliderPosition() == verticalScrollBar->maximum();
|
||||
}
|
||||
|
||||
// Scroll chat message area to bottom.
|
||||
void ChatWindow::scrollToBottom() {
|
||||
QScrollBar* verticalScrollBar = ui->messagesScrollArea->verticalScrollBar();
|
||||
verticalScrollBar->setSliderPosition(verticalScrollBar->maximum());
|
||||
}
|
||||
|
||||
void ChatWindow::togglePinned() {
|
||||
QMainWindow* mainWindow = Application::getInstance()->getWindow();
|
||||
mainWindow->removeDockWidget(this);
|
||||
|
@ -276,4 +335,4 @@ void ChatWindow::togglePinned() {
|
|||
}
|
||||
this->setFloating(!ui->togglePinnedButton->isChecked());
|
||||
setTitleBarWidget(ui->togglePinnedButton->isChecked()?new QWidget():titleBar);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,10 @@ public:
|
|||
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);
|
||||
|
||||
|
@ -48,11 +52,15 @@ private:
|
|||
#endif
|
||||
void startTimerForTimeStamps();
|
||||
void addTimeStamp();
|
||||
bool isAtBottom();
|
||||
void scrollToBottom();
|
||||
|
||||
Ui::ChatWindow* ui;
|
||||
QWidget* titleBar;
|
||||
int numMessagesAfterLastTimeStamp;
|
||||
QDateTime lastMessageStamp;
|
||||
bool _mousePressed;
|
||||
QPoint _mouseStartPosition;
|
||||
|
||||
private slots:
|
||||
void connected();
|
||||
|
|
|
@ -135,13 +135,23 @@
|
|||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
background-color: rgba( 0, 0, 0, 0% );
|
||||
border: none;
|
||||
image: url(../resources/images/close.svg)
|
||||
}
|
||||
|
||||
|
||||
QPushButton:pressed {
|
||||
background-color: rgba( 0, 0, 0, 0% );
|
||||
border: none;
|
||||
image: url(../resources/images/close_down.svg)
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>../resources/images/close.svg</normaloff>../resources/images/close.svg</iconset>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
|
|
Loading…
Reference in a new issue