LeechCraft 0.6.70-19214-g121e5318a7
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
util.cpp
Go to the documentation of this file.
1/**********************************************************************
2 * LeechCraft - modular cross-platform feature rich internet client.
3 * Copyright (C) 2006-2014 Georg Rudoy
4 *
5 * Distributed under the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7 **********************************************************************/
8
9#include "util.h"
10#include <QSize>
11#include <QAbstractItemView>
12#include <QApplication>
13#include <QItemSelectionModel>
14#include <QKeyEvent>
15#include <QTimer>
16#include <QLabel>
17#include <QPainter>
18#include <QStyleOptionViewItem>
19#include <QtDebug>
20#include <util/sll/prelude.h>
21#include <util/sll/qtutil.h>
22#include "geometry.h"
23
24namespace LC::Util
25{
26 namespace
27 {
28 class AADisplayEventFilter : public QObject
29 {
30 QWidget * const Display_;
31 public:
32 explicit AADisplayEventFilter (QWidget *display)
33 : QObject (display)
34 , Display_ (display)
35 {
36 }
37 protected:
38 bool eventFilter (QObject*, QEvent *event) override
39 {
40 bool shouldClose = false;
41 switch (event->type ())
42 {
43 case QEvent::KeyRelease:
44 shouldClose = static_cast<QKeyEvent*> (event)->key () == Qt::Key_Escape;
45 break;
46 case QEvent::MouseButtonRelease:
47 shouldClose = true;
48 break;
49 default:
50 break;
51 }
52
53 if (!shouldClose)
54 return false;
55
56 QTimer::singleShot (0,
57 Display_,
58 &QWidget::close);
59 return true;
60 }
61 };
62 }
63
64 QLabel* ShowPixmapLabel (const QPixmap& srcPx, const QPoint& centerPos)
65 {
66 const auto scaleFactor = 0.9;
67 const auto& availGeom = AvailableGeometry (centerPos);
68 const auto& availSize = availGeom.size () * scaleFactor;
69
70 auto px = srcPx;
71 if (px.size ().width () > availSize.width () ||
72 px.size ().height () > availSize.height ())
73 px = px.scaled (availSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
74
75 auto topLeftPos = centerPos - QPoint { px.size ().width (), px.size ().height () } /2;
76 if (!availGeom.contains (topLeftPos))
77 {
78 topLeftPos.setX (std::max (topLeftPos.x (), availGeom.left ()));
79 topLeftPos.setY (std::max (topLeftPos.y (), availGeom.top ()));
80 }
81
82 const auto label = new QLabel;
83 label->setWindowFlags (Qt::Tool);
84 label->setAttribute (Qt::WA_DeleteOnClose);
85 label->setFixedSize (px.size ());
86 label->setPixmap (px);
87 label->show ();
88 label->activateWindow ();
89 label->installEventFilter (new AADisplayEventFilter (label));
90 label->move (topLeftPos);
91 return label;
92 }
93
94 void SetCurrentRow (QAbstractItemView& view, const QModelIndex& index)
95 {
96 view.selectionModel ()->setCurrentIndex (index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
97 }
98
99 QColor TintColors (const QColor& c1, const QColor& c2, double alpha)
100 {
101 QColor color;
102 color.setRedF (alpha * c1.redF () + (1 - alpha) * c2.redF ());
103 color.setGreenF (alpha * c1.greenF () + (1 - alpha) * c2.greenF ());
104 color.setBlueF (alpha * c1.blueF () + (1 - alpha) * c2.blueF ());
105 return color;
106 }
107
108 QString ElideProgressBarText (const QString& text, const QStyleOptionViewItem& option)
109 {
110 return option.fontMetrics.elidedText (text, Qt::ElideRight, option.rect.width ());
111 }
112
113 void TintPalette (QWidget *widget, const QColor& color, double alpha, const QList<QPalette::ColorRole>& roles)
114 {
115 auto palette = widget->palette ();
116 for (auto role : roles)
117 palette.setColor (role, TintColors (palette.color (role), color, alpha));
118 widget->setPalette (palette);
119 }
120
121 QString FormatName (const QString& name)
122 {
123 return "<i>" + name + "</i>";
124 }
125
126 QString FormatHumanReadableList (QStringList items)
127 {
128 switch (items.size ())
129 {
130 case 0:
131 return {};
132 case 1:
133 return items [0];
134 default:
135 {
136 const auto& last = items.takeLast ();
137 //: %1 is a comma-separated list having at least one item, %2 is the final item
138 return QObject::tr ("%1 and %2").arg (items.join (u", "_qsv), last);
139 }
140 }
141 }
142
143 QPixmap DrawOverlayText (QPixmap px,
144 const QString& text, QFont font, const QPen& pen, const QBrush& brush)
145 {
146 const auto& iconSize = px.size () / px.devicePixelRatio ();
147
148 const auto fontHeight = iconSize.height () * 0.45;
149 const auto minFontHeight = 6.0;
150 font.setPixelSize (static_cast<int> (std::max (minFontHeight, fontHeight)));
151
152 const QFontMetrics fm (font);
153 const auto width = fm.horizontalAdvance (text) + 2. * iconSize.width () / 10.;
154 const auto height = fm.height () + 2. * iconSize.height () / 10.;
155 const bool tooSmall = width > iconSize.width ();
156
157 const QRectF textRect (iconSize.width () - width, iconSize.height () - height, width, height);
158
159 QPainter p (&px);
160 p.setBrush (brush);
161 p.setFont (font);
162 p.setPen (pen);
163 p.setRenderHint (QPainter::Antialiasing);
164 p.setRenderHint (QPainter::TextAntialiasing);
165 p.drawRoundedRect (textRect, 4, 4);
166 p.drawText (textRect,
167 Qt::AlignCenter,
168 tooSmall ? QStringLiteral ("#") : text);
169 p.end ();
170
171 return px;
172 }
173
174 // https://bugreports.qt.io/browse/QTBUG-53550
175 QIcon FixupTrayIcon (const QIcon& icon)
176 {
177 if (!icon.availableSizes ().isEmpty ())
178 return icon;
179
180 constexpr auto pxSize = 256;
181 return QIcon { icon.pixmap (pxSize, pxSize) };
182 }
183
184 namespace
185 {
186 QString MakeFileDialogFilterImpl (auto&& entries)
187 {
188 const auto toString = [] (const auto& e) { return e.Description_ + " (*." + e.Extension_ + ")"; };
189 return MapAs<QList> (entries, toString).join (";;"_ql);
190 }
191 }
192
193 QString MakeFileDialogFilter (std::initializer_list<FileDialogFilterEntry> entries)
194 {
195 return MakeFileDialogFilterImpl (entries);
196 }
197
199 {
200 return MakeFileDialogFilterImpl (entries);
201 }
202}
char * toString(const char *name, const T &t)
Definition common.h:38
QLabel * ShowPixmapLabel(const QPixmap &srcPx, const QPoint &centerPos)
Shows a pixmap at the given pos.
Definition util.cpp:64
QColor TintColors(const QColor &c1, const QColor &c2, double alpha)
Mixes two colors with the given weights.
Definition util.cpp:99
void TintPalette(QWidget *widget, const QColor &color, double alpha, const QList< QPalette::ColorRole > &roles)
Mixes some of the widget's palette roles with the given color.
Definition util.cpp:113
void SetCurrentRow(QAbstractItemView &view, const QModelIndex &index)
Makes the given row current and the only selected one.
Definition util.cpp:94
QString ElideProgressBarText(const QString &text, const QStyleOptionViewItem &option)
Definition util.cpp:108
QRect AvailableGeometry(const QPoint &p)
Definition geometry.cpp:66
QPixmap DrawOverlayText(QPixmap px, const QString &text, QFont font, const QPen &pen, const QBrush &brush)
Definition util.cpp:143
QString FormatHumanReadableList(QStringList items)
Definition util.cpp:126
QString MakeFileDialogFilter(std::initializer_list< FileDialogFilterEntry > entries)
Definition util.cpp:193
QIcon FixupTrayIcon(const QIcon &icon)
Definition util.cpp:175
QString FormatName(const QString &name)
HTML-formats the name to let the user know it is not a part of the fixed dialog text.
Definition util.cpp:121
auto MapAs(Container &&c, F &&f) noexcept(noexcept(std::is_nothrow_invocable_v< F, decltype(*c.begin())>))
Definition prelude.h:111