File: iconbutton.cpp

package info (click to toggle)
martchus-qtutilities 6.15.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 780 kB
  • sloc: cpp: 5,908; xml: 37; sh: 25; ansic: 12; makefile: 12
file content (125 lines) | stat: -rw-r--r-- 3,595 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "./iconbutton.h"

#include <c++utilities/conversion/stringbuilder.h>

#include <QKeyEvent>
#include <QStyle>
#include <QStyleOptionFocusRect>
#include <QStylePainter>

using namespace CppUtilities;

namespace QtUtilities {

/*!
 * \class IconButton
 * \brief A simple QAbstractButton implementation displaying a QPixmap.
 */

/*!
 * \brief Constructs an icon button.
 */
IconButton::IconButton(QWidget *parent)
    : QAbstractButton(parent)
{
    setCursor(Qt::ArrowCursor);
    setFocusPolicy(Qt::NoFocus);
}

/*!
 * \brief Destroys the icon button.
 */
IconButton::~IconButton()
{
}

/*!
 * \brief Creates an IconButton for the specified \a action.
 * \remarks Calling this function on the same action twice with the same \a id yields the
 *          same instance.
 */
IconButton *IconButton::fromAction(QAction *action, std::uintptr_t id)
{
    const auto propertyName = argsToString("iconButton-", id);
    const auto existingIconButton = action->property(propertyName.data());
    if (!existingIconButton.isNull()) {
        return existingIconButton.value<IconButton *>();
    }
    auto *const iconButton = new IconButton;
    iconButton->assignDataFromAction(action);
    action->setProperty(propertyName.data(), QVariant::fromValue(iconButton));
    connect(action, &QAction::changed, iconButton, &IconButton::assignDataFromActionChangedSignal);
    connect(iconButton, &IconButton::clicked, action, &QAction::trigger);
    return iconButton;
}

/*!
 * \brief Internally called to assign data from a QAction to the icon button.
 */
void IconButton::assignDataFromActionChangedSignal()
{
    assignDataFromAction(qobject_cast<const QAction *>(QObject::sender()));
}

/*!
 * \brief Internally called to assign data from a QAction to the icon button.
 */
void IconButton::assignDataFromAction(const QAction *action)
{
    auto const icon = action->icon();
    const auto sizes = icon.availableSizes();
    const auto text = action->text();
    setPixmap(icon.pixmap(sizes.empty() ? defaultPixmapSize : sizes.front()));
    setToolTip(text.isEmpty() ? action->toolTip() : text);
}

QSize IconButton::sizeHint() const
{
#if QT_VERSION >= 0x050100
    const qreal pixmapRatio = m_pixmap.devicePixelRatio();
#else
    const qreal pixmapRatio = 1.0;
#endif
    return QSize(static_cast<int>(m_pixmap.width() / pixmapRatio), static_cast<int>(m_pixmap.height() / pixmapRatio));
}

void IconButton::paintEvent(QPaintEvent *)
{
#if QT_VERSION >= 0x050100
    const qreal pixmapRatio = m_pixmap.devicePixelRatio();
#else
    const qreal pixmapRatio = 1.0;
#endif
    auto painter = QStylePainter(this);
    auto pixmapRect = QRect(0, 0, static_cast<int>(m_pixmap.width() / pixmapRatio), static_cast<int>(m_pixmap.height() / pixmapRatio));
    pixmapRect.moveCenter(rect().center());
    painter.drawPixmap(pixmapRect, m_pixmap);
    if (hasFocus()) {
        auto focusOption = QStyleOptionFocusRect();
        focusOption.initFrom(this);
        focusOption.rect = pixmapRect;
#ifdef Q_OS_MAC
        focusOption.rect.adjust(-4, -4, 4, 4);
        painter.drawControl(QStyle::CE_FocusFrame, focusOption);
#else
        painter.drawPrimitive(QStyle::PE_FrameFocusRect, focusOption);
#endif
    }
}

void IconButton::keyPressEvent(QKeyEvent *event)
{
    QAbstractButton::keyPressEvent(event);
    if (!event->modifiers() && (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)) {
        click();
    }
    event->accept();
}

void IconButton::keyReleaseEvent(QKeyEvent *event)
{
    QAbstractButton::keyReleaseEvent(event);
    event->accept();
}

} // namespace QtUtilities