Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_color_label_selector_widget.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include "kis_debug.h"
10#include "kis_global.h"
11
12#include <QAction>
13#include <QMenu>
14#include <QStyleOption>
15
16#include <QHBoxLayout>
17#include <QVBoxLayout>
18#include <QButtonGroup>
19#include <QSpacerItem>
20
23
24#include <kis_signals_blocker.h>
26
34
36 : QWidget(parent)
37 , m_d(new Private)
38{
40 m_d->colors = scm.allColorLabels();
41
42 QHBoxLayout *layout = new QHBoxLayout(this);
43 layout->setAlignment(Qt::AlignLeft);
44
45 layout->setContentsMargins(0,0,0,0);
46 layout->setSpacing(2);
47 {
48 m_d->colorButtonGroup = new KisColorLabelFilterGroup(this);
49 m_d->colorButtonGroup->setExclusive(true);
50 m_d->colorButtonGroup->setMinimumRequiredChecked(0);
51 QSet<int> viableColors;
52
53 for (int id = 0; id < m_d->colors.count(); id++) {
54 KisColorLabelButton* btn = new KisColorLabelButton(m_d->colors[id], m_d->buttonSize, this);
55 btn->setChecked(false);
57 m_d->colorButtonGroup->addButton(btn, id);
58 layout->addWidget(btn);
59 viableColors << id;
60 }
61
62 m_d->colorButtonGroup->setViableLabels(viableColors);
63
64 connect(m_d->colorButtonGroup, QOverload<QAbstractButton*, bool>::of(&QButtonGroup::buttonToggled),
65 [this](QAbstractButton *button, bool state)
66 {
67 const int index = m_d->colorButtonGroup->id(button);
68 Q_EMIT buttonToggled(index, state);
69 if (m_d->colorButtonGroup->exclusive()) {
70 if (!state) {
71 return;
72 }
73 Q_EMIT currentIndexChanged(index);
74 } else {
75 Q_EMIT selectionChanged();
76 }
77 }
78 );
79 }
80}
81
84
86{
87 return m_d->colorButtonGroup->button(index)->isChecked();
88}
89
91{
92 m_d->colorButtonGroup->button(index)->setChecked(state);
93}
94
96{
97 if (!m_d->colorButtonGroup->exclusive()) {
98 return -2;
99 }
100 return m_d->colorButtonGroup->checkedId();
101}
102
104{
105 if (!m_d->colorButtonGroup->exclusive()) {
106 return;
107 }
108 if (index == -1) {
109 QAbstractButton* btn = m_d->colorButtonGroup->checkedButton();
110 if (btn) {
111 btn->group()->setExclusive(false);
112 btn->setChecked(false);
113 btn->group()->setExclusive(true);
114 }
115 } else if (index != m_d->colorButtonGroup->checkedId()) {
116 QAbstractButton* btn = m_d->colorButtonGroup->button(index);
117 if (btn) {
118 btn->setChecked(true);
119 }
120 }
121
122 Q_EMIT currentIndexChanged(index);
123}
124
126{
127 QList<int> indices;
128 for (QAbstractButton *button : m_d->colorButtonGroup->buttons()) {
129 if (button->isChecked()) {
130 indices << m_d->colorButtonGroup->id(button);
131 }
132 }
133 return indices;
134}
135
137{
138 KisSignalsBlocker blocker(m_d->colorButtonGroup);
139 for (QAbstractButton *button : m_d->colorButtonGroup->buttons()) {
140 button->setChecked(false);
141 }
142 for (int index : indices) {
143 m_d->colorButtonGroup->button(index)->setChecked(true);
144 }
145 Q_EMIT selectionChanged();
146}
147
149{
150 return m_d->colorButtonGroup->exclusive();
151}
152
154{
155 m_d->colorButtonGroup->setExclusive(exclusive);
156}
157
159{
160 return dynamic_cast<KisWrappableHBoxLayout*>(layout());
161}
162
164{
165 QLayout *newLayout;
166 if (enabled) {
167 if (dynamic_cast<KisWrappableHBoxLayout*>(layout())) {
168 return;
169 }
170 newLayout = new KisWrappableHBoxLayout;
171 } else {
172 if (dynamic_cast<QHBoxLayout*>(layout())) {
173 return;
174 }
175 newLayout = new QHBoxLayout;
176 }
177 newLayout->setContentsMargins(0,0,0,0);
178 newLayout->setSpacing(2);
179 for (QAbstractButton *button : m_d->colorButtonGroup->buttons()) {
180 newLayout->addWidget(button);
181 }
182 delete layout();
183 setLayout(newLayout);
184}
185
187{
188 return m_d->dragFilter;
189}
190
192{
193 if (enabled) {
194 if (m_d->dragFilter) {
195 return;
196 }
197 m_d->dragFilter = new KisColorLabelMouseDragFilter(this);
198 for (QAbstractButton *button : m_d->colorButtonGroup->buttons()) {
199 button->installEventFilter(m_d->dragFilter);
200 }
201 } else {
202 if (!m_d->dragFilter) {
203 return;
204 }
205 for (QAbstractButton *button : m_d->colorButtonGroup->buttons()) {
206 button->removeEventFilter(m_d->dragFilter);
207 }
208 delete m_d->dragFilter;
209 m_d->dragFilter = nullptr;
210 }
211}
212
214{
215 return
216 static_cast<SelectionIndicationType>(
217 qobject_cast<KisColorLabelButton*>(
218 m_d->colorButtonGroup->button(0)
219 )->selectionVisType()
220 );
221}
222
224{
225 for (QAbstractButton *button : m_d->colorButtonGroup->buttons()) {
226 qobject_cast<KisColorLabelButton*>(button)->setSelectionVisType(
228 );
229 }
230}
231
233{
234 return m_d->buttonSize;
235}
236
238{
239 if (size == m_d->buttonSize) {
240 return;
241 }
242 m_d->buttonSize = size;
243 for (QAbstractButton *button : m_d->colorButtonGroup->buttons()) {
244 qobject_cast<KisColorLabelButton*>(button)->setSize(static_cast<uint>(size));
245 }
246 update();
247}
248
249
255
257 : QWidget(parent)
258 , m_d(new Private)
259{
260 m_d->colorLabelSelector = new KisColorLabelSelectorWidget(this);
261 m_d->menuAlignmentOffset = new QSpacerItem(0, 0);
262 QHBoxLayout *layout = new QHBoxLayout(this);
263 layout->setContentsMargins(0, 1, 0, 1);
264 layout->setSpacing(0);
265 layout->addItem(m_d->menuAlignmentOffset);
266 layout->addWidget(m_d->colorLabelSelector);
267}
268
271
276
278{
279 Q_UNUSED(e);
280 const int menuOffset = calculateMenuOffset();
281 m_d->menuAlignmentOffset->changeSize(menuOffset, height());
282}
283
285{
286 bool hasWideItems = false;
287 QMenu *menu = qobject_cast<QMenu*>(parent());
288 bool hasCheckable = false;
289 bool hasIcon = false;
290
291 int menuOffset = 0;
292
293 if (menu) {
294 Q_FOREACH(QAction *action, menu->actions()) {
295 hasCheckable |= action->isCheckable();
296 hasIcon |= action->icon().isNull();
297 hasWideItems |= (hasCheckable || hasIcon);
298
299 if (hasWideItems) {
300 break;
301 }
302 }
303 }
304
305 if (hasWideItems) {
306 QStyleOption opt;
307 opt.initFrom(this);
308 // some copy-pasted code from QFusionStyle style
309 const int hMargin = style()->pixelMetric(QStyle::PM_MenuHMargin, &opt, this);
310 const int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, this);
311 menuOffset = (hMargin + iconSize + 6);
312 }
313
314 return menuOffset;
315}
unsigned int uint
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
int iconSize(qreal width, qreal height)
void setSelectionVisType(SelectionIndicationType type)
KisColorLabelSelectorWidget * colorLabelSelector() const
bool mouseDragEnabled() const
Get if the user can drag to check/uncheck multiple buttons.
void setButtonSize(int size)
Set the size of the buttons.
void currentIndexChanged(int index)
int buttonSize() const
Get the size of the buttons.
void setSelection(const QList< int > &indices)
Set the list of checked button indices.
bool exclusive() const
Get if the button selection is mutually exclusive.
SelectionIndicationType selectionIndicationType() const
Get how the button is rendered.
void setButtonChecked(int index, bool state)
(Un)Check the button at the given position
void setExclusive(bool exclusive)
Set if the button selection is mutually exclusive. This allows switching between single or multiple s...
bool buttonWrapEnabled() const
Get if the buttons should wrap in multiple lines if there is no enough space horizontally.
void setButtonWrapEnabled(bool enabled)
Set if the buttons should wrap in multiple lines if there is no enough space horizontally.
int currentIndex() const
Get the index of the currently checked button. Returns -1 if there is no checked button and -2 if the...
KisColorLabelSelectorWidget(QWidget *parent=nullptr)
void setCurrentIndex(int index)
Set the currently selected button. It has no effect if the buttons are mutually exclusive.
void setSelectionIndicationType(SelectionIndicationType type)
Set how the button should be rendered.
bool isButtonChecked(int index) const
Get if the button at the given position is currently checked.
void setMouseDragEnabled(bool enabled)
Set if the user can drag to check/uncheck multiple buttons.
QList< int > selection() const
Get the list of checked button indices.
QVector< QColor > allColorLabels() const
QString button(const QWheelEvent &ev)