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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
#pragma once
#include <QtCore/QTimer>
#include <QtGui/QColor>
#include <QtGui/QPainter>
#include <QtGui/QPaintEvent>
#include <QtWidgets/QLabel>
#include "uicontext.h"
/*!
\defgroup clickablelabel ClickableLabel
\ingroup uiapi
*/
/*!
\ingroup clickablelabel
*/
struct BINARYNINJAUIAPI IconImage
{
QImage original;
QImage active, activeHover;
QImage inactive, inactiveHover;
static IconImage generate(const QImage& src);
};
/*!
\ingroup clickablelabel
*/
class BINARYNINJAUIAPI ClickableLabel : public QLabel
{
Q_OBJECT
bool m_passThroughMousePressEvent = false;
public:
ClickableLabel(QWidget* parent = nullptr, const QString& name = "") : QLabel(parent) { setText(name); }
// FIXME: The new UI header in the pane system has some keyboard focus issues; so consuming mousePressEvent seems to resolve them
// Since I can't repro the exact issues this allows the mouse event to pass through when needed.
void passThroughMousePressEvent(bool enable) { m_passThroughMousePressEvent = enable; }
Q_SIGNALS:
void clicked();
protected:
void mousePressEvent(QMouseEvent* event) override { if (m_passThroughMousePressEvent) { QLabel::mousePressEvent(event); } }
void mouseReleaseEvent(QMouseEvent* event) override
{
if (event->button() == Qt::LeftButton)
Q_EMIT clicked();
}
};
/*!
\ingroup clickablelabel
*/
class BINARYNINJAUIAPI ClickableIcon : public QWidget
{
Q_OBJECT
IconImage m_image;
bool m_canToggle = false;
bool m_active = true;
bool m_hover = false;
QTimer* m_timer;
public:
ClickableIcon(const QImage& icon, const QSize& desiredPointSize);
void setAllowToggle(bool canToggle);
void setActive(bool state);
bool active() const { return m_active; }
void setImage(const QImage& icon);
Q_SIGNALS:
void clicked();
void toggle(bool newState);
private Q_SLOTS:
void underMouseTimerEvent();
void handleToggle();
protected:
void enterEvent(QEnterEvent* event) override;
void leaveEvent(QEvent* event) override;
void paintEvent(QPaintEvent* event) override;
void mousePressEvent(QMouseEvent*) override {}
void mouseReleaseEvent(QMouseEvent* event) override;
};
/*!
\ingroup clickablelabel
*/
class BINARYNINJAUIAPI ClickableStateLabel : public ClickableLabel
{
Q_OBJECT
QString m_name;
QString m_altName;
bool m_state = true;
bool m_stateEffectEnabled = false;
bool m_altStateEffect = false;
QPalette::ColorRole m_altOverlayColorRole;
int m_alpha;
public:
ClickableStateLabel(QWidget* parent, const QString& name, const QString& altName) :
ClickableLabel(parent, name), m_name(name), m_altName(altName)
{}
bool getState() { return m_state; }
void setDisplayState(bool state)
{
m_state = state;
setText(m_state ? m_name : m_altName);
}
void setAlternateTransparency(QPalette::ColorRole colorRole, int alpha, bool state)
{
m_altOverlayColorRole = colorRole;
m_alpha = alpha;
m_altStateEffect = state;
m_stateEffectEnabled = true;
}
protected:
void paintEvent(QPaintEvent* event) override
{
ClickableLabel::paintEvent(event);
if (m_stateEffectEnabled && (m_state == m_altStateEffect))
{
QPainter p(this);
QColor overlayColor = palette().color(m_altOverlayColorRole);
overlayColor.setAlpha(m_alpha);
p.fillRect(event->rect(), overlayColor);
}
}
};
|