Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_cmb_composite.cc
Go to the documentation of this file.
1/*
2 * kis_cmb_composite.cc - part of KImageShop/Krayon/Krita
3 *
4 * SPDX-FileCopyrightText: 2004 Boudewijn Rempt (boud@valdyas.org)
5 * SPDX-FileCopyrightText: 2011 Silvio Heinrich <plassy@web.de>
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10#include "kis_cmb_composite.h"
11
12#include <KoCompositeOp.h>
14
17#include <kis_action.h>
18#include <QWheelEvent>
19#include "kis_action_manager.h"
20
22// ---- KisCompositeOpListWidget ------------------------------------------------------ //
23
26 m_model(new KisSortedCompositeOpListModel(false, this))
27{
29 setItemDelegate(new KisCategorizedItemDelegate(this));
30}
31
35
37 KoID op;
38
39 if (m_model->entryAt(op, currentIndex())) {
40 return op;
41 }
42
44}
45
47{
48 const QModelIndex index = m_model->indexOf(id);
49 if (index.isValid()) {
50 setCurrentIndex(index);
51 } else {
52 qWarning() << "KisCompositeOpListWidget::setCompositeOp: ailed to find index for blendmode" << ppVar(id);
53 }
54}
55
57// ---- KisCompositeOpComboBox -------------------------------------------------------- //
58
63
64KisCompositeOpComboBox::KisCompositeOpComboBox(bool limitToLayerStyles, QWidget* parent)
65 : KisSqueezedComboBox(parent),
66 m_model(new KisSortedCompositeOpListModel(limitToLayerStyles, this)),
67 m_allowToHidePopup(true)
68{
71
72 setMaxVisibleItems(100);
73 setSizeAdjustPolicy(AdjustToContents);
74 m_view->setResizeMode(QListView::Adjust);
75
76 setToolTip(i18n("Blending Mode"));
77
78 setModel(m_model);
79 setView(m_view);
80 setItemDelegate(new KisCategorizedItemDelegate(this));
81
82 connect(m_view, SIGNAL(sigCategoryToggled(QModelIndex,bool)), SLOT(slotCategoryToggled(QModelIndex,bool)));
83 connect(m_view, SIGNAL(sigEntryChecked(QModelIndex)), SLOT(slotEntryChecked(QModelIndex)));
84
85 selectCompositeOp(KoCompositeOpRegistry::instance().getDefaultCompositeOp());
86}
87
92
94{
95 KisAction *action = 0;
96
97 action = manager->createAction("Next Blending Mode");
98 connect(action, SIGNAL(triggered()), SLOT(slotNextBlendingMode()));
99
100 action = manager->createAction("Previous Blending Mode");
101 connect(action, SIGNAL(triggered()), SLOT(slotPreviousBlendingMode()));
102
103 action = manager->createAction("Select Normal Blending Mode");
104 connect(action, SIGNAL(triggered()), SLOT(slotNormal()));
105
106 action = manager->createAction("Select Dissolve Blending Mode");
107 connect(action, SIGNAL(triggered()), SLOT(slotDissolve()));
108
109 action = manager->createAction("Select Behind Blending Mode");
110 connect(action, SIGNAL(triggered()), SLOT(slotBehind()));
111
112 action = manager->createAction("Select Clear Blending Mode");
113 connect(action, SIGNAL(triggered()), SLOT(slotClear()));
114
115 action = manager->createAction("Select Darken Blending Mode");
116 connect(action, SIGNAL(triggered()), SLOT(slotDarken()));
117
118 action = manager->createAction("Select Multiply Blending Mode");
119 connect(action, SIGNAL(triggered()), SLOT(slotMultiply()));
120
121 action = manager->createAction("Select Color Burn Blending Mode");
122 connect(action, SIGNAL(triggered()), SLOT(slotColorBurn()));
123
124 action = manager->createAction("Select Linear Burn Blending Mode");
125 connect(action, SIGNAL(triggered()), SLOT(slotLinearBurn()));
126
127 action = manager->createAction("Select Lighten Blending Mode");
128 connect(action, SIGNAL(triggered()), SLOT(slotLighten()));
129
130 action = manager->createAction("Select Screen Blending Mode");
131 connect(action, SIGNAL(triggered()), SLOT(slotScreen()));
132
133 action = manager->createAction("Select Color Dodge Blending Mode");
134 connect(action, SIGNAL(triggered()), SLOT(slotColorDodge()));
135
136 action = manager->createAction("Select Linear Dodge Blending Mode");
137 connect(action, SIGNAL(triggered()), SLOT(slotLinearDodge()));
138
139 action = manager->createAction("Select Overlay Blending Mode");
140 connect(action, SIGNAL(triggered()), SLOT(slotOverlay()));
141
142 action = manager->createAction("Select Hard Overlay Blending Mode");
143 connect(action, SIGNAL(triggered()), SLOT(slotHardOverlay()));
144
145 action = manager->createAction("Select Soft Light Blending Mode");
146 connect(action, SIGNAL(triggered()), SLOT(slotSoftLight()));
147
148 action = manager->createAction("Select Hard Light Blending Mode");
149 connect(action, SIGNAL(triggered()), SLOT(slotHardLight()));
150
151 action = manager->createAction("Select Vivid Light Blending Mode");
152 connect(action, SIGNAL(triggered()), SLOT(slotVividLight()));
153
154 action = manager->createAction("Select Linear Light Blending Mode");
155 connect(action, SIGNAL(triggered()), SLOT(slotLinearLight()));
156
157 action = manager->createAction("Select Pin Light Blending Mode");
158 connect(action, SIGNAL(triggered()), SLOT(slotPinLight()));
159
160 action = manager->createAction("Select Hard Mix Blending Mode");
161 connect(action, SIGNAL(triggered()), SLOT(slotHardMix()));
162
163 action = manager->createAction("Select Difference Blending Mode");
164 connect(action, SIGNAL(triggered()), SLOT(slotDifference()));
165
166 action = manager->createAction("Select Exclusion Blending Mode");
167 connect(action, SIGNAL(triggered()), SLOT(slotExclusion()));
168
169 action = manager->createAction("Select Hue Blending Mode");
170 connect(action, SIGNAL(triggered()), SLOT(slotHue()));
171
172 action = manager->createAction("Select Saturation Blending Mode");
173 connect(action, SIGNAL(triggered()), SLOT(slotSaturation()));
174
175 action = manager->createAction("Select Color Blending Mode");
176 connect(action, SIGNAL(triggered()), SLOT(slotColor()));
177
178 action = manager->createAction("Select Luminosity Blending Mode");
179 connect(action, SIGNAL(triggered()), SLOT(slotLuminosity()));
180}
181
185
187 KoID currentOp;
188 if (m_model->entryAt(currentOp, m_model->index(currentIndex(), 0)) &&
189 currentOp == op) {
190
191 return;
192 }
193
194 QModelIndex index = m_model->indexOf(op);
195
196 setCurrentIndex(index.row());
197 Q_EMIT activated(index.row());
198 Q_EMIT textActivated(op.name());
199}
200
202 KoID op;
203
204 if (m_model->entryAt(op, m_model->index(currentIndex(), 0))) {
205 return op;
206 }
208}
209
210void KisCompositeOpComboBox::slotCategoryToggled(const QModelIndex& index, bool toggled)
211{
212 Q_UNUSED(index);
213 Q_UNUSED(toggled);
214
215 //NOTE: this will (should) fit the size of the
216 // popup widget to the view
217 // don't know if this is expected behaviour
218 // on all supported platforms.
219 // There is nothing written about this in the docs.
220 showPopup();
221}
222
223void KisCompositeOpComboBox::slotEntryChecked(const QModelIndex& index)
224{
225 Q_UNUSED(index);
226 m_allowToHidePopup = false;
227}
228
230{
231 if (m_allowToHidePopup) {
232 QComboBox::hidePopup();
233 }
234 else {
235 QComboBox::showPopup();
236 }
237
238 m_allowToHidePopup = true;
239}
240
245
250
255
260
265
270
275
280
285
290
295
300
305
310
315
320
325
330
335
340
345
350
355
360
365
370
375
380
382{
383 const int rowCount = count();
384 int newIndex = currentIndex();
385
386 QAbstractItemModel *model = this->model();
387 KoID op;
388
389 if (!down) {
390 newIndex--;
391 while ((newIndex >= 0) &&
392 (!(model->flags(model->index(newIndex, modelColumn(), rootModelIndex())) & Qt::ItemIsEnabled) ||
393 !m_model->entryAt(op, m_model->index(newIndex, modelColumn()))))
394
395 newIndex--;
396 } else {
397 newIndex++;
398 while (newIndex < rowCount &&
399 (!(model->index(newIndex, modelColumn(), rootModelIndex()).flags() & Qt::ItemIsEnabled) ||
400 !m_model->entryAt(op, m_model->index(newIndex, modelColumn()))))
401
402 newIndex++;
403 }
404
405 if (newIndex >= 0 && newIndex < rowCount && newIndex != currentIndex()) {
406 setCurrentIndex(newIndex);
407
408 Q_EMIT activated(newIndex);
409 if (m_model->entryAt(op, m_model->index(newIndex, 0))) {
410 Q_EMIT textActivated(op.name());
411 }
412 }
413}
414
416{
423 QStyleOptionComboBox opt;
424 initStyleOption(&opt);
425
426 if (style()->styleHint(QStyle::SH_ComboBox_AllowWheelScrolling, &opt, this)) {
427 if (e->angleDelta().y() != 0) {
428 selectNeighbouringBlendMode(e->angleDelta().y() < 0);
429 }
430
431 e->accept();
432 } else {
433 KisSqueezedComboBox::wheelEvent(e);
434 }
435}
436
438{
445 enum Move { NoMove=0 , MoveUp , MoveDown , MoveFirst , MoveLast};
446
447 Move move = NoMove;
448 int newIndex = currentIndex();
449 switch (e->key()) {
450 case Qt::Key_Up:
451 if (e->modifiers() & Qt::ControlModifier)
452 break; // pass to line edit for auto completion
453 Q_FALLTHROUGH();
454 case Qt::Key_PageUp:
455 move = MoveUp;
456 break;
457 case Qt::Key_Down:
458 if (e->modifiers() & Qt::AltModifier) {
459 showPopup();
460 return;
461 } else if (e->modifiers() & Qt::ControlModifier)
462 break; // pass to line edit for auto completion
463 Q_FALLTHROUGH();
464 case Qt::Key_PageDown:
465 move = MoveDown;
466 break;
467 case Qt::Key_Home:
468 move = MoveFirst;
469 break;
470 case Qt::Key_End:
471 move = MoveLast;
472 break;
473 case Qt::Key_F4:
474 if (!e->modifiers()) {
475 showPopup();
476 return;
477 }
478 break;
479 case Qt::Key_Space:
480 showPopup();
481 return;
482 default:
483 break;
484 }
485
486 const int rowCount = count();
487
488 if (move != NoMove) {
489 KoID op;
490
491 e->accept();
492 switch (move) {
493 case MoveFirst:
494 newIndex = -1;
495 Q_FALLTHROUGH();
496 case MoveDown:
497 newIndex++;
498 while (newIndex < rowCount &&
499 (!(model()->index(newIndex, modelColumn(), rootModelIndex()).flags() & Qt::ItemIsEnabled) ||
500 !m_model->entryAt(op, m_model->index(newIndex, modelColumn()))))
501 newIndex++;
502 break;
503 case MoveLast:
504 newIndex = rowCount;
505 Q_FALLTHROUGH();
506 case MoveUp:
507 newIndex--;
508 while ((newIndex >= 0) &&
509 (!(model()->flags(model()->index(newIndex, modelColumn(), rootModelIndex())) & Qt::ItemIsEnabled) ||
510 !m_model->entryAt(op, m_model->index(newIndex, modelColumn()))))
511 newIndex--;
512 break;
513 default:
514 e->ignore();
515 break;
516 }
517
518 if (newIndex >= 0 && newIndex < rowCount && newIndex != currentIndex()) {
519 setCurrentIndex(newIndex);
520 Q_EMIT activated(newIndex);
521
522 if (m_model->entryAt(op, m_model->index(newIndex, 0))) {
523 Q_EMIT textActivated(op.name());
524 }
525 }
526 } else {
527 KisSqueezedComboBox::keyPressEvent(e);
528 }
529}
530
const QString COMPOSITE_OVER
const QString COMPOSITE_DARKEN
const QString COMPOSITE_OVERLAY
const QString COMPOSITE_DODGE
const QString COMPOSITE_LIGHTEN
const QString COMPOSITE_LINEAR_BURN
const QString COMPOSITE_SOFT_LIGHT_PHOTOSHOP
const QString COMPOSITE_MULT
const QString COMPOSITE_SATURATION
const QString COMPOSITE_LINEAR_LIGHT
const QString COMPOSITE_CLEAR
const QString COMPOSITE_HARD_LIGHT
const QString COMPOSITE_HARD_OVERLAY
const QString COMPOSITE_SCREEN
const QString COMPOSITE_PIN_LIGHT
const QString COMPOSITE_DIFF
const QString COMPOSITE_HUE
const QString COMPOSITE_BEHIND
const QString COMPOSITE_DISSOLVE
const QString COMPOSITE_BURN
const QString COMPOSITE_LINEAR_DODGE
const QString COMPOSITE_COLOR
const QString COMPOSITE_EXCLUSION
const QString COMPOSITE_VIVID_LIGHT
const QString COMPOSITE_LUMINIZE
const QString COMPOSITE_HARD_MIX_PHOTOSHOP
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
A KisActionManager class keeps track of KisActions. These actions are always associated with the GUI....
KisAction * createAction(const QString &name)
void setModel(QAbstractItemModel *model) override
void validate(const KoColorSpace *cs)
KisCompositeOpComboBox(QWidget *parent=0)
void selectCompositeOp(const KoID &op)
KisCategorizedListView * m_view
void wheelEvent(QWheelEvent *e) override
void slotEntryChecked(const QModelIndex &index)
void keyPressEvent(QKeyEvent *e) override
void selectNeighbouringBlendMode(bool down)
KisSortedCompositeOpListModel * m_model
void connectBlendmodeActions(KisActionManager *manager)
void slotCategoryToggled(const QModelIndex &index, bool toggled)
KisCompositeOpListWidget(QWidget *parent=0)
KisSortedCompositeOpListModel * m_model
void setCompositeOp(const KoID &id)
KisLayerStyleCompositeOpComboBox(QWidget *parent=0)
bool entryAt(Entry_Type &entry, QModelIndex index) const
QModelIndex indexOf(const Entry_Type &entry) const
The KisSortedCompositeOpListModel class provides a model for the composite op combobox.
void validate(const KoColorSpace *cs)
static const KoCompositeOpRegistry & instance()
Definition KoID.h:30
QString name() const
Definition KoID.cpp:68
#define ppVar(var)
Definition kis_debug.h:155