add sidepanel button to make UI more intuitive and accessible without keyboard (tablets, etc.) (#631)

* add sidepanel toggle button and close button #613

* add side panel toggle button option

* make sidepanel button draggable
This commit is contained in:
Alex Pantechovskis
2020-09-12 23:55:51 +03:00
committed by GitHub
parent 962bba9640
commit 5f2132f91e
12 changed files with 351 additions and 5 deletions

View File

@@ -36,6 +36,7 @@ GeneneralConf::GeneneralConf(QWidget* parent)
m_layout = new QVBoxLayout(this);
m_layout->setAlignment(Qt::AlignTop);
initShowHelp();
initShowSidePanelButton();
initShowDesktopNotification();
initShowTrayIcon();
initAutostart();
@@ -53,6 +54,7 @@ GeneneralConf::updateComponents()
{
ConfigHandler config;
m_helpMessage->setChecked(config.showHelpValue());
m_sidePanelButton->setChecked(config.showSidePanelButtonValue());
m_sysNotifications->setChecked(config.desktopNotificationValue());
m_autostart->setChecked(config.startupLaunchValue());
m_closeAfterCapture->setChecked(config.closeAfterScreenshotValue());
@@ -78,6 +80,12 @@ GeneneralConf::showHelpChanged(bool checked)
ConfigHandler().setShowHelp(checked);
}
void
GeneneralConf::showSidePanelButtonChanged(bool checked)
{
ConfigHandler().setShowSidePanelButton(checked);
}
void
GeneneralConf::showDesktopNotificationChanged(bool checked)
{
@@ -182,6 +190,20 @@ GeneneralConf::initShowHelp()
m_helpMessage, &QCheckBox::clicked, this, &GeneneralConf::showHelpChanged);
}
void
GeneneralConf::initShowSidePanelButton()
{
m_sidePanelButton = new QCheckBox(tr("Show the side panel button"), this);
m_sidePanelButton->setChecked(ConfigHandler().showSidePanelButtonValue());
m_sidePanelButton->setToolTip(
tr("Show the side panel toggle button in the capture mode."));
m_layout->addWidget(m_sidePanelButton);
connect(m_sidePanelButton,
&QCheckBox::clicked,
this,
&GeneneralConf::showSidePanelButtonChanged);
}
void
GeneneralConf::initShowDesktopNotification()
{

View File

@@ -36,6 +36,7 @@ public slots:
private slots:
void showHelpChanged(bool checked);
void showSidePanelButtonChanged(bool checked);
void showDesktopNotificationChanged(bool checked);
void showTrayIconChanged(bool checked);
void autostartChanged(bool checked);
@@ -51,6 +52,7 @@ private:
QCheckBox* m_sysNotifications;
QCheckBox* m_showTray;
QCheckBox* m_helpMessage;
QCheckBox* m_sidePanelButton;
QCheckBox* m_autostart;
QCheckBox* m_closeAfterCapture;
QCheckBox* m_copyAndCloseAfterUpload;
@@ -62,6 +64,7 @@ private:
QPushButton* m_changeSaveButton;
void initShowHelp();
void initShowSidePanelButton();
void initShowDesktopNotification();
void initShowTrayIcon();
void initConfingButtons();

View File

@@ -208,6 +208,19 @@ ConfigHandler::setShowHelp(const bool showHelp)
m_settings.setValue(QStringLiteral("showHelp"), showHelp);
}
bool
ConfigHandler::showSidePanelButtonValue()
{
return m_settings.value(QStringLiteral("showSidePanelButton"), true).toBool();
}
void
ConfigHandler::setShowSidePanelButton(const bool showSidePanelButton)
{
m_settings.setValue(QStringLiteral("showSidePanelButton"),
showSidePanelButton);
}
bool
ConfigHandler::desktopNotificationValue()
{

View File

@@ -47,6 +47,9 @@ public:
bool showHelpValue();
void setShowHelp(const bool);
bool showSidePanelButtonValue();
void setShowSidePanelButton(const bool);
bool desktopNotificationValue();
void setDesktopNotification(const bool);

View File

@@ -5,15 +5,19 @@ add_subdirectory(capture)
target_sources(
flameshot
PRIVATE capturelauncher.h
draggablewidgetmaker.h
imagelabel.h
infowindow.h
loadspinner.h
notificationwidget.h)
notificationwidget.h
orientablepushbutton.h)
target_sources(
flameshot
PRIVATE capturelauncher.cpp
draggablewidgetmaker.cpp
imagelabel.cpp
infowindow.cpp
loadspinner.cpp
notificationwidget.cpp)
notificationwidget.cpp
orientablepushbutton.cpp)

View File

@@ -34,6 +34,7 @@
#include "src/widgets/capture/hovereventfilter.h"
#include "src/widgets/capture/modificationcommand.h"
#include "src/widgets/capture/notifierbox.h"
#include "src/widgets/orientablepushbutton.h"
#include "src/widgets/panel/sidepanelwidget.h"
#include <QApplication>
#include <QBuffer>
@@ -45,6 +46,7 @@
#include <QScreen>
#include <QShortcut>
#include <QUndoView>
#include <draggablewidgetmaker.h>
// CaptureWidget is the main component used to capture the screen. It contains
// an are of selection with its respective buttons.
@@ -602,12 +604,42 @@ CaptureWidget::initContext(const QString& savePath, bool fullscreen)
void
CaptureWidget::initPanel()
{
m_panel = new UtilityPanel(this);
makeChild(m_panel);
QRect panelRect = rect();
if (m_context.fullscreen) {
panelRect = QGuiApplication::primaryScreen()->geometry();
}
ConfigHandler config;
if (config.showSidePanelButtonValue()) {
auto* panelToggleButton =
new OrientablePushButton(tr("Tool Settings"), this);
makeChild(panelToggleButton);
panelToggleButton->setOrientation(
OrientablePushButton::VerticalBottomToTop);
panelToggleButton->move(panelRect.x(),
panelRect.y() + panelRect.height() / 2 -
panelToggleButton->width() / 2);
panelToggleButton->setCursor(Qt::ArrowCursor);
(new DraggableWidgetMaker(this))->makeDraggable(panelToggleButton);
connect(panelToggleButton,
&QPushButton::clicked,
this,
&CaptureWidget::togglePanel);
QColor mainColor = config.uiMainColorValue();
QColor textColor =
ColorUtils::colorIsDark(mainColor) ? Qt::white : Qt::black;
QPalette palette = panelToggleButton->palette();
palette.setColor(QPalette::Button, mainColor);
palette.setColor(QPalette::ButtonText, textColor);
panelToggleButton->setAutoFillBackground(true);
panelToggleButton->setPalette(palette);
panelToggleButton->update();
}
m_panel = new UtilityPanel(this);
makeChild(m_panel);
panelRect.moveTo(mapFromGlobal(panelRect.topLeft()));
panelRect.setWidth(m_colorPicker->width() * 3);
m_panel->setGeometry(panelRect);

View File

@@ -0,0 +1,81 @@
// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors
//
// This file is part of Flameshot.
//
// Flameshot 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.
//
// Flameshot 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
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
#include "draggablewidgetmaker.h"
#include <QMouseEvent>
DraggableWidgetMaker::DraggableWidgetMaker(QObject* parent)
: QObject(parent)
{}
void
DraggableWidgetMaker::makeDraggable(QWidget* widget)
{
widget->installEventFilter(this);
}
bool
DraggableWidgetMaker::eventFilter(QObject* obj, QEvent* event)
{
auto widget = static_cast<QWidget*>(obj);
// based on https://stackoverflow.com/a/12221360/964478
switch (event->type()) {
case QEvent::MouseButtonPress: {
auto mouseEvent = static_cast<QMouseEvent*>(event);
m_isPressing = false;
m_isDragging = false;
if (mouseEvent->button() == Qt::LeftButton) {
m_isPressing = true;
m_mousePressPos = mouseEvent->globalPos();
m_mouseMovePos = m_mousePressPos;
}
} break;
case QEvent::MouseMove: {
auto mouseEvent = static_cast<QMouseEvent*>(event);
if (m_isPressing) {
QPoint widgetPos = widget->mapToGlobal(widget->pos());
QPoint eventPos = mouseEvent->globalPos();
QPoint diff = eventPos - m_mouseMovePos;
QPoint newPos = widgetPos + diff;
widget->move(widget->mapFromGlobal(newPos));
if (!m_isDragging) {
QPoint totalMovedDiff = eventPos - m_mousePressPos;
if (totalMovedDiff.manhattanLength() > 3) {
m_isDragging = true;
}
}
m_mouseMovePos = eventPos;
}
} break;
case QEvent::MouseButtonRelease: {
if (m_isDragging) {
m_isPressing = false;
m_isDragging = false;
event->ignore();
return true;
}
} break;
}
return QObject::eventFilter(obj, event);
}

View File

@@ -0,0 +1,41 @@
// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors
//
// This file is part of Flameshot.
//
// Flameshot 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.
//
// Flameshot 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
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
#pragma once
#include <QEvent>
#include <QObject>
#include <QPoint>
#include <QWidget>
class DraggableWidgetMaker : public QObject
{
Q_OBJECT
public:
DraggableWidgetMaker(QObject* parent = nullptr);
void makeDraggable(QWidget* widget);
protected:
bool eventFilter(QObject* obj, QEvent* event) override;
private:
bool m_isPressing = false;
bool m_isDragging = false;
QPoint m_mouseMovePos;
QPoint m_mousePressPos;
};

View File

@@ -0,0 +1,87 @@
// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors
//
// This file is part of Flameshot.
//
// Flameshot 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.
//
// Flameshot 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
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
// Based on https://stackoverflow.com/a/53135675/964478
#include "orientablepushbutton.h"
#include <QDebug>
#include <QPainter>
#include <QStyleOptionButton>
#include <QStylePainter>
OrientablePushButton::OrientablePushButton(QWidget* parent)
: QPushButton(parent)
{}
OrientablePushButton::OrientablePushButton(const QString& text, QWidget* parent)
: QPushButton(text, parent)
{}
OrientablePushButton::OrientablePushButton(const QIcon& icon,
const QString& text,
QWidget* parent)
: QPushButton(icon, text, parent)
{}
QSize
OrientablePushButton::sizeHint() const
{
QSize sh = QPushButton::sizeHint();
if (m_orientation != OrientablePushButton::Horizontal) {
sh.transpose();
}
return sh;
}
void
OrientablePushButton::paintEvent(QPaintEvent* event)
{
Q_UNUSED(event)
QStylePainter painter(this);
QStyleOptionButton option;
initStyleOption(&option);
if (m_orientation == OrientablePushButton::VerticalTopToBottom) {
painter.rotate(90);
painter.translate(0, -1 * width());
option.rect = option.rect.transposed();
}
else if (m_orientation == OrientablePushButton::VerticalBottomToTop) {
painter.rotate(-90);
painter.translate(-1 * height(), 0);
option.rect = option.rect.transposed();
}
painter.drawControl(QStyle::CE_PushButton, option);
}
OrientablePushButton::Orientation
OrientablePushButton::orientation() const
{
return m_orientation;
}
void
OrientablePushButton::setOrientation(
const OrientablePushButton::Orientation& orientation)
{
m_orientation = orientation;
}

View File

@@ -0,0 +1,51 @@
// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors
//
// This file is part of Flameshot.
//
// Flameshot 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.
//
// Flameshot 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
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
// Based on https://stackoverflow.com/a/53135675/964478
#pragma once
#include <QPushButton>
class OrientablePushButton : public QPushButton
{
Q_OBJECT
public:
enum Orientation
{
Horizontal,
VerticalTopToBottom,
VerticalBottomToTop
};
OrientablePushButton(QWidget* parent = nullptr);
OrientablePushButton(const QString& text, QWidget* parent = nullptr);
OrientablePushButton(const QIcon& icon,
const QString& text,
QWidget* parent = nullptr);
QSize sizeHint() const;
OrientablePushButton::Orientation orientation() const;
void setOrientation(const OrientablePushButton::Orientation& orientation);
protected:
void paintEvent(QPaintEvent* event);
private:
Orientation m_orientation = Horizontal;
};

View File

@@ -17,6 +17,7 @@
#include "utilitypanel.h"
#include <QPropertyAnimation>
#include <QPushButton>
#include <QScrollArea>
#include <QTimer>
#include <QVBoxLayout>
@@ -72,7 +73,7 @@ UtilityPanel::clearToolWidget()
void
UtilityPanel::pushWidget(QWidget* w)
{
m_layout->addWidget(w);
m_layout->insertWidget(m_layout->count() - 1, w);
}
void
@@ -103,9 +104,16 @@ UtilityPanel::initInternalPanel()
m_layout = new QVBoxLayout();
m_upLayout = new QVBoxLayout();
m_bottomLayout = new QVBoxLayout();
m_layout->addLayout(m_upLayout);
m_layout->addLayout(m_bottomLayout);
widget->setLayout(m_layout);
QPushButton* closeButton = new QPushButton(this);
closeButton->setText(tr("Close"));
connect(closeButton, &QPushButton::clicked, this, &UtilityPanel::toggle);
m_bottomLayout->addWidget(closeButton);
QColor bgColor = palette().window().color();
bgColor.setAlphaF(0.0);
m_internalPanel->setStyleSheet(

View File

@@ -48,6 +48,7 @@ private:
QPointer<QWidget> m_toolWidget;
QScrollArea* m_internalPanel;
QVBoxLayout* m_upLayout;
QVBoxLayout* m_bottomLayout;
QVBoxLayout* m_layout;
QPropertyAnimation* m_showAnimation;
QPropertyAnimation* m_hideAnimation;