diff --git a/flameshot.pro b/flameshot.pro index 61f49000..7dba5f83 100644 --- a/flameshot.pro +++ b/flameshot.pro @@ -125,7 +125,9 @@ SOURCES += src/main.cpp \ src/tools/abstractpathtool.cpp \ src/tools/abstracttwopointtool.cpp \ src/tools/abstractactiontool.cpp \ - src/utils/globalvalues.cpp + src/utils/globalvalues.cpp \ + src/widgets/capture/utilitypanel.cpp \ + src/widgets/capture/hovereventfilter.cpp HEADERS += src/widgets/capture/buttonhandler.h \ src/widgets/infowindow.h \ @@ -187,7 +189,9 @@ HEADERS += src/widgets/capture/buttonhandler.h \ src/widgets/capture/modificationcommand.h \ src/tools/abstractpathtool.h \ src/tools/abstracttwopointtool.h \ - src/tools/abstractactiontool.h + src/tools/abstractactiontool.h \ + src/widgets/capture/utilitypanel.h \ + src/widgets/capture/hovereventfilter.h unix:!macx { SOURCES += src/core/flameshotdbusadapter.cpp \ diff --git a/src/tools/launcher/applaunchertool.cpp b/src/tools/launcher/applaunchertool.cpp index fd49d509..67f079b0 100644 --- a/src/tools/launcher/applaunchertool.cpp +++ b/src/tools/launcher/applaunchertool.cpp @@ -47,7 +47,7 @@ QWidget* AppLauncher::widget() { } CaptureTool* AppLauncher::copy(QObject *parent) { - return new AppLauncher(parent); // TODO + return new AppLauncher(parent); } void AppLauncher::pressed(const CaptureContext &context) { diff --git a/src/tools/save/savetool.cpp b/src/tools/save/savetool.cpp index f659b8ac..bc61000b 100644 --- a/src/tools/save/savetool.cpp +++ b/src/tools/save/savetool.cpp @@ -48,7 +48,6 @@ CaptureTool* SaveTool::copy(QObject *parent) { } void SaveTool::pressed(const CaptureContext &context) { - // TODO blocks type and others if (context.savePath.isEmpty()) { emit requestAction(REQ_HIDE_GUI); bool ok = ScreenshotSaver().saveToFilesystemGUI( diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index 2dffb57f..9af777ca 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -22,6 +22,7 @@ // released under the GNU LGPL #include "capturewidget.h" +#include "src/widgets/capture/hovereventfilter.h" #include "src/utils/colorutils.h" #include "src/utils/globalvalues.h" #include "src/widgets/capture/notifierbox.h" @@ -31,6 +32,7 @@ #include "src/utils/screenshotsaver.h" #include "src/core/controller.h" #include "src/widgets/capture/modificationcommand.h" +#include #include #include #include @@ -49,48 +51,32 @@ CaptureWidget::CaptureWidget(const uint id, const QString &savePath, bool fullscreen, QWidget *parent) : QWidget(parent), m_mouseOverHandle(nullptr), m_mouseIsClicked(false), m_rightClick(false), m_newSelection(false), - m_grabbing(false), m_captureDone(false), + m_grabbing(false), m_captureDone(false), m_previewEnabled(true), m_activeButton(nullptr), m_activeTool(nullptr), m_id(id) { + m_eventFilter = new HoverEventFilter(this); + connect(m_eventFilter, &HoverEventFilter::hoverIn, + this, &CaptureWidget::childEnter); + connect(m_eventFilter, &HoverEventFilter::hoverOut, + this, &CaptureWidget::childLeave); + + initContext(savePath, fullscreen); + initSelection(); + + // Base config of the widget + setAttribute(Qt::WA_DeleteOnClose); m_showInitialMsg = m_config.showHelpValue(); m_opacity = m_config.contrastOpacityValue(); - - // Init context - m_context.widgetDimensions = rect(); - // TODO check color handler. No handle on it, just here as it could have - // multiple color pickers - m_context.color = m_config.drawColorValue(); - m_context.savePath = savePath; - m_context.widgetOffset = mapToGlobal(QPoint(0,0)); - m_context.mousePos= mapFromGlobal(QCursor::pos()); - m_context.thickness = m_config.drawThicknessValue(); - m_context.fullscreen = fullscreen; - - setAttribute(Qt::WA_DeleteOnClose); - // create selection handlers - - QRect baseRect(0, 0, handleSize(), handleSize()); - m_TLHandle = baseRect; m_TRHandle = baseRect; - m_BLHandle = baseRect; m_BRHandle = baseRect; - m_LHandle = baseRect; m_THandle = baseRect; - m_RHandle = baseRect; m_BHandle = baseRect; - - m_handles << &m_TLHandle << &m_TRHandle << &m_BLHandle << &m_BRHandle - << &m_LHandle << &m_THandle << &m_RHandle << &m_BHandle; - - m_sides << &m_TLHandle << &m_TRHandle << &m_BLHandle << &m_BRHandle - << &m_LSide << &m_TSide << &m_RSide << &m_BSide; - - // set base config of the widget setMouseTracking(true); updateCursor(); initShortcuts(); #ifdef Q_OS_WIN + // Top left of the whole set of screens QPoint topLeft(0,0); #endif if (m_context.fullscreen) { - // init content + // Grab Screenshot bool ok = true; m_context.screenshot = ScreenGrabber().grabEntireDesktop(ok); if(!ok) { @@ -120,7 +106,7 @@ CaptureWidget::CaptureWidget(const uint id, const QString &savePath, #endif resize(pixmap().size()); } - // create buttons + // Create buttons m_buttonHandler = new ButtonHandler(this); updateButtons(); QVector areas; @@ -137,17 +123,21 @@ CaptureWidget::CaptureWidget(const uint id, const QString &savePath, } m_buttonHandler->updateScreenRegions(areas); m_buttonHandler->hide(); - // init interface color + + + // Init color picker m_colorPicker = new ColorPicker(this); connect(m_colorPicker, &ColorPicker::colorSelected, this, &CaptureWidget::setDrawColor); m_colorPicker->hide(); + // Init notification widget m_notifierBox = new NotifierBox(this); m_notifierBox->hide(); connect(&m_undoStack, &QUndoStack::indexChanged, this, [this](int){ this->update(); }); + initPanel(); } CaptureWidget::~CaptureWidget() { @@ -177,6 +167,7 @@ void CaptureWidget::updateButtons() { m_sizeIndButton = b; } b->setColor(m_uiColor); + makeChild(b); connect(b, &CaptureButton::pressedButton, this, &CaptureWidget::setState); connect(b->tool(), &CaptureTool::requestAction, @@ -198,7 +189,9 @@ void CaptureWidget::paintEvent(QPaintEvent *) { painter.save(); m_activeTool->process(painter, m_context.screenshot); painter.restore(); - } else if (m_activeButton && m_activeButton->tool()->showMousePreview()){ + } else if (m_activeButton && m_activeButton->tool()->showMousePreview() && + m_previewEnabled) + { painter.save(); m_activeButton->tool()->paintMousePreview(painter, m_context); painter.restore(); @@ -272,7 +265,7 @@ void CaptureWidget::mousePressEvent(QMouseEvent *e) { m_mouseIsClicked = true; if (m_activeButton) { if (m_activeTool) { - // TODO + m_activeTool->deleteLater(); } m_activeTool = m_activeButton->tool()->copy(this); connect(m_activeTool, &CaptureTool::requestAction, @@ -280,6 +273,7 @@ void CaptureWidget::mousePressEvent(QMouseEvent *e) { m_activeTool->drawStart(m_context); return; } + m_dragStartPoint = e->pos(); m_selectionBeforeDrag = m_context.selection; if (!m_context.selection.contains(e->pos()) && !m_mouseOverHandle) { @@ -488,6 +482,45 @@ void CaptureWidget::moveEvent(QMoveEvent *e) { m_context.widgetOffset = mapToGlobal(QPoint(0,0)); } +void CaptureWidget::initContext(const QString &savePath, bool fullscreen) { + m_context.widgetDimensions = rect(); + m_context.color = m_config.drawColorValue(); + m_context.savePath = savePath; + m_context.widgetOffset = mapToGlobal(QPoint(0,0)); + m_context.mousePos= mapFromGlobal(QCursor::pos()); + m_context.thickness = m_config.drawThicknessValue(); + m_context.fullscreen = fullscreen; +} + +void CaptureWidget::initPanel() { + m_panel = new UtilityPanel(this); + makeChild(m_panel); + QRect panelRect = QGuiApplication::primaryScreen()->geometry(); + panelRect.moveTo(mapFromGlobal(panelRect.topLeft())); + panelRect.setWidth(m_colorPicker->width() * 3); + m_panel->setGeometry(panelRect); + + m_panel->pushWidget(new QUndoView(&m_undoStack, this)); +} + +void CaptureWidget::initSelection() { + QRect baseRect(0, 0, handleSize(), handleSize()); + m_TLHandle = baseRect; m_TRHandle = baseRect; + m_BLHandle = baseRect; m_BRHandle = baseRect; + m_LHandle = baseRect; m_THandle = baseRect; + m_RHandle = baseRect; m_BHandle = baseRect; + + m_handles << &m_TLHandle << &m_TRHandle << &m_BLHandle << &m_BRHandle + << &m_LHandle << &m_THandle << &m_RHandle << &m_BHandle; + + m_sides << &m_TLHandle << &m_TRHandle << &m_BLHandle << &m_BRHandle + << &m_LSide << &m_TSide << &m_RSide << &m_BSide; +} + +void CaptureWidget::initWidget() { + +} + void CaptureWidget::setState(CaptureButton *b) { if (!b) { return; @@ -521,7 +554,7 @@ void CaptureWidget::processTool(CaptureTool *t) { m_activeTool = backup; QWidget *cw = t->configurationWidget(); if (cw) { - // TODO add to panel. + m_panel->addToolWidget(t->configurationWidget()); } } @@ -555,7 +588,7 @@ void CaptureWidget::handleButtonSignal(CaptureTool::Request r) { update(); break; case CaptureTool::REQ_TOGGLE_SIDEBAR: - // TODO + m_panel->toggle(); break; case CaptureTool::REQ_SHOW_COLOR_PICKER: // TODO @@ -569,7 +602,7 @@ void CaptureWidget::handleButtonSignal(CaptureTool::Request r) { case CaptureTool::REQ_ADD_CHILD_WIDGETS: if (m_activeTool) { QWidget *w = m_activeTool->widget(); - w->setParent(this); + makeChild(w); w->move(m_context.mousePos); w->show(); } @@ -593,7 +626,7 @@ void CaptureWidget::handleButtonSignal(CaptureTool::Request r) { } } -void CaptureWidget::setDrawColor(QColor c) { +void CaptureWidget::setDrawColor(const QColor &c) { m_context.color = c; ConfigHandler().setDrawColor(m_context.color); } @@ -642,12 +675,13 @@ void CaptureWidget::initShortcuts() { new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this, SLOT(close())); new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_S), this, SLOT(saveScreenshot())); new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_C), this, SLOT(copyScreenshot())); - new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Z), this, SLOT(undo())); // TODO + new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Z), this, SLOT(undo())); new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z), this, SLOT(redo())); new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Right), this, SLOT(rightResize())); new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Left), this, SLOT(leftResize())); new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Up), this, SLOT(upResize())); new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Down), this, SLOT(downResize())); + new QShortcut(Qt::Key_Space, this, SLOT(togglePanel())); new QShortcut(Qt::Key_Escape, this, SLOT(close())); new QShortcut(Qt::Key_Return, this, SLOT(copyScreenshot())); } @@ -706,7 +740,25 @@ void CaptureWidget::updateCursor() { } else { setCursor(Qt::CrossCursor); } +} +void CaptureWidget::makeChild(QWidget *w) { + w->setParent(this); + w->installEventFilter(m_eventFilter); +} + +void CaptureWidget::togglePanel() { + m_panel->toggle(); +} + +void CaptureWidget::childEnter() { + m_previewEnabled = false; + update(); +} + +void CaptureWidget::childLeave() { + m_previewEnabled = true; + update(); } int CaptureWidget::handleSize() { diff --git a/src/widgets/capture/capturewidget.h b/src/widgets/capture/capturewidget.h index d29377a3..d793a329 100644 --- a/src/widgets/capture/capturewidget.h +++ b/src/widgets/capture/capturewidget.h @@ -22,11 +22,12 @@ // released under the GNU LGPL #pragma once -// TODO + #include "capturebutton.h" #include "src/tools/capturecontext.h" #include "src/tools/capturetool.h" #include "src/utils/confighandler.h" +#include "src/widgets/capture/utilitypanel.h" #include "buttonhandler.h" #include #include @@ -41,6 +42,7 @@ class QNetworkReply; class ColorPicker; class Screenshot; class NotifierBox; +class HoverEventFilter; class CaptureWidget : public QWidget { Q_OBJECT @@ -68,6 +70,9 @@ private slots: void saveScreenshot(); void undo(); void redo(); + void togglePanel(); + void childEnter(); + void childLeave(); void leftResize(); void rightResize(); @@ -77,7 +82,7 @@ private slots: void setState(CaptureButton *b); void processTool(CaptureTool *t); void handleButtonSignal(CaptureTool::Request r); - void setDrawColor(QColor c); + void setDrawColor(const QColor &c); protected: void paintEvent(QPaintEvent *); @@ -109,12 +114,18 @@ protected: bool m_grabbing; bool m_showInitialMsg; bool m_captureDone; + bool m_previewEnabled; private: + void initContext(const QString &savePath, bool fullscreen); + void initPanel(); + void initSelection(); + void initWidget(); void initShortcuts(); void updateHandles(); void updateSizeIndicator(); void updateCursor(); + void makeChild(QWidget *w); // size of the handlers at the corners of the selection int handleSize(); @@ -128,11 +139,13 @@ private: QPointer m_activeTool; ButtonHandler *m_buttonHandler; + UtilityPanel *m_panel; ColorPicker *m_colorPicker; ConfigHandler m_config; NotifierBox *m_notifierBox; + HoverEventFilter *m_eventFilter; + QPoint m_dragStartPoint; - CaptureButton::ButtonType m_state; uint m_id; // naming convention for handles diff --git a/src/widgets/capture/colorpicker.cpp b/src/widgets/capture/colorpicker.cpp index acc274fe..0ed6d5f9 100644 --- a/src/widgets/capture/colorpicker.cpp +++ b/src/widgets/capture/colorpicker.cpp @@ -50,10 +50,6 @@ ColorPicker::ColorPicker(QWidget *parent) : QWidget(parent) { } } -ColorPicker::~ColorPicker() { - ConfigHandler().setDrawColor(m_drawColor); -} - QColor ColorPicker::drawColor() { return m_drawColor; } diff --git a/src/widgets/capture/colorpicker.h b/src/widgets/capture/colorpicker.h index 2ca17d26..024fd7b1 100644 --- a/src/widgets/capture/colorpicker.h +++ b/src/widgets/capture/colorpicker.h @@ -23,7 +23,6 @@ class ColorPicker : public QWidget { Q_OBJECT public: explicit ColorPicker(QWidget *parent = nullptr); - ~ColorPicker(); QColor drawColor(); diff --git a/src/widgets/capture/hovereventfilter.cpp b/src/widgets/capture/hovereventfilter.cpp new file mode 100644 index 00000000..69531fe3 --- /dev/null +++ b/src/widgets/capture/hovereventfilter.cpp @@ -0,0 +1,44 @@ +// Copyright(c) 2017-2018 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 . + +// Based on Lightscreen areadialog.h, Copyright 2017 Christian Kaiser +// released under the GNU GPL2 + +// Based on KDE's KSnapshot regiongrabber.cpp, revision 796531, Copyright 2007 Luca Gugelmann +// released under the GNU LGPL + +#include "hovereventfilter.h" +#include + +HoverEventFilter::HoverEventFilter(QObject *parent) : QObject(parent) { + +} + +bool HoverEventFilter::eventFilter(QObject *watched, QEvent *event) { + QEvent::Type t = event->type(); + switch (t) { + case QEvent::Enter: + emit hoverIn(watched); + break; + case QEvent::Leave: + emit hoverOut(watched); + break; + default: + break; + } + return false; +} diff --git a/src/widgets/capture/hovereventfilter.h b/src/widgets/capture/hovereventfilter.h new file mode 100644 index 00000000..2805f25b --- /dev/null +++ b/src/widgets/capture/hovereventfilter.h @@ -0,0 +1,40 @@ +// Copyright(c) 2017-2018 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 . + +// Based on Lightscreen areadialog.h, Copyright 2017 Christian Kaiser +// released under the GNU GPL2 + +// Based on KDE's KSnapshot regiongrabber.cpp, revision 796531, Copyright 2007 Luca Gugelmann +// released under the GNU LGPL + +#pragma once + +#include + +class HoverEventFilter : public QObject +{ + Q_OBJECT +public: + explicit HoverEventFilter(QObject *parent = nullptr); + +signals: + void hoverIn(QObject *); + void hoverOut(QObject *); + +protected: + bool eventFilter(QObject *watched, QEvent *event); +}; diff --git a/src/widgets/capture/modificationcommand.cpp b/src/widgets/capture/modificationcommand.cpp index ddc6aa0f..faeaaee0 100644 --- a/src/widgets/capture/modificationcommand.cpp +++ b/src/widgets/capture/modificationcommand.cpp @@ -21,16 +21,13 @@ ModificationCommand::ModificationCommand(QPixmap *p, CaptureTool *t) : m_pixmap(p), m_tool(t) { + setText(t->name()); } void ModificationCommand::undo() { m_tool->undo(*m_pixmap); } -QString ModificationCommand::text() const { - return m_tool->name(); -} - void ModificationCommand::redo() { QPainter p(m_pixmap); p.setRenderHint(QPainter::Antialiasing); diff --git a/src/widgets/capture/modificationcommand.h b/src/widgets/capture/modificationcommand.h index 7fe537ef..ab607f53 100644 --- a/src/widgets/capture/modificationcommand.h +++ b/src/widgets/capture/modificationcommand.h @@ -26,7 +26,7 @@ public: virtual void undo() override; virtual void redo() override; - QString text() const; + private: QPixmap *m_pixmap; QScopedPointer m_tool; diff --git a/src/widgets/capture/utilitypanel.cpp b/src/widgets/capture/utilitypanel.cpp new file mode 100644 index 00000000..69d0a1fb --- /dev/null +++ b/src/widgets/capture/utilitypanel.cpp @@ -0,0 +1,89 @@ +// Copyright(c) 2017-2018 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 . + +// Based on Lightscreen areadialog.h, Copyright 2017 Christian Kaiser +// released under the GNU GPL2 + +// Based on KDE's KSnapshot regiongrabber.cpp, revision 796531, Copyright 2007 Luca Gugelmann +// released under the GNU LGPL + +#include "utilitypanel.h" +#include +#include +#include +#include +#include + +UtilityPanel::UtilityPanel(QWidget *parent) : QWidget(parent) { + initInternalPanel(); + + m_showAnimation = new QPropertyAnimation(m_internalPanel, "geometry", this); + m_showAnimation->setEasingCurve(QEasingCurve::InOutQuad); + m_showAnimation->setDuration(300); + + m_hideAnimation = new QPropertyAnimation(m_internalPanel, "geometry", this); + m_hideAnimation->setEasingCurve(QEasingCurve::InOutQuad); + m_hideAnimation->setDuration(300); + + connect(m_hideAnimation, &QPropertyAnimation::finished, + m_internalPanel, &QWidget::hide); +} + +void UtilityPanel::addToolWidget(QWidget *w) { + if (m_toolWidget) { + m_toolWidget->deleteLater(); + m_toolWidget = w; + m_upLayout->addWidget(w); + } +} + +void UtilityPanel::pushWidget(QWidget *w) { + m_layout->addWidget(w); +} + +void UtilityPanel::toggle() { + if (m_internalPanel->isHidden()) { + m_showAnimation->setStartValue(QRect(-width(), 0, 0, height())); + m_showAnimation->setEndValue(QRect(0, 0, width(), height())); + m_internalPanel->show(); + m_showAnimation->start(); + } else { + m_hideAnimation->setStartValue(QRect(0, 0, width(), height())); + m_hideAnimation->setEndValue(QRect(-width(), 0, 0, height())); + m_hideAnimation->start(); + } + +} + +void UtilityPanel::initInternalPanel() { + m_internalPanel = new QScrollArea(this); + m_internalPanel->setAttribute(Qt::WA_NoMousePropagation); + QWidget *widget = new QWidget(); + m_internalPanel->setWidget(widget); + m_internalPanel->setWidgetResizable(true); + + m_layout = new QVBoxLayout(); + m_upLayout = new QVBoxLayout(); + m_layout->addLayout(m_upLayout); + widget->setLayout(m_layout); + + QColor bgColor = palette().background().color(); + bgColor.setAlphaF(0.0); + m_internalPanel->setStyleSheet(QString("QScrollArea {background-color: %1}") + .arg(bgColor.name())); + m_internalPanel->hide(); +} diff --git a/src/widgets/capture/utilitypanel.h b/src/widgets/capture/utilitypanel.h new file mode 100644 index 00000000..0228a67a --- /dev/null +++ b/src/widgets/capture/utilitypanel.h @@ -0,0 +1,57 @@ +// Copyright(c) 2017-2018 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 . + +// Based on Lightscreen areadialog.h, Copyright 2017 Christian Kaiser +// released under the GNU GPL2 + +// Based on KDE's KSnapshot regiongrabber.cpp, revision 796531, Copyright 2007 Luca Gugelmann +// released under the GNU LGPL + +#pragma once + +#include +#include + +class QVBoxLayout; +class QPropertyAnimation; +class QScrollArea; + +class UtilityPanel : public QWidget { + Q_OBJECT +public: + explicit UtilityPanel(QWidget *parent = nullptr); + + void addToolWidget(QWidget *w); + void pushWidget(QWidget *w); + +signals: + void mouseEnter(); + void mouseLeave(); + +public slots: + void toggle(); + +private: + void initInternalPanel(); + + QPointer m_toolWidget; + QScrollArea *m_internalPanel; + QVBoxLayout *m_upLayout; + QVBoxLayout *m_layout; + QPropertyAnimation *m_showAnimation; + QPropertyAnimation *m_hideAnimation; +};