mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Screen grabber: Flyout menu for the screenshot button
When hovering over the "attach file" button in the chat form, an additional button for the screenshot functionality will 'fly out' to the left, showing a computer monitor as icon. Leaving the attach file or the take screenshot button will collapse the fly out again. Bug: Moving the mouse over the fly out and then back again to the attach button collapses the fly out. Will sort this out later. Also used the opportunity to rename headers from hpp -> h extension I added earlier.
This commit is contained in:
parent
c6d5b4cc55
commit
04dc650596
11
qtox.pro
11
qtox.pro
|
@ -436,7 +436,8 @@ SOURCES += \
|
|||
src/widget/tool/screenshotgrabber.cpp \
|
||||
src/widget/tool/screengrabberchooserrectitem.cpp \
|
||||
src/widget/tool/screengrabberoverlayitem.cpp \
|
||||
src/widget/tool/toolboxgraphicsitem.cpp
|
||||
src/widget/tool/toolboxgraphicsitem.cpp \
|
||||
src/widget/tool/flyoutoverlaywidget.cpp
|
||||
|
||||
|
||||
HEADERS += \
|
||||
|
@ -464,7 +465,7 @@ HEADERS += \
|
|||
src/profilelocker.h \
|
||||
src/avatarbroadcaster.h \
|
||||
src/widget/tool/screenshotgrabber.h \
|
||||
src/widget/tool/screengrabberchooserrectitem.hpp \
|
||||
src/widget/tool/screengrabberoverlayitem.hpp \
|
||||
src/widget/tool/toolboxgraphicsitem.hpp
|
||||
|
||||
src/widget/tool/screengrabberchooserrectitem.h \
|
||||
src/widget/tool/screengrabberoverlayitem.h \
|
||||
src/widget/tool/toolboxgraphicsitem.h \
|
||||
src/widget/tool/flyoutoverlaywidget.h
|
||||
|
|
2
res.qrc
2
res.qrc
|
@ -80,6 +80,8 @@
|
|||
<file>ui/emoticonWidget/emoticonWidget.css</file>
|
||||
<file>ui/fileButton/fileButton.css</file>
|
||||
<file>ui/fileButton/fileButton.svg</file>
|
||||
<file>ui/screenshotButton/screenshotButton.css</file>
|
||||
<file>ui/screenshotButton/screenshotButton.svg</file>
|
||||
<file>ui/fileTransferWidget/fileTransferWidget.css</file>
|
||||
<file>ui/friendList/friendList.css</file>
|
||||
<file>ui/micButton/micButton.css</file>
|
||||
|
|
|
@ -85,9 +85,7 @@ ChatForm::ChatForm(Friend* chatFriend)
|
|||
connect(Core::getInstance(), &Core::fileSendStarted, this, &ChatForm::startFileSend);
|
||||
connect(sendButton, &QPushButton::clicked, this, &ChatForm::onSendTriggered);
|
||||
connect(fileButton, &QPushButton::clicked, this, &ChatForm::onAttachClicked);
|
||||
fileButton->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(fileButton, &QPushButton::customContextMenuRequested, this, &ChatForm::onAttachContext);
|
||||
connect(screenshotAction, &QAction::triggered, this, &ChatForm::onScreenshotCreate);
|
||||
connect(screenshotButton, &QPushButton::clicked, this, &ChatForm::onScreenshotClicked);
|
||||
connect(callButton, &QPushButton::clicked, this, &ChatForm::onCallTriggered);
|
||||
connect(videoButton, &QPushButton::clicked, this, &ChatForm::onVideoCallTriggered);
|
||||
connect(msgEdit, &ChatTextEdit::enterPressed, this, &ChatForm::onSendTriggered);
|
||||
|
@ -865,7 +863,7 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered)
|
|||
chatWidget->verticalScrollBar()->setValue(savedSliderPos);
|
||||
}
|
||||
|
||||
void ChatForm::onScreenshotCreate()
|
||||
void ChatForm::onScreenshotClicked()
|
||||
{
|
||||
ScreenshotGrabber *screenshotGrabber = new ScreenshotGrabber (this);
|
||||
connect(screenshotGrabber, &ScreenshotGrabber::screenshotTaken, this, &ChatForm::onScreenshotTaken);
|
||||
|
@ -896,14 +894,6 @@ void ChatForm::onScreenshotTaken (const QPixmap &pixmap) {
|
|||
|
||||
}
|
||||
|
||||
void ChatForm::onAttachContext(const QPoint &pos)
|
||||
{
|
||||
QMenu* context = new QMenu(fileButton);
|
||||
context->addAction(screenshotAction);
|
||||
|
||||
context->exec(fileButton->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void ChatForm::onLoadHistory()
|
||||
{
|
||||
LoadHistoryDialog dlg;
|
||||
|
|
|
@ -95,7 +95,7 @@ private slots:
|
|||
void onLoadHistory();
|
||||
void onUpdateTime();
|
||||
void onEnableCallButtons();
|
||||
void onScreenshotCreate();
|
||||
void onScreenshotClicked();
|
||||
void onScreenshotTaken(const QPixmap &pixmap);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "src/friend.h"
|
||||
#include "src/chatlog/chatlog.h"
|
||||
#include "src/chatlog/content/timestamp.h"
|
||||
#include "src/widget/tool/flyoutoverlaywidget.h"
|
||||
|
||||
GenericChatForm::GenericChatForm(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
|
@ -77,6 +78,8 @@ GenericChatForm::GenericChatForm(QWidget *parent)
|
|||
// Setting the sizes in the CSS doesn't work (glitch with high DPIs)
|
||||
fileButton = new QPushButton();
|
||||
fileButton->setToolTip(tr("Send file(s)"));
|
||||
screenshotButton = new QPushButton;
|
||||
screenshotButton->setToolTip(tr("Send a screenshot"));
|
||||
callButton = new QPushButton();
|
||||
callButton->setFixedSize(50,40);
|
||||
callButton->setToolTip(tr("Start an audio call"));
|
||||
|
@ -89,10 +92,15 @@ GenericChatForm::GenericChatForm(QWidget *parent)
|
|||
micButton = new QPushButton();
|
||||
// micButton->setFixedSize(25,20);
|
||||
micButton->setToolTip("");
|
||||
|
||||
screenshotAction = new QAction(tr("Send screenshot"), nullptr);
|
||||
|
||||
fileFlyout = new FlyoutOverlayWidget;
|
||||
QHBoxLayout *fileLayout = new QHBoxLayout(fileFlyout);
|
||||
fileLayout->addWidget(screenshotButton);
|
||||
fileLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
footButtonsSmall->setSpacing(2);
|
||||
fileLayout->setSpacing(0);
|
||||
fileLayout->setMargin(0);
|
||||
|
||||
msgEdit->setStyleSheet(Style::getStylesheet(":/ui/msgEdit/msgEdit.css"));
|
||||
msgEdit->setFixedHeight(50);
|
||||
|
@ -100,6 +108,7 @@ GenericChatForm::GenericChatForm(QWidget *parent)
|
|||
|
||||
sendButton->setStyleSheet(Style::getStylesheet(":/ui/sendButton/sendButton.css"));
|
||||
fileButton->setStyleSheet(Style::getStylesheet(":/ui/fileButton/fileButton.css"));
|
||||
screenshotButton->setStyleSheet(Style::getStylesheet(":/ui/screenshotButton/screenshotButton.css"));
|
||||
emoteButton->setStyleSheet(Style::getStylesheet(":/ui/emoteButton/emoteButton.css"));
|
||||
|
||||
callButton->setObjectName("green");
|
||||
|
@ -156,6 +165,7 @@ GenericChatForm::GenericChatForm(QWidget *parent)
|
|||
//https://bugreports.qt-project.org/browse/QTBUG-14591
|
||||
sendButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
|
||||
fileButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
|
||||
screenshotButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
|
||||
emoteButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
|
||||
micButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
|
||||
volButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
|
||||
|
@ -175,6 +185,28 @@ GenericChatForm::GenericChatForm(QWidget *parent)
|
|||
|
||||
chatWidget->setStyleSheet(Style::getStylesheet(":/ui/chatArea/chatArea.css"));
|
||||
headWidget->setStyleSheet(Style::getStylesheet(":/ui/chatArea/chatHead.css"));
|
||||
|
||||
fileFlyout->setFixedSize(24, 24);
|
||||
fileFlyout->setParent(this);
|
||||
fileButton->installEventFilter(this);
|
||||
}
|
||||
|
||||
void GenericChatForm::showFileMenu()
|
||||
{
|
||||
if (!fileFlyout->isShown()) {
|
||||
QPoint pos = fileButton->pos();
|
||||
QSize size = fileFlyout->size();
|
||||
fileFlyout->move(pos.x() - size.width(), pos.y());
|
||||
fileFlyout->animateShow();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GenericChatForm::hideFileMenu()
|
||||
{
|
||||
if(fileFlyout->isShown())
|
||||
fileFlyout->animateHide();
|
||||
|
||||
}
|
||||
|
||||
bool GenericChatForm::isEmpty()
|
||||
|
@ -377,4 +409,32 @@ void GenericChatForm::insertChatMessage(ChatMessage::Ptr msg)
|
|||
chatWidget->insertChatlineAtBottom(std::dynamic_pointer_cast<ChatLine>(msg));
|
||||
}
|
||||
|
||||
|
||||
bool GenericChatForm::eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
if (object != this->fileButton)
|
||||
return false;
|
||||
|
||||
switch(event->type())
|
||||
{
|
||||
case QEvent::Enter:
|
||||
showFileMenu();
|
||||
break;
|
||||
|
||||
case QEvent::Leave: {
|
||||
QPoint pos = mapFromGlobal(QCursor::pos());
|
||||
QRect rect (fileFlyout->pos(), fileFlyout->size());
|
||||
|
||||
if (!rect.contains(pos))
|
||||
hideFileMenu();
|
||||
} break;
|
||||
|
||||
case QEvent::MouseButtonPress:
|
||||
hideFileMenu();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ class ChatLog;
|
|||
class MaskablePixmapWidget;
|
||||
class Widget;
|
||||
struct ToxID;
|
||||
class FlyoutOverlayWidget;
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
|
@ -59,6 +60,7 @@ public:
|
|||
|
||||
ChatLog* getChatLog() const;
|
||||
|
||||
bool eventFilter(QObject* object, QEvent* event);
|
||||
signals:
|
||||
void sendMessage(uint32_t, QString);
|
||||
void sendAction(uint32_t, QString);
|
||||
|
@ -76,6 +78,8 @@ protected slots:
|
|||
void clearChatArea(bool);
|
||||
void clearChatArea();
|
||||
void onSelectAllClicked();
|
||||
void showFileMenu();
|
||||
void hideFileMenu();
|
||||
|
||||
protected:
|
||||
QString resolveToxID(const ToxID &id);
|
||||
|
@ -89,8 +93,8 @@ protected:
|
|||
CroppingLabel *nameLabel;
|
||||
MaskablePixmapWidget *avatar;
|
||||
QWidget *headWidget;
|
||||
QPushButton *fileButton, *emoteButton, *callButton, *videoButton, *volButton, *micButton;
|
||||
QAction *screenshotAction;
|
||||
QPushButton *fileButton, *screenshotButton, *emoteButton, *callButton, *videoButton, *volButton, *micButton;
|
||||
FlyoutOverlayWidget *fileFlyout;
|
||||
QVBoxLayout *headTextLayout;
|
||||
ChatTextEdit *msgEdit;
|
||||
QPushButton *sendButton;
|
||||
|
|
100
src/widget/tool/flyoutoverlaywidget.cpp
Normal file
100
src/widget/tool/flyoutoverlaywidget.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
Copyright (C) 2013 by Maxim Biro <nurupo.contributions@gmail.com>
|
||||
|
||||
This file is part of Tox Qt GUI.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#include "flyoutoverlaywidget.h"
|
||||
|
||||
#include <QPropertyAnimation>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPainter>
|
||||
#include <QBitmap>
|
||||
|
||||
FlyoutOverlayWidget::FlyoutOverlayWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
animation = new QPropertyAnimation(this, QByteArrayLiteral("flyoutPercent"), this);
|
||||
animation->setKeyValueAt(0, 0.0f);
|
||||
animation->setKeyValueAt(1, 1.0f);
|
||||
animation->setDuration(200);
|
||||
|
||||
connect(animation, &QAbstractAnimation::finished, this, &FlyoutOverlayWidget::finishedAnimation);
|
||||
setFlyoutPercent(0);
|
||||
show();
|
||||
|
||||
}
|
||||
|
||||
FlyoutOverlayWidget::~FlyoutOverlayWidget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int FlyoutOverlayWidget::animationDuration() const
|
||||
{
|
||||
return animation->duration();
|
||||
}
|
||||
|
||||
void FlyoutOverlayWidget::setAnimationDuration(int timeMs)
|
||||
{
|
||||
animation->setDuration(timeMs);
|
||||
}
|
||||
|
||||
qreal FlyoutOverlayWidget::flyoutPercent() const
|
||||
{
|
||||
return percent;
|
||||
}
|
||||
|
||||
void FlyoutOverlayWidget::setFlyoutPercent(qreal progress)
|
||||
{
|
||||
percent = progress;
|
||||
|
||||
QSize self = size();
|
||||
setMask(QRegion(0, 0, self.width() * progress + 1, self.height()));
|
||||
move(startPos.x() + self.width() - self.width() * percent, startPos.y());
|
||||
setVisible (progress != 0);
|
||||
|
||||
}
|
||||
|
||||
bool FlyoutOverlayWidget::isShown() const
|
||||
{
|
||||
return (percent == 1);
|
||||
}
|
||||
|
||||
void FlyoutOverlayWidget::animateShow()
|
||||
{
|
||||
this->startPos = pos();
|
||||
animation->setDirection(QAbstractAnimation::Forward);
|
||||
animation->start();
|
||||
}
|
||||
|
||||
void FlyoutOverlayWidget::animateHide()
|
||||
{
|
||||
this->startPos = pos();
|
||||
animation->setDirection(QAbstractAnimation::Backward);
|
||||
animation->start();
|
||||
}
|
||||
|
||||
void FlyoutOverlayWidget::leaveEvent(QEvent* event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
animateHide();
|
||||
}
|
||||
|
||||
void FlyoutOverlayWidget::finishedAnimation()
|
||||
{
|
||||
bool hide = (animation->direction() == QAbstractAnimation::Backward);
|
||||
setAttribute(Qt::WA_TransparentForMouseEvents, hide);
|
||||
}
|
57
src/widget/tool/flyoutoverlaywidget.h
Normal file
57
src/widget/tool/flyoutoverlaywidget.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
Copyright (C) 2013 by Maxim Biro <nurupo.contributions@gmail.com>
|
||||
|
||||
This file is part of Tox Qt GUI.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#ifndef FLYOUTOVERLAYWIDGET_HPP
|
||||
#define FLYOUTOVERLAYWIDGET_HPP
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QPropertyAnimation;
|
||||
|
||||
class FlyoutOverlayWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(qreal flyoutPercent READ flyoutPercent WRITE setFlyoutPercent)
|
||||
public:
|
||||
explicit FlyoutOverlayWidget(QWidget *parent = 0);
|
||||
~FlyoutOverlayWidget();
|
||||
|
||||
int animationDuration() const;
|
||||
void setAnimationDuration(int timeMs);
|
||||
|
||||
qreal flyoutPercent() const;
|
||||
void setFlyoutPercent(qreal progress);
|
||||
|
||||
bool isShown() const;
|
||||
|
||||
void animateShow();
|
||||
void animateHide();
|
||||
|
||||
protected:
|
||||
void leaveEvent(QEvent* event);
|
||||
|
||||
private:
|
||||
|
||||
void finishedAnimation();
|
||||
|
||||
QWidget *container;
|
||||
QPropertyAnimation *animation;
|
||||
qreal percent = 1.0f;
|
||||
QPoint startPos;
|
||||
|
||||
};
|
||||
|
||||
#endif // FLYOUTOVERLAYWIDGET_HPP
|
|
@ -14,7 +14,7 @@
|
|||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#include "screengrabberchooserrectitem.hpp"
|
||||
#include "screengrabberchooserrectitem.h"
|
||||
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QGraphicsScene>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#include "screengrabberoverlayitem.hpp"
|
||||
#include "screengrabberoverlayitem.h"
|
||||
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QPainter>
|
||||
|
|
|
@ -26,9 +26,9 @@
|
|||
#include <QScreen>
|
||||
#include <QDebug>
|
||||
|
||||
#include "screengrabberchooserrectitem.hpp"
|
||||
#include "screengrabberoverlayitem.hpp"
|
||||
#include "toolboxgraphicsitem.hpp"
|
||||
#include "screengrabberchooserrectitem.h"
|
||||
#include "screengrabberoverlayitem.h"
|
||||
#include "toolboxgraphicsitem.h"
|
||||
|
||||
ScreenshotGrabber::ScreenshotGrabber(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#include "toolboxgraphicsitem.hpp"
|
||||
#include "toolboxgraphicsitem.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
|
|
31
ui/screenshotButton/screenshotButton.css
Normal file
31
ui/screenshotButton/screenshotButton.css
Normal file
|
@ -0,0 +1,31 @@
|
|||
QPushButton
|
||||
{
|
||||
background-color: #6bc260;
|
||||
background-image: url(":/ui/screenshotButton/screenshotButton.svg");
|
||||
background-repeat: none;
|
||||
background-position: center;
|
||||
border-top-left-radius: 5px;
|
||||
border: none;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
QPushButton:hover
|
||||
{
|
||||
background-color: #79c76f;
|
||||
}
|
||||
|
||||
QPushButton:pressed
|
||||
{
|
||||
background-color: #51b244;
|
||||
}
|
||||
|
||||
QPushButton[enabled="false"]
|
||||
{
|
||||
background-color: #919191;
|
||||
}
|
||||
|
||||
QPushButton:focus
|
||||
{
|
||||
outline: none;
|
||||
}
|
8
ui/screenshotButton/screenshotButton.svg
Normal file
8
ui/screenshotButton/screenshotButton.svg
Normal file
|
@ -0,0 +1,8 @@
|
|||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata id="metadata13">image/svg+xml</metadata>
|
||||
<g>
|
||||
<title>Layer 1</title>
|
||||
<rect ry="1" rx="1" id="svg_6" height="8" width="14" y="3" x="1" stroke-linecap="null" stroke-linejoin="null" stroke-width="2" stroke="#ffffff" fill="none"/>
|
||||
<path id="svg_8" d="m4.50183,15.49984l3.4986,-4.12208l3.49866,4.12208l-6.99725,0z" stroke-linecap="null" stroke-linejoin="null" stroke="#ffffff" fill="#ffffff"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 482 B |
Loading…
Reference in New Issue
Block a user