Commit bcc7b92c authored by Noah Davis's avatar Noah Davis 🌵
Browse files

Use decorated tags in info sidebar

It would probably be a good idea to turn these into interactive tags one day. For now, they are not interactive, but at least they make the list of tags more attractive and readable. If they are ever made interactive, they should probably be changed to have a more interactive looking appearance.
parent d82258c4
......@@ -68,6 +68,7 @@ find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS
WindowSystem
IconThemes
Notifications
GuiAddons
WidgetsAddons
)
find_package(KF5 ${KF5_MIN_VERSION} OPTIONAL_COMPONENTS
......
......@@ -46,8 +46,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA
#include "ui_semanticinfosidebaritem.h"
#include "ui_semanticinfodialog.h"
#include <lib/contextmanager.h>
#include <lib/decoratedtag/decoratedtag.h>
#include <lib/documentview/documentview.h>
#include <lib/eventwatcher.h>
#include <lib/flowlayout.h>
#include <lib/hud/hudwidget.h>
#include <lib/signalblocker.h>
#include <lib/widgetfloater.h>
......@@ -167,6 +169,8 @@ struct SemanticInfoContextManagerItemPrivate : public Ui_SemanticInfoSideBarItem
/** A list of all actions, so that we can disable them when necessary */
QList<QAction *> mActions;
QPointer<RatingIndicator> mRatingIndicator;
FlowLayout *mTagLayout;
QLabel *mEditLabel;
void setupGroup()
{
......@@ -178,13 +182,27 @@ struct SemanticInfoContextManagerItemPrivate : public Ui_SemanticInfoSideBarItem
setupUi(container);
container->layout()->setContentsMargins(0, 0, 0, 0);
mGroup->addWidget(container);
mTagLayout = new FlowLayout;
mTagLayout->setHorizontalSpacing(2);
mTagLayout->setVerticalSpacing(2);
mTagLayout->setContentsMargins(0,0,0,0);
mTagContainerWidget->setLayout(mTagLayout);
DecoratedTag tempTag;
tempTag.setVisible(false);
mEditLabel = new QLabel(QStringLiteral("<a href='edit'>%1</a>").arg(i18n("Edit")));
mEditLabel->setVisible(false);
mEditLabel->setContentsMargins(tempTag.contentsMargins().left() / 2,
tempTag.contentsMargins().top(),
tempTag.contentsMargins().right() / 2,
tempTag.contentsMargins().bottom());
label_2->setContentsMargins(mEditLabel->contentsMargins());
QObject::connect(mRatingWidget, SIGNAL(ratingChanged(int)),
q, SLOT(slotRatingChanged(int)));
mDescriptionTextEdit->installEventFilter(q);
QObject::connect(mTagLabel, &QLabel::linkActivated,
QObject::connect(mEditLabel, &QLabel::linkActivated,
mEditTagsAction, &QAction::trigger);
}
......@@ -215,10 +233,17 @@ struct SemanticInfoContextManagerItemPrivate : public Ui_SemanticInfoSideBarItem
}
}
void updateTagLabel()
void updateTags()
{
QLayoutItem *item;
while ((item = mTagLayout->takeAt(0))) {
auto tag = item->widget();
if (tag != nullptr && tag != mEditLabel) {
tag->deleteLater();
}
}
if (q->contextManager()->selectedFileItemList().isEmpty()) {
mTagLabel->clear();
mEditLabel->setVisible(false);
return;
}
......@@ -239,9 +264,13 @@ struct SemanticInfoContextManagerItemPrivate : public Ui_SemanticInfoSideBarItem
}
QStringList labels(labelMap.values());
QString editLink = i18n("Edit");
QString text = labels.join(", ") + QStringLiteral(" <a href='edit'>%1</a>").arg(editLink);
mTagLabel->setText(text);
for (const QString &label : labels) {
DecoratedTag *decoratedTag = new DecoratedTag(label);
mTagLayout->addWidget(decoratedTag);
}
mTagLayout->addWidget(mEditLabel);
mEditLabel->setVisible(true);
mTagLayout->update();
}
void updateSemanticInfoDialog()
......@@ -357,7 +386,7 @@ void SemanticInfoContextManagerItem::update()
for (QAction * action : qAsConst(d->mActions)) {
action->setEnabled(enabled);
}
d->updateTagLabel();
d->updateTags();
if (d->mSemanticInfoDialog) {
d->updateSemanticInfoDialog();
}
......
......@@ -44,22 +44,19 @@
<property name="text">
<string>Tags:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="mTagLabel">
<widget class="QWidget" name="mTagContainerWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
......
......@@ -87,6 +87,7 @@ set(gwenviewlib_SRCS
recentfilesmodel.cpp
archiveutils.cpp
datewidget.cpp
decoratedtag/decoratedtag.cpp
exiv2imageloader.cpp
flowlayout.cpp
fullscreenbar.cpp
......@@ -237,6 +238,7 @@ target_link_libraries(gwenviewlib
Qt5::Concurrent
Qt5::Svg
Qt5::PrintSupport
KF5::GuiAddons
KF5::KIOCore
KF5::KIOWidgets
KF5::KIOFileWidgets
......
// SPDX-FileCopyrightText: 2021 Noah Davis <noahadvs@gmail.com>
// SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
#include "decoratedtag.h"
#include <KColorUtils>
#include <QEvent>
#include <QPaintEvent>
#include <QStylePainter>
#include <QStyleOptionFrame>
#include <QTextItem>
using namespace Gwenview;
class Gwenview::DecoratedTagPrivate
{
Q_DECLARE_PUBLIC(DecoratedTag)
public:
DecoratedTagPrivate(DecoratedTag *q) : q_ptr(q) {}
DecoratedTag *q_ptr = nullptr;
void updateMargins();
qreal horizontalMargin;
qreal verticalMargin;
};
void DecoratedTagPrivate::updateMargins()
{
Q_Q(DecoratedTag);
horizontalMargin = q->fontMetrics().descent() + 2;
verticalMargin = 2;
q->setContentsMargins(horizontalMargin, verticalMargin,
horizontalMargin, verticalMargin);
}
DecoratedTag::DecoratedTag(QWidget *parent, Qt::WindowFlags f)
: QLabel(parent, f)
, d_ptr(new DecoratedTagPrivate(this))
{
Q_D(DecoratedTag);
d->updateMargins();
}
DecoratedTag::DecoratedTag(const QString &text, QWidget *parent, Qt::WindowFlags f)
: QLabel(text, parent, f)
, d_ptr(new DecoratedTagPrivate(this))
{
Q_D(DecoratedTag);
d->updateMargins();
}
Gwenview::DecoratedTag::~DecoratedTag() noexcept
{
}
void DecoratedTag::changeEvent(QEvent *event)
{
Q_D(DecoratedTag);
if (event->type() == QEvent::FontChange) {
d->updateMargins();
}
}
void DecoratedTag::paintEvent(QPaintEvent *event)
{
Q_D(const DecoratedTag);
QStylePainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QColor penColor = KColorUtils::mix(palette().base().color(), palette().text().color(), 0.3);
// QPainter is bad at drawing lines that are exactly 1px.
// Using QPen::setCosmetic(true) with a 1px pen width
// doesn't look quite as good as just using 1.001px.
qreal penWidth = 1.001;
qreal penMargin = penWidth/2;
QPen pen(penColor, penWidth);
pen.setCosmetic(true);
QRectF rect = event->rect();
rect.adjust(penMargin, penMargin, -penMargin, -penMargin);
painter.setBrush(palette().base());
painter.setPen(pen);
painter.drawRoundedRect(rect, d->horizontalMargin, d->horizontalMargin);
QLabel::paintEvent(event);
}
// SPDX-FileCopyrightText: 2021 Noah Davis <noahadvs@gmail.com>
// SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
#ifndef GWENVIEW_DECORATEDTAG_H
#define GWENVIEW_DECORATEDTAG_H
#include <lib/gwenviewlib_export.h>
#include <QLabel>
namespace Gwenview {
class DecoratedTagPrivate;
/**
* A label with a custom background under it.
*
* TODO: Turn this into a more interactive control and make it look like Manuel's mockup.
* Should probably be turned into a QAbstractButton subclass or something.
*/
class GWENVIEWLIB_EXPORT DecoratedTag : public QLabel
{
Q_OBJECT
public:
explicit DecoratedTag(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
explicit DecoratedTag(const QString &text, QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
~DecoratedTag() override;
protected:
void changeEvent(QEvent *event) override;
void paintEvent(QPaintEvent* event) override;
private:
const std::unique_ptr<DecoratedTagPrivate> d_ptr;
Q_DECLARE_PRIVATE(DecoratedTag)
};
}
#endif // GWENVIEW_DECORATEDTAG_H
......@@ -45,6 +45,7 @@
class GWENVIEWLIB_EXPORT FlowLayout : public QLayout
{
Q_OBJECT
public:
explicit FlowLayout(QWidget *parent, int margin = 0, int spacing = -1);
FlowLayout(int spacing = -1);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment