diff --git a/src/config/generalconf.cpp b/src/config/generalconf.cpp index 30020f7d..41bf2720 100644 --- a/src/config/generalconf.cpp +++ b/src/config/generalconf.cpp @@ -56,6 +56,7 @@ GeneralConf::GeneralConf(QWidget* parent) #endif initPredefinedColorPaletteLarge(); initCopyOnDoubleClick(); + initshowSelectionGeometry(); m_layout->addStretch(); @@ -104,6 +105,8 @@ void GeneralConf::_updateComponents(bool allowEmptySavePath) #if defined(Q_OS_LINUX) || defined(Q_OS_UNIX) m_showTray->setChecked(!config.disabledTrayIcon()); #endif + // m_showSelectionGeometry->setChecked( + // config.value("showSelectionGeometry").toBool()); } void GeneralConf::updateComponents() @@ -707,6 +710,73 @@ void GeneralConf::initSquareMagnifier() }); } +void GeneralConf::initshowSelectionGeometry() +{ + auto* tobox = new QHBoxLayout(); + + int timeout = + ConfigHandler().value("showSelectionGeometryHideTime").toInt(); + m_xywhTimeout = new QSpinBox(); + m_xywhTimeout->setRange(0, INT_MAX); + m_xywhTimeout->setToolTip( + tr("Milliseconds before geometry display hides; 0 means do not hide")); + m_xywhTimeout->setValue(timeout); + tobox->addWidget(m_xywhTimeout); + tobox->addWidget(new QLabel(tr("Set geometry display timeout (ms)"))); + + m_scrollAreaLayout->addLayout(tobox); + connect(m_xywhTimeout, + SIGNAL(valueChanged(int)), + this, + SLOT(setSelGeoHideTime(int))); + + auto* box = new QGroupBox(tr("Selection Geometry Display")); + box->setFlat(true); + m_layout->addWidget(box); + + auto* vboxLayout = new QVBoxLayout(); + box->setLayout(vboxLayout); + auto* selgeoLayout = new QHBoxLayout(); + selgeoLayout->addWidget(new QLabel(tr("Display Location"))); + m_selectGeometryLocation = new QComboBox(this); + + m_selectGeometryLocation->addItem(tr("None"), GeneralConf::xywh_none); + m_selectGeometryLocation->addItem(tr("Top Left"), + GeneralConf::xywh_top_left); + m_selectGeometryLocation->addItem(tr("Top Right"), + GeneralConf::xywh_top_right); + m_selectGeometryLocation->addItem(tr("Bottom Left"), + GeneralConf::xywh_bottom_left); + m_selectGeometryLocation->addItem(tr("Bottom Right"), + GeneralConf::xywh_bottom_right); + m_selectGeometryLocation->addItem(tr("Center"), GeneralConf::xywh_center); + + // pick up int from config and use findData + int pos = ConfigHandler().value("showSelectionGeometry").toInt(); + m_selectGeometryLocation->setCurrentIndex( + m_selectGeometryLocation->findData(pos)); + + connect(m_selectGeometryLocation, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(setGeometryLocation(int))); + + selgeoLayout->addWidget(m_selectGeometryLocation); + vboxLayout->addLayout(selgeoLayout); + vboxLayout->addStretch(); +} + +void GeneralConf::setSelGeoHideTime(int v) +{ + ConfigHandler().setValue("showSelectionGeometryHideTime", v); +} + +void GeneralConf::setGeometryLocation(int index) +{ + ConfigHandler().setValue("showSelectionGeometry", + m_selectGeometryLocation->itemData(index)); +} + void GeneralConf::togglePathFixed() { ConfigHandler().setSavePathFixed(m_screenshotPathFixedCheck->isChecked()); diff --git a/src/config/generalconf.h b/src/config/generalconf.h index a1178cf5..fe4c6b52 100644 --- a/src/config/generalconf.h +++ b/src/config/generalconf.h @@ -19,6 +19,15 @@ class GeneralConf : public QWidget Q_OBJECT public: explicit GeneralConf(QWidget* parent = nullptr); + enum xywh_position + { + xywh_none = 0, + xywh_top_left = 1, + xywh_bottom_left = 2, + xywh_top_right = 3, + xywh_bottom_right = 4, + xywh_center = 5 + }; public slots: void updateComponents(); @@ -44,6 +53,8 @@ private slots: void uploadClientKeyEdited(); void useJpgForClipboardChanged(bool checked); void setSaveAsFileExtension(QString extension); + void setGeometryLocation(int index); + void setSelGeoHideTime(int v); private: const QString chooseFolder(const QString currentPath = ""); @@ -74,6 +85,7 @@ private: void initUploadHistoryMax(); void initUploadClientSecret(); void initSaveLastRegion(); + void initshowSelectionGeometry(); void _updateComponents(bool allowEmptySavePath); @@ -112,4 +124,7 @@ private: QCheckBox* m_showMagnifier; QCheckBox* m_squareMagnifier; QCheckBox* m_copyOnDoubleClick; + QCheckBox* m_showSelectionGeometry; + QComboBox* m_selectGeometryLocation; + QSpinBox* m_xywhTimeout; }; diff --git a/src/utils/confighandler.cpp b/src/utils/confighandler.cpp index 657e8963..34d00d73 100644 --- a/src/utils/confighandler.cpp +++ b/src/utils/confighandler.cpp @@ -121,6 +121,8 @@ static QMap> // drawFontSize, remember to update ConfigHandler::toolSize OPTION("copyOnDoubleClick" ,Bool ( false )), OPTION("uploadClientSecret" ,String ( "313baf0c7b4d3ff" )), + OPTION("showSelectionGeometry" , BoundedInt (0,5,4)), + OPTION("showSelectionGeometryHideTime", LowerBoundedInt (0, 3000)) }; static QMap> recognizedShortcuts = { diff --git a/src/utils/confighandler.h b/src/utils/confighandler.h index 3be5953a..cd87c8db 100644 --- a/src/utils/confighandler.h +++ b/src/utils/confighandler.h @@ -120,6 +120,7 @@ public: CONFIG_GETTER_SETTER(copyOnDoubleClick, setCopyOnDoubleClick, bool) CONFIG_GETTER_SETTER(uploadClientSecret, setUploadClientSecret, QString) CONFIG_GETTER_SETTER(saveLastRegion, setSaveLastRegion, bool) + CONFIG_GETTER_SETTER(showSelectionGeometry, setshowSelectionGeometry, int) // SPECIAL CASES bool startupLaunch(); void setStartupLaunch(const bool); diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index 4282159a..97fa7a86 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -13,6 +13,7 @@ #include "abstractlogger.h" #include "copytool.h" #include "src/config/cacheutils.h" +#include "src/config/generalconf.h" #include "src/core/flameshot.h" #include "src/core/qguiappcurrentscreen.h" #include "src/tools/toolfactory.h" @@ -72,9 +73,10 @@ CaptureWidget::CaptureWidget(const CaptureRequest& req, , m_existingObjectIsChanged(false) , m_startMove(false) , m_toolSizeByKeyboard(0) + , m_xywhDisplay(false) + { m_undoStack.setUndoLimit(ConfigHandler().undoLimit()); - m_context.circleCount = 1; // Base config of the widget @@ -87,6 +89,8 @@ CaptureWidget::CaptureWidget(const CaptureRequest& req, &HoverEventFilter::hoverOut, this, &CaptureWidget::childLeave); + + connect(&m_xywhTimer, SIGNAL(timeout()), this, SLOT(xywhTick())); setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_QuitOnClose, false); m_opacity = m_config.contrastOpacity(); @@ -375,6 +379,24 @@ void CaptureWidget::handleButtonLeftClick(CaptureToolButton* b) setState(b); } +void CaptureWidget::xywhTick() +{ + m_xywhDisplay = false; + repaint(); +} + +void CaptureWidget::showxywh(bool show) +{ + int timeout = + ConfigHandler().value("showSelectionGeometryHideTime").toInt(); + m_xywhDisplay = show; + m_xywhTimer.stop(); + repaint(); + if (show && timeout != 0) { + m_xywhTimer.start(timeout); + } +} + void CaptureWidget::initHelpMessage() { QList> keyMap; @@ -488,19 +510,101 @@ void CaptureWidget::paintEvent(QPaintEvent* paintEvent) { Q_UNUSED(paintEvent) QPainter painter(this); + GeneralConf::xywh_position position = + static_cast( + ConfigHandler().value("showSelectionGeometry").toInt()); + /* QPainter::save and restore is somewhat costly so we try to guess + if we need to do it here. What that means is that if you add + anything to the paintEvent and want to save/restore you should + add a test to the below if statement -- also if you change + any of the conditions that current trigger it you'll need to change here, + too + */ + bool save = false; + if (((position != GeneralConf::xywh_none && + m_selection && // clause 1: xywh display + m_xywhDisplay)) || + (m_activeTool && m_mouseIsClicked) || // clause 2: tool/click + (m_previewEnabled && activeButtonTool() && // clause 3: mouse preview + m_activeButton->tool()->showMousePreview())) { + painter.save(); + save = true; + } painter.drawPixmap(0, 0, m_context.screenshot); + if (position != GeneralConf::xywh_none && m_selection && m_xywhDisplay) { + const QRect& selection = m_selection->geometry().normalized(); + const qreal scale = m_context.screenshot.devicePixelRatio(); + QRect xybox; + QFontMetrics fm = painter.fontMetrics(); - if (m_activeTool && m_mouseIsClicked) { - painter.save(); - m_activeTool->process(painter, m_context.screenshot); - painter.restore(); - } else if (m_previewEnabled && activeButtonTool() && - m_activeButton->tool()->showMousePreview()) { - painter.save(); - m_activeButton->tool()->paintMousePreview(painter, m_context); - painter.restore(); + QString xy = QString("%1x%2+%3+%4") + .arg(static_cast(selection.left() * scale)) + .arg(static_cast(selection.top() * scale)) + .arg(static_cast(selection.width() * scale)) + .arg(static_cast(selection.height() * scale)); + + xybox = fm.boundingRect(xy); + // the small numbers here are just margins so the text doesn't + // smack right up to the box; they aren't critical and the box + // size itself is tied to the font metrics + xybox.adjust(0, 0, 10, 12); + // in anticipation of making the position adjustable + int x0, y0; + // Move these to header + +// adjust for small selection +#if 0 // seems more usable not to do this + if (xybox.width() > selection.width()) + xybox.setWidth(selection.width()); + if (xybox.height() > selection.height()) + xybox.setHeight(selection.height()); +#endif + switch (position) { + case GeneralConf::xywh_top_left: + x0 = selection.left(); + y0 = selection.top(); + break; + case GeneralConf::xywh_bottom_left: + x0 = selection.left(); + y0 = selection.bottom() - xybox.height(); + break; + case GeneralConf::xywh_top_right: + x0 = selection.right() - xybox.width(); + y0 = selection.top(); + break; + case GeneralConf::xywh_bottom_right: + x0 = selection.right() - xybox.width(); + y0 = selection.bottom() - xybox.height(); + break; + case GeneralConf::xywh_center: + default: + x0 = selection.left() + (selection.width() - xybox.width()) / 2; + y0 = + selection.top() + (selection.height() - xybox.height()) / 2; + } + + QColor uicolor = ConfigHandler().uiColor(); + uicolor.setAlpha(200); + painter.fillRect( + x0, y0, xybox.width(), xybox.height(), QBrush(uicolor)); + painter.setPen(ColorUtils::colorIsDark(uicolor) ? Qt::white + : Qt::black); + painter.drawText(x0, + y0, + xybox.width(), + xybox.height(), + Qt::AlignVCenter | Qt::AlignHCenter, + xy); } + if (m_activeTool && m_mouseIsClicked) { + m_activeTool->process(painter, m_context.screenshot); + } else if (m_previewEnabled && activeButtonTool() && + m_activeButton->tool()->showMousePreview()) { + m_activeButton->tool()->paintMousePreview(painter, m_context); + } + if (save) + painter.restore(); // draw inactive region drawInactiveRegion(&painter); @@ -614,7 +718,6 @@ void CaptureWidget::mousePressEvent(QMouseEvent* e) updateCursor(); return; } - // reset object selection if capture area selection is active if (m_selection->getMouseSide(e->pos()) != SelectionWidget::CENTER) { m_panel->setActiveLayer(-1); @@ -646,7 +749,6 @@ void CaptureWidget::mousePressEvent(QMouseEvent* e) } selectToolItemAtPos(m_mousePressedPos); - updateSelectionState(); updateCursor(); } @@ -1431,6 +1533,7 @@ void CaptureWidget::deleteCurrentTool() void CaptureWidget::updateSizeIndicator() { + showxywh(); // Note: even if sizeIndButton goes away, we have to keep this! if (m_sizeIndButton) { const QRect& selection = extendedSelection(); m_sizeIndButton->setText(QStringLiteral("%1\n%2") diff --git a/src/widgets/capture/capturewidget.h b/src/widgets/capture/capturewidget.h index edff083a..b994c346 100644 --- a/src/widgets/capture/capturewidget.h +++ b/src/widgets/capture/capturewidget.h @@ -14,12 +14,14 @@ #include "buttonhandler.h" #include "capturetoolbutton.h" #include "capturetoolobjects.h" +#include "src/config/generalconf.h" #include "src/tools/capturecontext.h" #include "src/tools/capturetool.h" #include "src/utils/confighandler.h" #include "src/widgets/capture/magnifierwidget.h" #include "src/widgets/capture/selectionwidget.h" #include +#include #include #include @@ -80,9 +82,11 @@ private slots: void onMoveCaptureToolUp(int captureToolIndex); void onMoveCaptureToolDown(int captureToolIndex); void selectAll(); + void xywhTick(); public: void removeToolObject(int index = -1); + void showxywh(bool show = true); protected: void paintEvent(QPaintEvent* paintEvent) override; @@ -193,6 +197,10 @@ private: QPoint m_mousePressedPos; QPoint m_activeToolOffsetToMouseOnStart; + // XYWH display position and timer + bool m_xywhDisplay; + QTimer m_xywhTimer; + QUndoStack m_undoStack; bool m_existingObjectIsChanged;