Krita Source Code Documentation
Loading...
Searching...
No Matches
LayerBox Class Reference

#include <LayerBox.h>

+ Inheritance diagram for LayerBox:

Signals

void imageChanged ()
 

Public Member Functions

 LayerBox ()
 
QString observerName () override
 
void setCanvas (KoCanvasBase *canvas) override
 
void setViewManager (KisViewManager *kisview) override
 reimplemented from KisMainwindowObserver
 
void unsetCanvas () override
 
 ~LayerBox () override
 
- Public Member Functions inherited from KisMainwindowObserver
 KisMainwindowObserver ()
 
 ~KisMainwindowObserver () override
 
- Public Member Functions inherited from KoCanvasObserverBase
 KoCanvasObserverBase ()
 
KoCanvasBase * observedCanvas () const
 
void setObservedCanvas (KoCanvasBase *canvas)
 
void unsetObservedCanvas ()
 
virtual ~KoCanvasObserverBase ()
 

Protected Member Functions

void hideEvent (QHideEvent *event) override
 
void showEvent (QShowEvent *event) override
 

Private Slots

void notifyImageDeleted ()
 
void selectionChanged (const QModelIndexList &selection)
 
void setCurrentNode (KisNodeSP node)
 
void slotAddLayerBnClicked ()
 
void slotAdjustCurrentBeforeRemoveRows (const QModelIndex &parent, int first, int last)
 
void slotChangeCloneSourceClicked ()
 
void slotCollapsed (const QModelIndex &index)
 
void slotColorLabelChanged (int index)
 
void slotCompositeOpChanged (int index)
 
void slotContextMenuRequested (const QPoint &pos, const QModelIndex &index)
 
void slotEditGlobalSelection (bool showSelections)
 
void slotExpanded (const QModelIndex &index)
 
void slotForgetAboutSavedNodeBeforeEditSelectionMode ()
 
void slotImageTimeChanged (int time)
 
void slotLayerOpMenuClosed ()
 
void slotLayerOpMenuOpened ()
 
void slotLowerClicked ()
 
void slotModelReset ()
 
void slotNodeCollapsedChanged ()
 
void slotNodeManagerChangedSelection (const QList< KisNodeSP > &nodes)
 
void slotOpacityChanged ()
 
void slotOpacitySliderMoved (qreal opacity)
 
void slotPropertiesClicked ()
 
void slotRaiseClicked ()
 
void slotRenameCurrentNode ()
 
void slotRmClicked ()
 
void slotSelectOpaque ()
 
void slotSetCompositeOp (const KoCompositeOp *compositeOp)
 
void slotSetOpacity (double opacity)
 
void slotSyncThumbnailIconSize ()
 
void slotUpdateIcons ()
 
void slotUpdateLayerInfoTextOpacity ()
 
void slotUpdateLayerInfoTextStyle ()
 
void slotUpdateOpacitySlider (quint8 value)
 
void slotUpdateThumbnailIconSize ()
 
void slotUpdateTreeIndentation ()
 
void slotUpdateUseInlineLayerInfoText ()
 
void slotUpdateUseLayerSelectionCheckbox ()
 
void toggleActiveLayerSolo ()
 
void updateAvailableLabels ()
 
void updateLayerFiltering ()
 
void updateLayerOpMenu (const QModelIndex &index, QMenu &menu)
 
void updateUI ()
 

Private Member Functions

void addActionToMenu (QMenu *menu, const QString &id)
 
void connectActionToButton (KisViewManager *view, QAbstractButton *button, const QString &id)
 
qint32 convertOpacityToInt (qreal opacity)
 
KisNodeSP findNonHidableNode (KisNodeSP startNode)
 

Private Attributes

QSlider * indentationSlider
 
QComboBox * infoTextCombobox
 
QCheckBox * infoTextInlineChkbox
 
KisSliderSpinBox * infoTextOpacitySlider
 
KisLayerFilterWidget * layerFilterWidget
 
QCheckBox * layerSelectionCheckBox {nullptr}
 
KisNodeSP m_activeNode
 
KisSignalAutoConnectionsStore m_activeNodeConnections
 
QPointer< KisCanvas2 > m_canvas
 
KisAction * m_changeCloneSourceAction
 
KisNodeSP m_changedOpacityNode
 
KisSignalCompressor m_colorLabelCompressor
 
QPointer< KisColorLabelSelectorWidgetMenuWrapper > m_colorSelector
 
QPointer< QWidgetAction > m_colorSelectorAction
 
QPointer< KisNodeFilterProxyModel > m_filteringModel
 
KisImageWSP m_image
 
KisSignalCompressor m_infoTextOpacityCompressor
 
KisAction * m_layerToggleSolo
 
QMenu * m_newLayerMenu
 
int m_newOpacity
 
QPointer< KisNodeManager > m_nodeManager
 
QPointer< KisNodeModel > m_nodeModel
 
KisSignalCompressor m_nodeOpacityCompressor
 
QMenu * m_opLayerMenu
 
KisAction * m_propertiesAction
 
KisAction * m_removeAction
 
KisNodeWSP m_savedNodeBeforeEditSelectionMode
 
QScopedPointer< KisScreenMigrationTracker > m_screenMigrationTracker
 
QScopedPointer< KisSelectionActionsAdapter > m_selectionActionsAdapter
 
KisAction * m_showGlobalSelectionMask
 
KisSignalCompressor m_thumbnailSizeCompressor
 
KisSignalCompressor m_treeIndentationCompressor
 
Ui_WdgLayerBox * m_wdgLayerBox
 
QSlider * thumbnailSizeSlider
 

Detailed Description

A widget that shows a visualization of the layer structure.

The center of the layer box is KisNodeModel, which shows the actual layers. This widget adds docking functionality and command buttons.

Definition at line 64 of file LayerBox.h.

Constructor & Destructor Documentation

◆ LayerBox()

LayerBox::LayerBox ( )

Connect model updateUI() to enable/disable controls. Note: nodeActivated() is connected separately in setImage(), because it needs particular order of calls: first the connection to the node manager should be called, then updateUI()

Definition at line 160 of file LayerBox.cpp.

161 : QDockWidget(i18n("Layers"))
162 , m_canvas(0)
163 , m_wdgLayerBox(new Ui_WdgLayerBox)
169{
170 KisConfig cfg(false);
171
172 QWidget* mainWidget = new QWidget(this);
173 setWidget(mainWidget);
174
175 m_wdgLayerBox->setupUi(mainWidget);
176
177 QStyle *newStyle = QStyleFactory::create(m_wdgLayerBox->listLayers->style()->objectName());
178 // proxy style steals the ownership of the style and deletes it later
179 LayerBoxStyle *proxyStyle = new LayerBoxStyle(newStyle);
180
181 proxyStyle->setParent(m_wdgLayerBox->listLayers);
182 m_wdgLayerBox->listLayers->setStyle(proxyStyle);
183
184 connect(m_wdgLayerBox->listLayers,
185 SIGNAL(contextMenuRequested(QPoint,QModelIndex)),
186 this, SLOT(slotContextMenuRequested(QPoint,QModelIndex)));
187 connect(m_wdgLayerBox->listLayers,
188 SIGNAL(collapsed(QModelIndex)), SLOT(slotCollapsed(QModelIndex)));
189 connect(m_wdgLayerBox->listLayers,
190 SIGNAL(expanded(QModelIndex)), SLOT(slotExpanded(QModelIndex)));
191 connect(m_wdgLayerBox->listLayers,
193
195
196 m_wdgLayerBox->bnAdd->setIconSize(QSize(22, 22));
197 m_wdgLayerBox->bnDelete->setIconSize(QSize(22, 22));
198 m_wdgLayerBox->bnRaise->setIconSize(QSize(22, 22));
199 m_wdgLayerBox->bnLower->setIconSize(QSize(22, 22));
200 m_wdgLayerBox->bnProperties->setIconSize(QSize(22, 22));
201 m_wdgLayerBox->bnDuplicate->setIconSize(QSize(22, 22));
202
203 m_wdgLayerBox->bnLower->setEnabled(false);
204 m_wdgLayerBox->bnRaise->setEnabled(false);
205
206 m_wdgLayerBox->doubleOpacity->setRange(0, 100, 0);
207 if (cfg.sliderLabels()) {
208 m_wdgLayerBox->opacityLabel->hide();
210 i18nc("{n} is the number value, % is the percent sign", "Opacity: {n}%"));
211 } else {
213 i18nc("{n} is the number value, % is the percent sign", "{n}%"));
214 }
215
216 connect(m_wdgLayerBox->doubleOpacity, SIGNAL(valueChanged(qreal)), SLOT(slotOpacitySliderMoved(qreal)));
217 connect(&m_nodeOpacityCompressor, SIGNAL(timeout()), SLOT(slotOpacityChanged()));
218
219 connect(m_wdgLayerBox->cmbComposite, SIGNAL(activated(int)), SLOT(slotCompositeOpChanged(int)));
220
221 m_newLayerMenu = new QMenu(this);
222 m_wdgLayerBox->bnAdd->setMenu(m_newLayerMenu);
223 m_wdgLayerBox->bnAdd->setPopupMode(QToolButton::MenuButtonPopup);
224
225 m_opLayerMenu = new QMenu(this);
226 m_wdgLayerBox->bnProperties->setMenu(m_opLayerMenu);
227 m_wdgLayerBox->bnProperties->setPopupMode(QToolButton::MenuButtonPopup);
228
229 m_nodeModel = new KisNodeModel(this, 2);
231 m_filteringModel->setNodeModel(m_nodeModel);
232
239 connect(m_nodeModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(updateUI()));
240 connect(m_nodeModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(updateUI()));
241 connect(m_nodeModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), SLOT(updateUI()));
242 connect(m_nodeModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(updateUI()));
243 connect(m_nodeModel, SIGNAL(modelReset()), SLOT(slotModelReset()));
244
245 connect(m_nodeModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(slotForgetAboutSavedNodeBeforeEditSelectionMode()));
246 connect(m_nodeModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(slotForgetAboutSavedNodeBeforeEditSelectionMode()));
247 connect(m_nodeModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), SLOT(slotForgetAboutSavedNodeBeforeEditSelectionMode()));
248 connect(m_nodeModel, SIGNAL(modelReset()), SLOT(slotForgetAboutSavedNodeBeforeEditSelectionMode()));
249
250 // we should update expanded state of the nodes on adding the nodes
251 connect(m_nodeModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(slotNodeCollapsedChanged()));
252 connect(m_nodeModel, SIGNAL(modelReset()), SLOT(slotNodeCollapsedChanged()));
253
254 m_showGlobalSelectionMask = new KisAction(i18n("&Show Global Selection Mask"), this);
255 m_showGlobalSelectionMask->setObjectName("show-global-selection-mask");
257 m_showGlobalSelectionMask->setToolTip(i18nc("@info:tooltip", "Shows global selection as a usual selection mask in <b>Layers</b> docker"));
258 m_showGlobalSelectionMask->setCheckable(true);
259 connect(m_showGlobalSelectionMask, SIGNAL(triggered(bool)), SLOT(slotEditGlobalSelection(bool)));
260
261 m_showGlobalSelectionMask->setChecked(cfg.showGlobalSelection());
262
264 MouseClickIgnore* mouseEater = new MouseClickIgnore(this);
265 m_colorSelector->installEventFilter(mouseEater);
266 connect(m_colorSelector->colorLabelSelector(), SIGNAL(currentIndexChanged(int)), SLOT(slotColorLabelChanged(int)));
267 m_colorSelectorAction = new QWidgetAction(this);
268 m_colorSelectorAction->setDefaultWidget(m_colorSelector);
269
270 connect(m_nodeModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
271 &m_colorLabelCompressor, SLOT(start()));
272
273 m_wdgLayerBox->listLayers->setModel(m_filteringModel);
274 // this connection should be done *after* the setModel() call to
275 // happen later than the internal selection model
278
279
280 //LayerFilter Menu
281 QMenu *layerFilterMenu = new QMenu(this);
282 m_wdgLayerBox->bnLayerFilters->setMenu(layerFilterMenu);
283 m_wdgLayerBox->bnLayerFilters->setPopupMode(QToolButton::InstantPopup);
284
285 const QIcon filterIcon = KisIconUtils::loadIcon("view-filter");
286 m_wdgLayerBox->bnLayerFilters->setIcon(filterIcon);
287 m_wdgLayerBox->bnLayerFilters->setAutoRaise(true);
288 QPixmap filterEnabledPixmap = filterIcon.pixmap(64,64);
289 const QBitmap filterEnabledBitmask = filterEnabledPixmap.mask();
290 filterEnabledPixmap.fill(palette().color(QPalette::Highlight));
291 filterEnabledPixmap.setMask(filterEnabledBitmask);
292 const QIcon filterEnabledIcon = QIcon(filterEnabledPixmap);
293
295 connect(layerFilterWidget, SIGNAL(filteringOptionsChanged()), this, SLOT(updateLayerFiltering()));
296 connect(layerFilterWidget, &KisLayerFilterWidget::filteringOptionsChanged, [this, filterIcon, filterEnabledIcon](){
298 m_wdgLayerBox->bnLayerFilters->setIcon(filterEnabledIcon);
299 } else {
300 m_wdgLayerBox->bnLayerFilters->setIcon(filterIcon);
301 }
302
303 auto activeColors = layerFilterWidget->getActiveColors();
304 m_wdgLayerBox->bnLayerFilters->setSelectedColors(QList(activeColors.begin(), activeColors.end()));
305 m_wdgLayerBox->bnLayerFilters->setTextFilter(layerFilterWidget->hasTextFilter());
306 });
307
308 QWidgetAction *layerFilterMenuAction = new QWidgetAction(this);
309 layerFilterMenuAction->setDefaultWidget(layerFilterWidget);
310 layerFilterMenu->addAction(layerFilterMenuAction);
311
312
313 KisMenuStyleDontCloseOnAlt *menuStyle = new KisMenuStyleDontCloseOnAlt(layerFilterMenu->style());
314 menuStyle->setParent(layerFilterMenu);
315 layerFilterMenu->setStyle(menuStyle);
316
317 setEnabled(false);
318
319 connect(&m_colorLabelCompressor, SIGNAL(timeout()), SLOT(updateAvailableLabels()));
320
321
322 // set up the configure menu for changing thumbnail size
323 QMenu* configureMenu = new QMenu(this);
324 configureMenu->setContentsMargins(6, 6, 6, 6);
325 configureMenu->addSection(i18n("Thumbnail Size"));
326
327 m_wdgLayerBox->configureLayerDockerToolbar->setMenu(configureMenu);
328 m_wdgLayerBox->configureLayerDockerToolbar->setIconSize(QSize(16, 16));
329 m_wdgLayerBox->configureLayerDockerToolbar->setPopupMode(QToolButton::InstantPopup);
330 m_wdgLayerBox->configureLayerDockerToolbar->setAutoRaise(true);
331
332
333 // add horizontal slider
334 thumbnailSizeSlider = new QSlider(this);
335 thumbnailSizeSlider->setOrientation(Qt::Horizontal);
336 thumbnailSizeSlider->setRange(20, 80);
337
338 thumbnailSizeSlider->setValue(cfg.layerThumbnailSize(false)); // grab this from the kritarc
339
340 thumbnailSizeSlider->setMinimumHeight(20);
341 thumbnailSizeSlider->setMinimumWidth(40);
342 thumbnailSizeSlider->setTickInterval(5);
343 m_nodeModel->setPreferredThumnalSize(cfg.layerThumbnailSize() * m_wdgLayerBox->listLayers->devicePixelRatioF());
344
345 QWidgetAction *sliderAction= new QWidgetAction(this);
346 sliderAction->setDefaultWidget(thumbnailSizeSlider);
347 configureMenu->addAction(sliderAction);
348
349
350 connect(thumbnailSizeSlider, SIGNAL(valueChanged(int)), &m_thumbnailSizeCompressor, SLOT(start()));
351 connect(&m_thumbnailSizeCompressor, SIGNAL(timeout()), SLOT(slotUpdateThumbnailIconSize()));
352
353 configureMenu->addSection(i18nc("@item:inmenu Layers Docker settings, slider", "Tree Indentation"));
354
355 // add horizontal slider
356 indentationSlider = new QSlider(Qt::Horizontal, this);
357 indentationSlider->setRange(20, 100);
358 indentationSlider->setMinimumSize(40, 20);
359 indentationSlider->setSingleStep(5);
360 indentationSlider->setPageStep(20);
361 indentationSlider->setValue(cfg.layerTreeIndentation());
362
363
364 sliderAction= new QWidgetAction(this);
365 sliderAction->setDefaultWidget(indentationSlider);
366 configureMenu->addAction(sliderAction);
367
368 // NOTE: if KisConfig would just compress its file sync events, we wouldn't need
369 // this extra compressor that juggles between slow UI and disk thrashing
370 connect(indentationSlider, SIGNAL(valueChanged(int)), &m_treeIndentationCompressor, SLOT(start()));
371 connect(&m_treeIndentationCompressor, SIGNAL(timeout()), SLOT(slotUpdateTreeIndentation()));
372
373
374 // Layer info-text settings:
375 // blending info-text style combobox
376 configureMenu->addSection(i18nc("@item:inmenu Layers Docker settings, combobox", "Blending Info Style"));
377 infoTextCombobox = new QComboBox(this);
378 infoTextCombobox->setToolTip(i18nc("@item:tooltip", "None: Show nothing.\n"
379 "Simple: Show changed opacities or blending modes.\n"
380 "Balanced: Show both opacity and blending mode if either are changed.\n"
381 "Detailed: Show both opacity and blending mode even if unchanged."));
382 infoTextCombobox->insertItems(0, QStringList ({
383 i18nc("@item:inlistbox Layer Docker blending info style", "None"),
384 i18nc("@item:inlistbox Layer Docker blending info style", "Simple"),
385 i18nc("@item:inlistbox Layer Docker blending info style", "Balanced"),
386 i18nc("@item:inlistbox Layer Docker blending info style", "Detailed"),
387 }));
388 infoTextCombobox->setCurrentIndex((int)cfg.layerInfoTextStyle());
389
390 QWidgetAction *cmbboxAction = new QWidgetAction(this);
391 cmbboxAction->setDefaultWidget(infoTextCombobox);
392 configureMenu->addAction(cmbboxAction);
393 connect(infoTextCombobox, SIGNAL(currentIndexChanged(int)), SLOT(slotUpdateLayerInfoTextStyle()));
394
395 // info-text opacity slider
398 i18nc("{n} is the number value, % is the percent sign", "Opacity: {n}%"));
399 infoTextOpacitySlider->setToolTip(i18nc("@item:tooltip", "Blending info text opacity"));
400 // 55% is the opacity of nonvisible layer text
402 infoTextOpacitySlider->setMinimumSize(40, 20);
403 infoTextOpacitySlider->setSingleStep(5);
405 infoTextOpacitySlider->setValue(cfg.layerInfoTextOpacity());
406 if (infoTextCombobox->currentIndex() == 0) {
407 infoTextOpacitySlider->setDisabled(true);
408 }
409
410 sliderAction= new QWidgetAction(this);
411 sliderAction->setDefaultWidget(infoTextOpacitySlider);
412 configureMenu->addAction(sliderAction);
413 connect(infoTextOpacitySlider, SIGNAL(valueChanged(int)), &m_infoTextOpacityCompressor, SLOT(start()));
414 connect(&m_infoTextOpacityCompressor, SIGNAL(timeout()), SLOT(slotUpdateLayerInfoTextOpacity()));
415
416 // info-text inline checkbox
417 infoTextInlineChkbox = new QCheckBox(i18nc("@item:inmenu Layers Docker settings, checkbox", "Inline"), this);
418 infoTextInlineChkbox->setChecked(cfg.useInlineLayerInfoText());
419 infoTextInlineChkbox->setToolTip(i18nc("@item:tooltip", "If enabled, show blending info beside layer names.\n"
420 "If disabled, show below layer names (when enough space)."));
421 if (infoTextCombobox->currentIndex() == 0) {
422 infoTextInlineChkbox->setDisabled(true);
423 }
424
425 QWidgetAction *chkboxAction = new QWidgetAction(this);
426 chkboxAction->setDefaultWidget(infoTextInlineChkbox);
427 configureMenu->addAction(chkboxAction);
428 connect(infoTextInlineChkbox, SIGNAL(stateChanged(int)), SLOT(slotUpdateUseInlineLayerInfoText()));
429
430 layerSelectionCheckBox = new QCheckBox(
431 i18nc("@item:inmenu Layers Docker settings, checkbox", "Checkbox for Selecting Layers"), this);
432 layerSelectionCheckBox->setToolTip(i18nc("@item:tooltip", "Show checkbox to select/unselect layers."));
433 layerSelectionCheckBox->setChecked(cfg.useLayerSelectionCheckbox());
434
435 QWidgetAction *layerSelectionAction = new QWidgetAction(this);
436 layerSelectionAction->setDefaultWidget(layerSelectionCheckBox);
437 configureMenu->addAction(layerSelectionAction);
438 connect(layerSelectionCheckBox, SIGNAL(stateChanged(int)), SLOT(slotUpdateUseLayerSelectionCheckbox()));
439
443}
void setActivationFlags(ActivationFlags flags)
@ ACTIVE_IMAGE
Activate if there is at least one image.
Definition kis_action.h:43
QSet< int > getActiveColors() const
void filteringOptionsChanged()
void sigBeforeBeginRemoveRows(const QModelIndex &parent, int start, int end)
void sigScreenOrResolutionChanged(QScreen *screen)
This class is a spinbox in which you can click and drag to set the value. A slider like bar is displa...
void setValue(int newValue)
void setRange(int newMinimum, int newMaximum, bool computeNewFastSliderStep=true)
Set the minimum and the maximum values of the range, computing a new "fast slider step" based on the ...
void setPageStep(int newPageStep)
Does nothing currently.
void slotForgetAboutSavedNodeBeforeEditSelectionMode()
QComboBox * infoTextCombobox
Definition LayerBox.h:183
void updateAvailableLabels()
void slotOpacitySliderMoved(qreal opacity)
Definition LayerBox.cpp:885
void slotCollapsed(const QModelIndex &index)
Definition LayerBox.cpp:892
void slotCompositeOpChanged(int index)
Definition LayerBox.cpp:870
KisSignalCompressor m_colorLabelCompressor
Definition LayerBox.h:174
void slotContextMenuRequested(const QPoint &pos, const QModelIndex &index)
Definition LayerBox.cpp:813
KisLayerFilterWidget * layerFilterWidget
Definition LayerBox.h:180
void slotSyncThumbnailIconSize()
void selectionChanged(const QModelIndexList &selection)
void slotUpdateThumbnailIconSize()
QSlider * thumbnailSizeSlider
Definition LayerBox.h:181
KisSignalCompressor m_thumbnailSizeCompressor
Definition LayerBox.h:175
QCheckBox * infoTextInlineChkbox
Definition LayerBox.h:185
void slotUpdateLayerInfoTextStyle()
void slotUpdateUseInlineLayerInfoText()
QScopedPointer< KisScreenMigrationTracker > m_screenMigrationTracker
Definition LayerBox.h:191
void updateUI()
Definition LayerBox.cpp:676
QSlider * indentationSlider
Definition LayerBox.h:182
void slotModelReset()
Definition LayerBox.cpp:769
void slotEditGlobalSelection(bool showSelections)
Definition LayerBox.cpp:962
void slotUpdateIcons()
void slotExpanded(const QModelIndex &index)
Definition LayerBox.cpp:900
KisSignalCompressor m_infoTextOpacityCompressor
Definition LayerBox.h:177
KisAction * m_showGlobalSelectionMask
Definition LayerBox.h:173
KisSignalCompressor m_nodeOpacityCompressor
Definition LayerBox.h:178
void updateLayerFiltering()
void slotOpacityChanged()
Definition LayerBox.cpp:879
KisSliderSpinBox * infoTextOpacitySlider
Definition LayerBox.h:184
Ui_WdgLayerBox * m_wdgLayerBox
Definition LayerBox.h:165
QMenu * m_newLayerMenu
Definition LayerBox.h:157
QPointer< KisNodeFilterProxyModel > m_filteringModel
Definition LayerBox.h:161
void slotUpdateTreeIndentation()
QPointer< QWidgetAction > m_colorSelectorAction
Definition LayerBox.h:164
QPointer< KisColorLabelSelectorWidgetMenuWrapper > m_colorSelector
Definition LayerBox.h:163
void slotUpdateUseLayerSelectionCheckbox()
void slotUpdateLayerInfoTextOpacity()
void slotColorLabelChanged(int index)
QMenu * m_opLayerMenu
Definition LayerBox.h:158
void slotNodeCollapsedChanged()
Definition LayerBox.cpp:917
QPointer< KisNodeModel > m_nodeModel
Definition LayerBox.h:160
void slotAdjustCurrentBeforeRemoveRows(const QModelIndex &parent, int first, int last)
QCheckBox * layerSelectionCheckBox
Definition LayerBox.h:186
QPointer< KisCanvas2 > m_canvas
Definition LayerBox.h:155
KisSignalCompressor m_treeIndentationCompressor
Definition LayerBox.h:176
QIcon loadIcon(const QString &name)
void setText(QSpinBox *spinBox, const QStringView textTemplate)

References KisAction::ACTIVE_IMAGE, KisLayerFilterWidget::filteringOptionsChanged(), KisLayerFilterWidget::getActiveColors(), KisLayerFilterWidget::hasTextFilter(), indentationSlider, infoTextCombobox, infoTextInlineChkbox, infoTextOpacitySlider, KisLayerFilterWidget::isCurrentlyFiltering(), layerFilterWidget, KisConfig::layerInfoTextOpacity(), KisConfig::layerInfoTextStyle(), layerSelectionCheckBox, KisConfig::layerThumbnailSize(), KisConfig::layerTreeIndentation(), KisIconUtils::loadIcon(), m_colorLabelCompressor, m_colorSelector, m_colorSelectorAction, m_filteringModel, m_infoTextOpacityCompressor, m_newLayerMenu, m_nodeModel, m_nodeOpacityCompressor, m_opLayerMenu, m_screenMigrationTracker, m_showGlobalSelectionMask, m_thumbnailSizeCompressor, m_treeIndentationCompressor, m_wdgLayerBox, selectionChanged(), KisAction::setActivationFlags(), KisSliderSpinBox::setPageStep(), KisSliderSpinBox::setRange(), KisSpinBoxI18nHelper::setText(), KisSliderSpinBox::setValue(), KisConfig::showGlobalSelection(), KisNodeFilterProxyModel::sigBeforeBeginRemoveRows(), KisScreenMigrationTracker::sigScreenOrResolutionChanged(), KisConfig::sliderLabels(), slotAdjustCurrentBeforeRemoveRows(), slotCollapsed(), slotColorLabelChanged(), slotCompositeOpChanged(), slotContextMenuRequested(), slotEditGlobalSelection(), slotExpanded(), slotForgetAboutSavedNodeBeforeEditSelectionMode(), slotModelReset(), slotNodeCollapsedChanged(), slotOpacityChanged(), slotOpacitySliderMoved(), slotSyncThumbnailIconSize(), slotUpdateIcons(), slotUpdateLayerInfoTextOpacity(), slotUpdateLayerInfoTextStyle(), slotUpdateThumbnailIconSize(), slotUpdateTreeIndentation(), slotUpdateUseInlineLayerInfoText(), slotUpdateUseLayerSelectionCheckbox(), thumbnailSizeSlider, updateAvailableLabels(), updateLayerFiltering(), updateUI(), KisConfig::useInlineLayerInfoText(), and KisConfig::useLayerSelectionCheckbox().

◆ ~LayerBox()

LayerBox::~LayerBox ( )
override

Definition at line 445 of file LayerBox.cpp.

446{
447 delete m_wdgLayerBox;
448}

References m_wdgLayerBox.

Member Function Documentation

◆ addActionToMenu()

void LayerBox::addActionToMenu ( QMenu * menu,
const QString & id )
inlineprivate

Definition at line 143 of file LayerBox.cpp.

144{
145 if (m_canvas) {
146 menu->addAction(m_canvas->viewManager()->actionManager()->actionByName(id));
147 }
148}

References m_canvas.

◆ connectActionToButton()

void LayerBox::connectActionToButton ( KisViewManager * view,
QAbstractButton * button,
const QString & id )
inlineprivate

Definition at line 130 of file LayerBox.cpp.

131{
132 if (!viewManager || !button) return;
133
134 KisAction *action = viewManager->actionManager()->actionByName(id);
135
136 if (!action) return;
137
138 connect(button, SIGNAL(clicked()), action, SLOT(trigger()));
139 connect(action, SIGNAL(sigEnableSlaves(bool)), button, SLOT(setEnabled(bool)));
140 connect(viewManager->mainWindowAsQWidget(), SIGNAL(themeChanged()), this, SLOT(slotUpdateIcons()));
141}
KisAction * actionByName(const QString &name) const
KisActionManager * actionManager
QString button(const QWheelEvent &ev)

References KisActionManager::actionByName(), KisViewManager::actionManager(), button(), KisViewManager::mainWindowAsQWidget(), and slotUpdateIcons().

◆ convertOpacityToInt()

qint32 LayerBox::convertOpacityToInt ( qreal opacity)
private

Scales opacity from the range 0...100 to the integer range 0...255

Definition at line 150 of file LayerBox.cpp.

151{
157 return qMin(255, int(opacity * 2.55 + 0.5));
158}

◆ findNonHidableNode()

KisNodeSP LayerBox::findNonHidableNode ( KisNodeSP startNode)
private

Definition at line 929 of file LayerBox.cpp.

930{
931 if (KisNodeManager::isNodeHidden(startNode, true) &&
932 startNode->parent() &&
933 !startNode->parent()->parent()) {
934
935
936 KisNodeSP node = startNode->prevSibling();
937 while (node && KisNodeManager::isNodeHidden(node, true)) {
938 node = node->prevSibling();
939 }
940
941 if (!node) {
942 node = startNode->nextSibling();
943 while (node && KisNodeManager::isNodeHidden(node, true)) {
944 node = node->nextSibling();
945 }
946 }
947
948 if (!node) {
949 node = m_image->root()->lastChild();
950 while (node && KisNodeManager::isNodeHidden(node, true)) {
951 node = node->prevSibling();
952 }
953 }
954
955 KIS_ASSERT_RECOVER_NOOP(node && "cannot activate any node!");
956 startNode = node;
957 }
958
959 return startNode;
960}
static bool isNodeHidden(KisNodeSP node, bool isGlobalSelectionHidden)
KisImageWSP m_image
Definition LayerBox.h:159
#define KIS_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:97
KisNodeSP prevSibling() const
Definition kis_node.cpp:402
KisNodeWSP parent
Definition kis_node.cpp:86
KisNodeSP lastChild() const
Definition kis_node.cpp:367
KisNodeSP nextSibling() const
Definition kis_node.cpp:408

References KisNodeManager::isNodeHidden(), KIS_ASSERT_RECOVER_NOOP, KisNode::lastChild(), m_image, KisNode::nextSibling(), KisNode::parent, KisNode::prevSibling(), and KisNodeFacade::root.

◆ hideEvent()

void LayerBox::hideEvent ( QHideEvent * event)
overrideprotected

Definition at line 665 of file LayerBox.cpp.

666{
667 QDockWidget::hideEvent(event);
668 m_nodeModel->setIdleTaskManager(0);
669}

References m_nodeModel.

◆ imageChanged

void LayerBox::imageChanged ( )
signal

◆ notifyImageDeleted

void LayerBox::notifyImageDeleted ( )
privateslot

Definition at line 671 of file LayerBox.cpp.

672{
673 setCanvas(0);
674}
void setCanvas(KoCanvasBase *canvas) override
Definition LayerBox.cpp:545

References setCanvas().

◆ observerName()

QString LayerBox::observerName ( )
inlineoverridevirtual

Reimplemented from KoCanvasObserverBase.

Definition at line 73 of file LayerBox.h.

73{ return "LayerBox"; }

◆ selectionChanged

void LayerBox::selectionChanged ( const QModelIndexList & selection)
privateslot

When the user clears the extended selection by clicking on the empty area of the docker, the selection should be reset on to the active layer, which might be even unselected(!).

Definition at line 1046 of file LayerBox.cpp.

1047{
1048 if (!m_nodeManager) return;
1049
1055 if (selection.isEmpty() && m_nodeManager->activeNode()) {
1056 QModelIndex selectedIndex =
1057 m_filteringModel->indexFromNode(m_nodeManager->activeNode());
1058
1059 m_wdgLayerBox->listLayers->selectionModel()->
1060 setCurrentIndex(selectedIndex, QItemSelectionModel::ClearAndSelect);
1061 return;
1062 }
1063
1064 QList<KisNodeSP> selectedNodes;
1065 Q_FOREACH (const QModelIndex &idx, selection) {
1066 // Precaution because node manager doesn't like duplicates in that list.
1067 // NodeView Selection behavior is SelectRows, although currently only column 0 allows selections.
1068 if (idx.column() != 0) {
1069 continue;
1070 }
1071 selectedNodes << m_filteringModel->nodeFromIndex(idx);
1072 }
1073
1074 m_nodeManager->slotSetSelectedNodes(selectedNodes);
1075 updateUI();
1076}
QPointer< KisNodeManager > m_nodeManager
Definition LayerBox.h:162

References m_filteringModel, m_nodeManager, m_wdgLayerBox, and updateUI().

◆ setCanvas()

void LayerBox::setCanvas ( KoCanvasBase * canvas)
overridevirtual

re-implement this method in your canvas observer. It will be called whenever a canvas becomes active. Note that you are responsible for not connecting more than one time to the signals of a canvas or any of the QObjects you can access through the canvas.

Implements KoCanvasObserverBase.

Definition at line 545 of file LayerBox.cpp.

546{
547 if (m_canvas == canvas)
548 return;
549
550 setEnabled(canvas != 0);
551
552 if (m_canvas) {
553 m_canvas->disconnectCanvasObserver(this);
554 m_nodeModel->setIdleTaskManager(0);
555 m_nodeModel->setDummiesFacade(0, 0, 0, 0, 0);
557
558 if (m_image) {
560 animation->disconnect(this);
561 }
562
563 disconnect(m_image, 0, this, 0);
564 disconnect(m_nodeManager, 0, this, 0);
565 disconnect(m_nodeModel, 0, m_nodeManager, 0);
566 m_nodeManager->slotSetSelectedNodes(KisNodeList());
567 }
568
569 m_canvas = dynamic_cast<KisCanvas2*>(canvas);
570
571 if (m_canvas) {
572 m_image = m_canvas->image();
573 Q_EMIT imageChanged();
574
575 KisDocument* doc = static_cast<KisDocument*>(m_canvas->imageView()->document());
576 KisShapeController *kritaShapeController =
577 dynamic_cast<KisShapeController*>(doc->shapeController());
578 KisDummiesFacadeBase *kritaDummiesFacade =
579 static_cast<KisDummiesFacadeBase*>(kritaShapeController);
580
581
582 m_selectionActionsAdapter.reset(new KisSelectionActionsAdapter(m_canvas->viewManager()->selectionManager()));
583 m_nodeModel->setDummiesFacade(kritaDummiesFacade,
584 m_image,
585 kritaShapeController,
588
589 if (isVisible()) {
590 m_nodeModel->setIdleTaskManager(m_canvas->viewManager()->idleTasksManager());
591 }
592
593 connect(m_image, SIGNAL(sigAboutToBeDeleted()), SLOT(notifyImageDeleted()));
594 connect(m_image, SIGNAL(sigNodeCollapsedChanged()), SLOT(slotNodeCollapsedChanged()));
595
596 // cold start
597 if (m_nodeManager) {
598 setCurrentNode(m_nodeManager->activeNode());
599 // Connection KisNodeManager -> LayerBox
600 connect(m_nodeManager, SIGNAL(sigUiNeedChangeActiveNode(KisNodeSP)),
601 this, SLOT(setCurrentNode(KisNodeSP)));
602
603 connect(m_nodeManager,
604 SIGNAL(sigUiNeedChangeSelectedNodes(QList<KisNodeSP>)),
606 }
607 else {
608 setCurrentNode(m_canvas->imageView()->currentNode());
609 }
610
611 // Connection LayerBox -> KisNodeManager (isolate layer)
612 connect(m_nodeModel, SIGNAL(toggleIsolateActiveNode()),
613 m_nodeManager, SLOT(toggleIsolateActiveNode()));
614
617
619 m_wdgLayerBox->listLayers->scrollTo(m_wdgLayerBox->listLayers->currentIndex());
621
622 addActionToMenu(m_newLayerMenu, "add_new_paint_layer");
623 addActionToMenu(m_newLayerMenu, "add_new_group_layer");
624 addActionToMenu(m_newLayerMenu, "add_new_clone_layer");
625 addActionToMenu(m_newLayerMenu, "add_new_shape_layer");
626 addActionToMenu(m_newLayerMenu, "add_new_adjustment_layer");
627 addActionToMenu(m_newLayerMenu, "add_new_fill_layer");
628 addActionToMenu(m_newLayerMenu, "add_new_file_layer");
629 m_newLayerMenu->addSeparator();
630 addActionToMenu(m_newLayerMenu, "add_new_transparency_mask");
631 addActionToMenu(m_newLayerMenu, "add_new_filter_mask");
632 addActionToMenu(m_newLayerMenu, "add_new_fast_color_overlay_mask");
633 addActionToMenu(m_newLayerMenu, "add_new_colorize_mask");
634 addActionToMenu(m_newLayerMenu, "add_new_transform_mask");
635 addActionToMenu(m_newLayerMenu, "add_new_selection_mask");
636 }
637}
void expandNodesRecursively(KisNodeSP root, QPointer< KisNodeFilterProxyModel > filteringModel, NodeView *nodeView)
Definition LayerBox.cpp:451
KisShapeController * shapeController
void sigUiTimeChanged(int newTime)
KisGroupLayerSP rootLayer() const
KisImageAnimationInterface * animationInterface() const
void slotImageTimeChanged(int time)
void imageChanged()
void addActionToMenu(QMenu *menu, const QString &id)
Definition LayerBox.cpp:143
void slotNodeManagerChangedSelection(const QList< KisNodeSP > &nodes)
QScopedPointer< KisSelectionActionsAdapter > m_selectionActionsAdapter
Definition LayerBox.h:156
void setCurrentNode(KisNodeSP node)
Definition LayerBox.cpp:746
void notifyImageDeleted()
Definition LayerBox.cpp:671
QList< KisNodeSP > KisNodeList
Definition kis_types.h:264

References addActionToMenu(), KisImage::animationInterface(), expandNodesRecursively(), imageChanged(), m_canvas, m_filteringModel, m_image, m_newLayerMenu, m_nodeManager, m_nodeModel, m_selectionActionsAdapter, m_wdgLayerBox, notifyImageDeleted(), KisImage::rootLayer(), setCurrentNode(), KisDocument::shapeController, KisImageAnimationInterface::sigUiTimeChanged(), slotImageTimeChanged(), slotNodeCollapsedChanged(), slotNodeManagerChangedSelection(), and updateAvailableLabels().

◆ setCurrentNode

void LayerBox::setCurrentNode ( KisNodeSP node)
privateslot

This method is called only when non-GUI code requested the change of the current node

setCanvas() calls to node managed and layer box are coming out-of-sync, so it might happen that setCurrentNode() call will arrive with a node from a different image. We should check that and ignore such calls.

TODO: make bootstrapping of layers-related structures a bit more straight-forward. We need to have a single source of truth for the "active layer", and all the initialization should happen in one direction without cycles.

Definition at line 746 of file LayerBox.cpp.

747{
758 if (node && m_image && node->graphListener() != m_image.data()) {
759 return;
760 }
761
762 m_filteringModel->setActiveNode(node);
763
764 QModelIndex index = node ? m_filteringModel->indexFromNode(node) : QModelIndex();
765 m_filteringModel->setData(index, true, KisNodeModel::ActiveRole);
766 updateUI();
767}
@ ActiveRole
Whether the section is the active one.
KisNodeGraphListener * graphListener
Definition kis_node.cpp:87

References KisNodeModel::ActiveRole, KisWeakSharedPtr< T >::data(), KisNode::graphListener, m_filteringModel, m_image, and updateUI().

◆ setViewManager()

void LayerBox::setViewManager ( KisViewManager * kisview)
overridevirtual

reimplemented from KisMainwindowObserver

Implements KisMainwindowObserver.

Definition at line 488 of file LayerBox.cpp.

489{
490 m_nodeManager = kisview->nodeManager();
491
492 if (m_nodeManager) {
493 connect(m_nodeManager, SIGNAL(sigNodeActivated(KisNodeSP)), SLOT(slotForgetAboutSavedNodeBeforeEditSelectionMode()));
494 }
495
496 kisview->actionManager()->
497 addAction(m_showGlobalSelectionMask->objectName(),
499
500 connect(m_wdgLayerBox->bnAdd, SIGNAL(clicked()), this, SLOT(slotAddLayerBnClicked()));
501
502 connectActionToButton(kisview, m_wdgLayerBox->bnDuplicate, "duplicatelayer");
503
504 KisActionManager *actionManager = kisview->actionManager();
505
506 KisAction *action = actionManager->createAction("RenameCurrentLayer");
507 Q_ASSERT(action);
508 connect(action, SIGNAL(triggered()), this, SLOT(slotRenameCurrentNode()));
509
510 m_propertiesAction = actionManager->createAction("layer_properties");
511 Q_ASSERT(m_propertiesAction);
512 new SyncButtonAndAction(m_propertiesAction, m_wdgLayerBox->bnProperties, this);
513 connect(m_propertiesAction, SIGNAL(triggered()), this, SLOT(slotPropertiesClicked()));
514
515 connect(m_opLayerMenu, SIGNAL(aboutToShow()), this, SLOT(slotLayerOpMenuOpened()));
516
517 // It's necessary to clear the layer operations menu when it closes, else
518 // the color selector can't be shared with the right-click context menu
519 connect(m_opLayerMenu, SIGNAL(aboutToHide()), this, SLOT(slotLayerOpMenuClosed()));
520
521 m_removeAction = actionManager->createAction("remove_layer");
522 Q_ASSERT(m_removeAction);
524 connect(m_removeAction, SIGNAL(triggered()), this, SLOT(slotRmClicked()));
525
526 action = actionManager->createAction("move_layer_up");
527 Q_ASSERT(action);
528 new SyncButtonAndAction(action, m_wdgLayerBox->bnRaise, this);
529 connect(action, SIGNAL(triggered()), this, SLOT(slotRaiseClicked()));
530
531 action = actionManager->createAction("move_layer_down");
532 Q_ASSERT(action);
533 new SyncButtonAndAction(action, m_wdgLayerBox->bnLower, this);
534 connect(action, SIGNAL(triggered()), this, SLOT(slotLowerClicked()));
535
536 m_changeCloneSourceAction = actionManager->createAction("set-copy-from");
538 connect(m_changeCloneSourceAction, &KisAction::triggered,
540
541 m_layerToggleSolo = actionManager->createAction("toggle_layer_soloing");
542 connect(m_layerToggleSolo, SIGNAL(triggered(bool)), this, SLOT(toggleActiveLayerSolo()));
543}
A KisActionManager class keeps track of KisActions. These actions are always associated with the GUI....
KisAction * createAction(const QString &name)
KisActionManager * actionManager() const
KisNodeManager * nodeManager() const
The node manager handles everything about nodes.
void slotRmClicked()
Definition LayerBox.cpp:826
KisAction * m_changeCloneSourceAction
Definition LayerBox.h:171
void slotRaiseClicked()
Definition LayerBox.cpp:832
void connectActionToButton(KisViewManager *view, QAbstractButton *button, const QString &id)
Definition LayerBox.cpp:130
void toggleActiveLayerSolo()
KisAction * m_layerToggleSolo
Definition LayerBox.h:172
void slotLayerOpMenuOpened()
Definition LayerBox.cpp:852
KisAction * m_propertiesAction
Definition LayerBox.h:170
void slotLowerClicked()
Definition LayerBox.cpp:838
void slotAddLayerBnClicked()
Definition LayerBox.cpp:473
void slotPropertiesClicked()
Definition LayerBox.cpp:844
void slotRenameCurrentNode()
void slotChangeCloneSourceClicked()
Definition LayerBox.cpp:864
KisAction * m_removeAction
Definition LayerBox.h:169
void slotLayerOpMenuClosed()
Definition LayerBox.cpp:858

References KisViewManager::actionManager(), connectActionToButton(), KisActionManager::createAction(), m_changeCloneSourceAction, m_layerToggleSolo, m_nodeManager, m_opLayerMenu, m_propertiesAction, m_removeAction, m_showGlobalSelectionMask, m_wdgLayerBox, KisViewManager::nodeManager(), slotAddLayerBnClicked(), slotChangeCloneSourceClicked(), slotForgetAboutSavedNodeBeforeEditSelectionMode(), slotLayerOpMenuClosed(), slotLayerOpMenuOpened(), slotLowerClicked(), slotPropertiesClicked(), slotRaiseClicked(), slotRenameCurrentNode(), slotRmClicked(), and toggleActiveLayerSolo().

◆ showEvent()

void LayerBox::showEvent ( QShowEvent * event)
overrideprotected

Definition at line 656 of file LayerBox.cpp.

657{
658 QDockWidget::showEvent(event);
659
660 if (m_canvas) {
661 m_nodeModel->setIdleTaskManager(m_canvas->viewManager()->idleTasksManager());
662 }
663}

References m_canvas, and m_nodeModel.

◆ slotAddLayerBnClicked

void LayerBox::slotAddLayerBnClicked ( )
privateslot

Definition at line 473 of file LayerBox.cpp.

474{
475 if (m_canvas) {
476 KisNodeList nodes = m_nodeManager->selectedNodes();
477
478 if (nodes.size() == 1) {
479 KisAction *action = m_canvas->viewManager()->actionManager()->actionByName("add_new_paint_layer");
480 action->trigger();
481 } else {
482 KisAction *action = m_canvas->viewManager()->actionManager()->actionByName("create_quick_group");
483 action->trigger();
484 }
485 }
486}

References m_canvas, and m_nodeManager.

◆ slotAdjustCurrentBeforeRemoveRows

void LayerBox::slotAdjustCurrentBeforeRemoveRows ( const QModelIndex & parent,
int first,
int last )
privateslot

Qt has changed its behavior when deleting an item. Previously the selection priority was on the next item in the list, and now it has changed to the previous item. Here we just adjust the selected item after the node removal.

This method is called right before the Qt's beginRemoveRows() is called, that is we make sure that Qt will never have to adjust the position of the removed cursor.

See bug: https://bugs.kde.org/show_bug.cgi?id=345601

Definition at line 1078 of file LayerBox.cpp.

1079{
1093 QModelIndex currentIndex = m_wdgLayerBox->listLayers->currentIndex();
1094 QAbstractItemModel *model = m_filteringModel;
1095
1096 if (currentIndex.isValid() && parent == currentIndex.parent()
1097 && currentIndex.row() >= start && currentIndex.row() <= end) {
1098 QModelIndex old = currentIndex;
1099
1100 if (model && end < model->rowCount(parent) - 1) // there are rows left below the change
1101 currentIndex = model->index(end + 1, old.column(), parent);
1102 else if (model && start > 0) // there are rows left above the change
1103 currentIndex = model->index(start - 1, old.column(), parent);
1104 else // there are no rows left in the table
1105 currentIndex = QModelIndex();
1106
1107 if (currentIndex.isValid() && currentIndex != old) {
1108 m_wdgLayerBox->listLayers->setCurrentIndex(currentIndex);
1109 }
1110 }
1111}

References m_filteringModel, and m_wdgLayerBox.

◆ slotChangeCloneSourceClicked

void LayerBox::slotChangeCloneSourceClicked ( )
privateslot

Definition at line 864 of file LayerBox.cpp.

865{
866 if (!m_canvas) return;
867 m_nodeManager->changeCloneSource();
868}

References m_canvas, and m_nodeManager.

◆ slotCollapsed

void LayerBox::slotCollapsed ( const QModelIndex & index)
privateslot

Definition at line 892 of file LayerBox.cpp.

893{
894 KisNodeSP node = m_filteringModel->nodeFromIndex(index);
895 if (node) {
896 node->setCollapsed(true);
897 }
898}
void setCollapsed(bool collapsed)

References m_filteringModel, and KisBaseNode::setCollapsed().

◆ slotColorLabelChanged

void LayerBox::slotColorLabelChanged ( int index)
privateslot

Definition at line 1141 of file LayerBox.cpp.

1142{
1143 KisNodeList selectedNodes = m_nodeManager->selectedNodes();
1144
1145 Q_FOREACH(KisNodeSP selectedNode, selectedNodes) {
1146 //Always apply label to selected nodes..
1147 selectedNode->setColorLabelIndex(label);
1148
1149 //Apply label only to unlabelled children..
1150 KisNodeList children = selectedNode->childNodes(QStringList(), KoProperties());
1151
1152 auto applyLabelFunc =
1153 [label](KisNodeSP child) {
1154 if (child->colorLabelIndex() == 0) {
1155 child->setColorLabelIndex(label);
1156 }
1157 };
1158
1159 Q_FOREACH(KisNodeSP child, children) {
1160 KisLayerUtils::recursiveApplyNodes(child, applyLabelFunc);
1161 }
1162 }
1163}
QList< QString > QStringList
void recursiveApplyNodes(NodePointer node, Functor func)
void setColorLabelIndex(int index)
QList< KisNodeSP > childNodes(const QStringList &nodeTypes, const KoProperties &properties) const
Definition kis_node.cpp:439

References KisNode::childNodes(), m_nodeManager, KisLayerUtils::recursiveApplyNodes(), and KisBaseNode::setColorLabelIndex().

◆ slotCompositeOpChanged

void LayerBox::slotCompositeOpChanged ( int index)
privateslot

Definition at line 870 of file LayerBox.cpp.

871{
872 Q_UNUSED(index);
873 if (!m_canvas) return;
874
875 QString compositeOp = m_wdgLayerBox->cmbComposite->selectedCompositeOp().id();
876 m_nodeManager->nodeCompositeOpChanged(m_nodeManager->activeColorSpace()->compositeOp(compositeOp));
877}

References m_canvas, m_nodeManager, and m_wdgLayerBox.

◆ slotContextMenuRequested

void LayerBox::slotContextMenuRequested ( const QPoint & pos,
const QModelIndex & index )
privateslot

Definition at line 813 of file LayerBox.cpp.

814{
815 KisNodeList nodes = m_nodeManager->selectedNodes();
816 KisNodeSP activeNode = m_nodeManager->activeNode();
817 if (nodes.isEmpty() || !activeNode) return;
818
819 if (m_canvas) {
820 QMenu menu;
821 updateLayerOpMenu(index, menu);
822 menu.exec(pos);
823 }
824}
void updateLayerOpMenu(const QModelIndex &index, QMenu &menu)

References m_canvas, m_nodeManager, and updateLayerOpMenu().

◆ slotEditGlobalSelection

void LayerBox::slotEditGlobalSelection ( bool showSelections)
privateslot

Definition at line 962 of file LayerBox.cpp.

963{
964 KisNodeSP lastActiveNode = m_nodeManager->activeNode();
965 KisNodeSP activateNode = lastActiveNode;
966 KisSelectionMaskSP globalSelectionMask;
967
968 if (!showSelections) {
969 activateNode =
972 findNonHidableNode(activateNode);
973 }
974
975 m_nodeModel->setShowGlobalSelection(showSelections);
976
977 globalSelectionMask = m_image->rootLayer()->selectionMask();
978
979 // try to find deactivated, but visible masks
980 if (!globalSelectionMask) {
981 KoProperties properties;
982 properties.setProperty("visible", true);
983 QList<KisNodeSP> masks = m_image->rootLayer()->childNodes(QStringList("KisSelectionMask"), properties);
984 if (!masks.isEmpty()) {
985 globalSelectionMask = dynamic_cast<KisSelectionMask*>(masks.first().data());
986 }
987 }
988
989 // try to find at least any selection mask
990 if (!globalSelectionMask) {
991 KoProperties properties;
992 QList<KisNodeSP> masks = m_image->rootLayer()->childNodes(QStringList("KisSelectionMask"), properties);
993 if (!masks.isEmpty()) {
994 globalSelectionMask = dynamic_cast<KisSelectionMask*>(masks.first().data());
995 }
996 }
997
998 if (globalSelectionMask) {
999 if (showSelections) {
1000 activateNode = globalSelectionMask;
1001 }
1002 }
1003
1004 if (activateNode != lastActiveNode) {
1005 m_nodeManager->slotNonUiActivatedNode(activateNode);
1006 } else if (lastActiveNode) {
1007 setCurrentNode(lastActiveNode);
1008 }
1009
1010 if (showSelections && !globalSelectionMask) {
1011 KisProcessingApplicator applicator(m_image, 0,
1014 kundo2_i18n("Quick Selection Mask"));
1015
1016 applicator.applyCommand(
1018 m_nodeManager->selectedNodes(), KisNodeList(),
1019 lastActiveNode, 0, m_image, false),
1021 applicator.applyCommand(new KisSetEmptyGlobalSelectionCommand(m_image),
1024 applicator.applyCommand(new KisLayerUtils::SelectGlobalSelectionMask(m_image),
1027
1028 applicator.end();
1029 } else if (!showSelections &&
1030 globalSelectionMask &&
1031 globalSelectionMask->selection()->selectedRect().isEmpty()) {
1032
1033 KisProcessingApplicator applicator(m_image, 0,
1036 kundo2_i18n("Cancel Quick Selection Mask"));
1038 applicator.end();
1039 }
1040
1041 if (showSelections) {
1042 m_savedNodeBeforeEditSelectionMode = lastActiveNode;
1043 }
1044}
QVector< KisImageSignalType > KisImageSignalVector
void setProperty(const QString &name, const QVariant &value)
KisNodeSP findNonHidableNode(KisNodeSP startNode)
Definition LayerBox.cpp:929
KisNodeWSP m_savedNodeBeforeEditSelectionMode
Definition LayerBox.h:189
KisSharedPtr< KisNode > KisNodeSP
Definition kis_types.h:86
KUndo2MagicString kundo2_i18n(const char *text)
virtual KisSelectionMaskSP selectionMask() const
Definition kis_layer.cc:504
KisSelectionSP selection
Definition kis_mask.cc:44
QRect selectedRect() const

References KisProcessingApplicator::applyCommand(), KisNode::childNodes(), KisProcessingApplicator::end(), KisStrokeJobData::EXCLUSIVE, findNonHidableNode(), kundo2_i18n(), m_image, m_nodeManager, m_nodeModel, m_savedNodeBeforeEditSelectionMode, KisProcessingApplicator::NONE, KisImage::rootLayer(), KisSelection::selectedRect(), KisMask::selection, KisLayer::selectionMask(), KisStrokeJobData::SEQUENTIAL, setCurrentNode(), and KoProperties::setProperty().

◆ slotExpanded

void LayerBox::slotExpanded ( const QModelIndex & index)
privateslot

Definition at line 900 of file LayerBox.cpp.

901{
902 KisNodeSP node = m_filteringModel->nodeFromIndex(index);
903 if (node) {
904 node->setCollapsed(false);
905 }
906}

References m_filteringModel, and KisBaseNode::setCollapsed().

◆ slotForgetAboutSavedNodeBeforeEditSelectionMode

void LayerBox::slotForgetAboutSavedNodeBeforeEditSelectionMode ( )
privateslot

Definition at line 1299 of file LayerBox.cpp.

1300{
1302}

References m_savedNodeBeforeEditSelectionMode.

◆ slotImageTimeChanged

void LayerBox::slotImageTimeChanged ( int time)
privateslot

Definition at line 1177 of file LayerBox.cpp.

1178{
1179 Q_UNUSED(time);
1180 updateUI();
1181}

References updateUI().

◆ slotLayerOpMenuClosed

void LayerBox::slotLayerOpMenuClosed ( )
privateslot

Definition at line 858 of file LayerBox.cpp.

859{
860 if (!m_canvas) return;
861 m_opLayerMenu->clear();
862}

References m_canvas, and m_opLayerMenu.

◆ slotLayerOpMenuOpened

void LayerBox::slotLayerOpMenuOpened ( )
privateslot

Definition at line 852 of file LayerBox.cpp.

853{
854 if (!m_canvas) return;
855 updateLayerOpMenu(m_wdgLayerBox->listLayers->currentIndex(), *m_opLayerMenu);
856}

References m_canvas, m_opLayerMenu, m_wdgLayerBox, and updateLayerOpMenu().

◆ slotLowerClicked

void LayerBox::slotLowerClicked ( )
privateslot

Definition at line 838 of file LayerBox.cpp.

839{
840 if (!m_canvas) return;
841 m_nodeManager->lowerNode();
842}

References m_canvas, and m_nodeManager.

◆ slotModelReset

void LayerBox::slotModelReset ( )
privateslot

Definition at line 769 of file LayerBox.cpp.

770{
771 if(m_nodeModel->hasDummiesFacade()) {
772 QItemSelection selection;
773 Q_FOREACH (const KisNodeSP node, m_nodeManager->selectedNodes()) {
774 const QModelIndex &idx = m_filteringModel->indexFromNode(node);
775 if(idx.isValid()){
776 QItemSelectionRange selectionRange(idx);
777 selection << selectionRange;
778 }
779 }
780
781 m_wdgLayerBox->listLayers->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect);
782 }
783
784 updateUI();
785}

References m_filteringModel, m_nodeManager, m_nodeModel, m_wdgLayerBox, and updateUI().

◆ slotNodeCollapsedChanged

void LayerBox::slotNodeCollapsedChanged ( )
privateslot

Definition at line 917 of file LayerBox.cpp.

918{
919 if (m_nodeModel->hasDummiesFacade()) {
921 }
922}

References expandNodesRecursively(), m_filteringModel, m_image, m_nodeModel, m_wdgLayerBox, and KisImage::rootLayer().

◆ slotNodeManagerChangedSelection

void LayerBox::slotNodeManagerChangedSelection ( const QList< KisNodeSP > & nodes)
privateslot

Definition at line 1113 of file LayerBox.cpp.

1114{
1115 if (!m_nodeManager) return;
1116
1117 QModelIndexList newSelection;
1118 Q_FOREACH(KisNodeSP node, nodes) {
1119 newSelection << m_filteringModel->indexFromNode(node);
1120 }
1121
1122 QItemSelectionModel *model = m_wdgLayerBox->listLayers->selectionModel();
1123
1124 if (KritaUtils::compareListsUnordered(newSelection, model->selectedRows())) {
1125 return;
1126 }
1127
1128 QItemSelection selection;
1129 Q_FOREACH(const QModelIndex &idx, newSelection) {
1130 selection.select(idx, idx);
1131 }
1132
1133 model->select(selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
1134}
bool compareListsUnordered(const QList< T > &a, const QList< T > &b)

References KritaUtils::compareListsUnordered(), m_filteringModel, m_nodeManager, and m_wdgLayerBox.

◆ slotOpacityChanged

void LayerBox::slotOpacityChanged ( )
privateslot

Definition at line 879 of file LayerBox.cpp.

880{
881 if (!m_canvas) return;
883}
qint32 convertOpacityToInt(qreal opacity)
Definition LayerBox.cpp:150
KisNodeSP m_changedOpacityNode
Definition LayerBox.h:167
int m_newOpacity
Definition LayerBox.h:166

References convertOpacityToInt(), m_canvas, m_changedOpacityNode, m_newOpacity, and m_nodeManager.

◆ slotOpacitySliderMoved

void LayerBox::slotOpacitySliderMoved ( qreal opacity)
privateslot

◆ slotPropertiesClicked

void LayerBox::slotPropertiesClicked ( )
privateslot

Definition at line 844 of file LayerBox.cpp.

845{
846 if (!m_canvas) return;
847 if (KisNodeSP active = m_nodeManager->activeNode()) {
848 m_nodeManager->nodeProperties(active);
849 }
850}

References m_canvas, and m_nodeManager.

◆ slotRaiseClicked

void LayerBox::slotRaiseClicked ( )
privateslot

Definition at line 832 of file LayerBox.cpp.

833{
834 if (!m_canvas) return;
835 m_nodeManager->raiseNode();
836}

References m_canvas, and m_nodeManager.

◆ slotRenameCurrentNode

void LayerBox::slotRenameCurrentNode ( )
privateslot

Definition at line 1136 of file LayerBox.cpp.

1137{
1138 m_wdgLayerBox->listLayers->edit(m_wdgLayerBox->listLayers->currentIndex());
1139}

References m_wdgLayerBox.

◆ slotRmClicked

void LayerBox::slotRmClicked ( )
privateslot

Definition at line 826 of file LayerBox.cpp.

827{
828 if (!m_canvas) return;
829 m_nodeManager->removeNode();
830}

References m_canvas, and m_nodeManager.

◆ slotSelectOpaque

void LayerBox::slotSelectOpaque ( )
privateslot

Definition at line 908 of file LayerBox.cpp.

909{
910 if (!m_canvas) return;
911 QAction *action = m_canvas->viewManager()->actionManager()->actionByName("selectopaque");
912 if (action) {
913 action->trigger();
914 }
915}

References m_canvas.

◆ slotSetCompositeOp

void LayerBox::slotSetCompositeOp ( const KoCompositeOp * compositeOp)
privateslot

Definition at line 787 of file LayerBox.cpp.

788{
789 KoID opId = KoCompositeOpRegistry::instance().getKoID(compositeOp->id());
790
791 m_wdgLayerBox->cmbComposite->blockSignals(true);
792 m_wdgLayerBox->cmbComposite->selectCompositeOp(opId);
793 m_wdgLayerBox->cmbComposite->blockSignals(false);
794}
static const KoCompositeOpRegistry & instance()
KoID getKoID(const QString &compositeOpID) const
Definition KoID.h:30

References KoCompositeOpRegistry::getKoID(), KoCompositeOp::id, KoCompositeOpRegistry::instance(), and m_wdgLayerBox.

◆ slotSetOpacity

void LayerBox::slotSetOpacity ( double opacity)
privateslot

Definition at line 797 of file LayerBox.cpp.

798{
799 Q_ASSERT(opacity >= 0 && opacity <= 100);
800 m_wdgLayerBox->doubleOpacity->blockSignals(true);
801 m_wdgLayerBox->doubleOpacity->setValue(opacity);
802 m_wdgLayerBox->doubleOpacity->blockSignals(false);
803}

References m_wdgLayerBox.

◆ slotSyncThumbnailIconSize

void LayerBox::slotSyncThumbnailIconSize ( )
privateslot

Definition at line 1342 of file LayerBox.cpp.

1343{
1344 m_nodeModel->setPreferredThumnalSize(thumbnailSizeSlider->value() * m_wdgLayerBox->listLayers->devicePixelRatioF());
1345}

References m_nodeModel, m_wdgLayerBox, and thumbnailSizeSlider.

◆ slotUpdateIcons

void LayerBox::slotUpdateIcons ( )
privateslot

Definition at line 1304 of file LayerBox.cpp.

1304 {
1305 m_wdgLayerBox->bnAdd->setIcon(KisIconUtils::loadIcon("addlayer"));
1306 m_wdgLayerBox->bnRaise->setIcon(KisIconUtils::loadIcon("arrowup"));
1307 m_wdgLayerBox->bnDelete->setIcon(KisIconUtils::loadIcon("deletelayer"));
1308 m_wdgLayerBox->bnLower->setIcon(KisIconUtils::loadIcon("arrowdown"));
1309 m_wdgLayerBox->bnProperties->setIcon(KisIconUtils::loadIcon("properties"));
1310 m_wdgLayerBox->bnDuplicate->setIcon(KisIconUtils::loadIcon("duplicatelayer"));
1311 m_wdgLayerBox->configureLayerDockerToolbar->setIcon(KisIconUtils::loadIcon("view-choose"));
1312
1313 // call child function about needing to update icons
1314 m_wdgLayerBox->listLayers->slotUpdateIcons();
1315}

References KisIconUtils::loadIcon(), and m_wdgLayerBox.

◆ slotUpdateLayerInfoTextOpacity

void LayerBox::slotUpdateLayerInfoTextOpacity ( )
privateslot

Definition at line 1376 of file LayerBox.cpp.

1377{
1378 KisConfig cfg(false);
1379 if (infoTextOpacitySlider->value() == cfg.layerInfoTextOpacity()) {
1380 return;
1381 }
1382 cfg.setLayerInfoTextOpacity(infoTextOpacitySlider->value());
1383 m_wdgLayerBox->listLayers->slotConfigurationChanged();
1384 m_wdgLayerBox->listLayers->viewport()->update();
1385}

References infoTextOpacitySlider, KisConfig::layerInfoTextOpacity(), m_wdgLayerBox, and KisConfig::setLayerInfoTextOpacity().

◆ slotUpdateLayerInfoTextStyle

void LayerBox::slotUpdateLayerInfoTextStyle ( )
privateslot

Definition at line 1357 of file LayerBox.cpp.

1358{
1359 KisConfig cfg(false);
1360 if (infoTextCombobox->currentIndex() == cfg.layerInfoTextStyle()) {
1361 return;
1362 }
1363 cfg.setLayerInfoTextStyle((KisConfig::LayerInfoTextStyle)infoTextCombobox->currentIndex());
1364 m_wdgLayerBox->listLayers->slotConfigurationChanged();
1365 m_wdgLayerBox->listLayers->viewport()->update();
1366 if (infoTextCombobox->currentIndex() == 0) {
1367 infoTextOpacitySlider->setDisabled(true);
1368 infoTextInlineChkbox->setDisabled(true);
1369 }
1370 else {
1371 infoTextOpacitySlider->setDisabled(false);
1372 infoTextInlineChkbox->setDisabled(false);
1373 }
1374}

References infoTextCombobox, infoTextInlineChkbox, infoTextOpacitySlider, KisConfig::layerInfoTextStyle(), m_wdgLayerBox, and KisConfig::setLayerInfoTextStyle().

◆ slotUpdateOpacitySlider

void LayerBox::slotUpdateOpacitySlider ( quint8 value)
privateslot

Definition at line 805 of file LayerBox.cpp.

805 {
806 double percentage = value * 100.0 / 255.0;
807
808 m_wdgLayerBox->doubleOpacity->blockSignals(true);
809 m_wdgLayerBox->doubleOpacity->setValue(percentage);
810 m_wdgLayerBox->doubleOpacity->blockSignals(false);
811}
float value(const T *src, size_t ch)

References m_wdgLayerBox, and value().

◆ slotUpdateThumbnailIconSize

void LayerBox::slotUpdateThumbnailIconSize ( )
privateslot

Definition at line 1333 of file LayerBox.cpp.

1334{
1335 KisConfig cfg(false);
1336 cfg.setLayerThumbnailSize(thumbnailSizeSlider->value());
1337
1338 m_nodeModel->setPreferredThumnalSize(thumbnailSizeSlider->value() * m_wdgLayerBox->listLayers->devicePixelRatioF());
1339 m_wdgLayerBox->listLayers->slotConfigurationChanged();
1340}

References m_nodeModel, m_wdgLayerBox, KisConfig::setLayerThumbnailSize(), and thumbnailSizeSlider.

◆ slotUpdateTreeIndentation

void LayerBox::slotUpdateTreeIndentation ( )
privateslot

Definition at line 1347 of file LayerBox.cpp.

1348{
1349 KisConfig cfg(false);
1350 if (indentationSlider->value() == cfg.layerTreeIndentation()) {
1351 return;
1352 }
1353 cfg.setLayerTreeIndentation(indentationSlider->value());
1354 m_wdgLayerBox->listLayers->slotConfigurationChanged();
1355}

References indentationSlider, KisConfig::layerTreeIndentation(), m_wdgLayerBox, and KisConfig::setLayerTreeIndentation().

◆ slotUpdateUseInlineLayerInfoText

void LayerBox::slotUpdateUseInlineLayerInfoText ( )
privateslot

Definition at line 1387 of file LayerBox.cpp.

1388{
1389 KisConfig cfg(false);
1390 if (infoTextInlineChkbox->isChecked() == cfg.useInlineLayerInfoText()) {
1391 return;
1392 }
1393 cfg.setUseInlineLayerInfoText(infoTextInlineChkbox->isChecked());
1394 m_wdgLayerBox->listLayers->slotConfigurationChanged();
1395 m_wdgLayerBox->listLayers->viewport()->update();
1396}

References infoTextInlineChkbox, m_wdgLayerBox, KisConfig::setUseInlineLayerInfoText(), and KisConfig::useInlineLayerInfoText().

◆ slotUpdateUseLayerSelectionCheckbox

void LayerBox::slotUpdateUseLayerSelectionCheckbox ( )
privateslot

Definition at line 1399 of file LayerBox.cpp.

1400{
1401 KisConfig cfg(false);
1402 if (layerSelectionCheckBox->isChecked() == cfg.useLayerSelectionCheckbox()) {
1403 return;
1404 }
1405 cfg.setUseLayerSelectionCheckbox(layerSelectionCheckBox->isChecked());
1406 m_wdgLayerBox->listLayers->slotConfigurationChanged();
1407 m_wdgLayerBox->listLayers->viewport()->update();
1408}

References layerSelectionCheckBox, m_wdgLayerBox, KisConfig::setUseLayerSelectionCheckbox(), and KisConfig::useLayerSelectionCheckbox().

◆ toggleActiveLayerSolo

void LayerBox::toggleActiveLayerSolo ( )
privateslot

Definition at line 1317 of file LayerBox.cpp.

1317 {
1318 NodeView* view = m_wdgLayerBox->listLayers;
1319 if (!view)
1320 return;
1321
1322 KisNodeSP node = m_nodeManager->activeNode();
1323 if (!node)
1324 return;
1325
1326 QModelIndex index = m_filteringModel->indexFromNode(node);
1327 if (!index.isValid())
1328 return;
1329
1330 view->toggleSolo(index);
1331}
void toggleSolo(const QModelIndex &index)
Definition NodeView.cpp:158

References m_filteringModel, m_nodeManager, m_wdgLayerBox, and NodeView::toggleSolo().

◆ unsetCanvas()

void LayerBox::unsetCanvas ( )
overridevirtual

Re-implement to notify the observer that its canvas is no longer among the living. The daisies, it is pushing up. This means you don't have to disconnect, it's dead.

The old canvas should be deleted already, so if you stored a pointer to it, don't touch!

Note that currently there is a bug where in certain specific circumstances unsetCanvas can be called when it shouldn't, see for example KWStatisticsDocker for a workaround for this problem.

Implements KoCanvasObserverBase.

Definition at line 640 of file LayerBox.cpp.

641{
642 setEnabled(false);
643 if (m_canvas) {
644 m_newLayerMenu->clear();
645 }
646
647 m_filteringModel->unsetDummiesFacade();
648 disconnect(m_image, 0, this, 0);
649 disconnect(m_nodeManager, 0, this, 0);
650 disconnect(m_nodeModel, 0, m_nodeManager, 0);
651 m_nodeManager->slotSetSelectedNodes(KisNodeList());
652
653 m_canvas = 0;
654}

References m_canvas, m_filteringModel, m_image, m_newLayerMenu, m_nodeManager, and m_nodeModel.

◆ updateAvailableLabels

void LayerBox::updateAvailableLabels ( )
privateslot

Definition at line 1165 of file LayerBox.cpp.

1166{
1167 if (!m_image) return;
1169}
void updateColorLabels(KisNodeSP root)

References layerFilterWidget, m_image, KisNodeFacade::root, and KisLayerFilterWidget::updateColorLabels().

◆ updateLayerFiltering

void LayerBox::updateLayerFiltering ( )
privateslot

◆ updateLayerOpMenu

void LayerBox::updateLayerOpMenu ( const QModelIndex & index,
QMenu & menu )
privateslot

Definition at line 1183 of file LayerBox.cpp.

1183 {
1184
1185 KisNodeList nodes = m_nodeManager->selectedNodes();
1186 KisNodeSP activeNode = m_nodeManager->activeNode();
1187 const bool singleNode = nodes.size() == 1;
1188
1189 if (index.isValid()) {
1190 menu.addAction(m_propertiesAction);
1191
1192 KisLayerSP singleLayer = dynamic_cast<KisLayer*>(activeNode.data());
1193
1194 if (singleLayer) {
1195 addActionToMenu(&menu, "layer_style");
1196
1197 if (singleLayer->layerStyle()) {
1198 addActionToMenu(&menu, "copy_layer_style");
1199 }
1200
1201 if (KisClipboard::instance()->hasLayerStyles()) {
1202 addActionToMenu(&menu, "paste_layer_style");
1203 }
1204 }
1205
1206 Q_FOREACH(KisNodeSP node, nodes) {
1207 if (node && node->inherits("KisCloneLayer")) {
1208 menu.addAction(m_changeCloneSourceAction);
1209 break;
1210 }
1211 }
1212
1213 {
1214 KisSignalsBlocker b(m_colorSelector->colorLabelSelector());
1215 m_colorSelector->colorLabelSelector()->setCurrentIndex(singleNode ? activeNode->colorLabelIndex() : -1);
1216 }
1217
1218 menu.addAction(m_colorSelectorAction);
1219
1220 menu.addSeparator();
1221
1222 addActionToMenu(&menu, "cut_layer_clipboard");
1223 addActionToMenu(&menu, "copy_layer_clipboard");
1224 addActionToMenu(&menu, "paste_layer_from_clipboard");
1225 menu.addAction(m_removeAction);
1226 addActionToMenu(&menu, "duplicatelayer");
1227 addActionToMenu(&menu, "merge_layer");
1228 addActionToMenu(&menu, "new_from_visible");
1229
1230 if (singleNode) {
1231 addActionToMenu(&menu, "flatten_image");
1232 addActionToMenu(&menu, "flatten_layer");
1233 }
1234
1235 menu.addSeparator();
1236 QMenu *selectMenu = menu.addMenu(i18n("&Select"));
1237 addActionToMenu(selectMenu, "select_all_layers");
1238 addActionToMenu(selectMenu, "select_visible_layers");
1239 addActionToMenu(selectMenu, "select_invisible_layers");
1240 addActionToMenu(selectMenu, "select_locked_layers");
1241 addActionToMenu(selectMenu, "select_unlocked_layers");
1242 QMenu *groupMenu = menu.addMenu(i18nc("A group of layers", "&Group"));
1243 addActionToMenu(groupMenu, "create_quick_group");
1244 addActionToMenu(groupMenu, "create_quick_clipping_group");
1245 addActionToMenu(groupMenu, "quick_ungroup");
1246 QMenu *locksMenu = menu.addMenu(i18n("&Toggle Locks && Visibility"));
1247 addActionToMenu(locksMenu, "toggle_layer_visibility");
1248 addActionToMenu(locksMenu, "toggle_layer_lock");
1249 addActionToMenu(locksMenu, "toggle_layer_inherit_alpha");
1250 addActionToMenu(locksMenu, "toggle_layer_alpha_lock");
1251
1252 if (singleNode) {
1253 QMenu *addLayerMenu = menu.addMenu(i18n("&Add"));
1254 addActionToMenu(addLayerMenu, "add_new_transparency_mask");
1255 addActionToMenu(addLayerMenu, "add_new_filter_mask");
1256 addActionToMenu(addLayerMenu, "add_new_fast_color_overlay_mask");
1257 addActionToMenu(addLayerMenu, "add_new_colorize_mask");
1258 addActionToMenu(addLayerMenu, "add_new_transform_mask");
1259 addActionToMenu(addLayerMenu, "add_new_selection_mask");
1260 addLayerMenu->addSeparator();
1261 addActionToMenu(addLayerMenu, "add_new_clone_layer");
1262
1263 QMenu *convertToMenu = menu.addMenu(i18n("&Convert"));
1264 addActionToMenu(convertToMenu, "convert_to_paint_layer");
1265 addActionToMenu(convertToMenu, "convert_to_transparency_mask");
1266 addActionToMenu(convertToMenu, "convert_to_filter_mask");
1267 addActionToMenu(convertToMenu, "convert_to_selection_mask");
1268 addActionToMenu(convertToMenu, "convert_to_file_layer");
1269 addActionToMenu(convertToMenu, "convert_group_to_animated");
1270 addActionToMenu(convertToMenu, "layercolorspaceconversion");
1271
1272 QMenu *splitAlphaMenu = menu.addMenu(i18n("S&plit Alpha"));
1273 addActionToMenu(splitAlphaMenu, "split_alpha_into_mask");
1274 addActionToMenu(splitAlphaMenu, "split_alpha_write");
1275 addActionToMenu(splitAlphaMenu, "split_alpha_save_merged");
1276 } else {
1277 QMenu *addLayerMenu = menu.addMenu(i18n("&Add"));
1278 addActionToMenu(addLayerMenu, "add_new_clone_layer");
1279 }
1280
1281 menu.addSeparator();
1282
1283 addActionToMenu(&menu, "pin_to_timeline");
1284
1285
1286 if (singleNode) {
1287 KisNodeSP node = m_filteringModel->nodeFromIndex(index);
1288 if (node && !node->inherits("KisTransformMask")) {
1289 addActionToMenu(&menu, "isolate_active_layer");
1290 addActionToMenu(&menu, "isolate_active_group");
1291 }
1292
1293 addActionToMenu(&menu, "selectopaque");
1294
1295 }
1296 }
1297}
static KisClipboard * instance()
int colorLabelIndex() const
KisPSDLayerStyleSP layerStyle
Definition kis_layer.cc:171

References addActionToMenu(), KisBaseNode::colorLabelIndex(), KisSharedPtr< T >::data(), KisClipboard::instance(), KisLayer::layerStyle, m_changeCloneSourceAction, m_colorSelector, m_colorSelectorAction, m_filteringModel, m_nodeManager, m_propertiesAction, and m_removeAction.

◆ updateUI

void LayerBox::updateUI ( )
privateslot

the composite op works in the color space of the parent layer, not the active one.

Definition at line 676 of file LayerBox.cpp.

677{
678 if (!m_canvas) return;
679 if (!m_nodeManager) return;
680
681 KisNodeSP activeNode = m_nodeManager->activeNode();
682
683 if (activeNode != m_activeNode) {
685 m_activeNode = activeNode;
686
687 if (activeNode) {
688 KisPaintDeviceSP parentLayerDevice = activeNode->parent() ? activeNode->parent()->original() : 0;
689 if (parentLayerDevice) {
690 // update blending modes availability
692 parentLayerDevice, SIGNAL(colorSpaceChanged(const KoColorSpace*)),
693 this, SLOT(updateUI()));
694 }
695
697 activeNode, SIGNAL(opacityChanged(quint8)),
698 this, SLOT(slotUpdateOpacitySlider(quint8)));
699 }
700 }
701
702 m_wdgLayerBox->bnRaise->setEnabled(activeNode && activeNode->isEditable(false) && (activeNode->nextSibling()
703 || (activeNode->parent() && activeNode->parent() != m_image->root())));
704 m_wdgLayerBox->bnLower->setEnabled(activeNode && activeNode->isEditable(false) && (activeNode->prevSibling()
705 || (activeNode->parent() && activeNode->parent() != m_image->root())));
706
707 m_wdgLayerBox->doubleOpacity->setEnabled(activeNode && activeNode->isEditable(false));
708
709 m_wdgLayerBox->cmbComposite->setEnabled(activeNode && activeNode->isEditable(false));
710
711 if (activeNode) {
712 if (activeNode->inherits("KisColorizeMask") || activeNode->inherits("KisLayer")) {
713
714 m_wdgLayerBox->doubleOpacity->setEnabled(true);
715
716 if (!m_wdgLayerBox->doubleOpacity->isDragging()) {
717 slotSetOpacity(activeNode->opacity() * 100.0 / 255);
718 }
719
720 const KoCompositeOp* compositeOp = activeNode->compositeOp();
721 if (compositeOp) {
724 m_wdgLayerBox->cmbComposite->validate(compositeOp->colorSpace());
725 slotSetCompositeOp(compositeOp);
726 } else {
727 m_wdgLayerBox->cmbComposite->setEnabled(false);
728 }
729
730 const KisGroupLayer *group = qobject_cast<const KisGroupLayer*>(activeNode.data());
731 bool compositeSelectionActive = !(group && group->passThroughMode());
732
733 m_wdgLayerBox->cmbComposite->setEnabled(compositeSelectionActive);
734 } else if (activeNode->inherits("KisMask")) {
735 m_wdgLayerBox->cmbComposite->setEnabled(false);
736 m_wdgLayerBox->doubleOpacity->setEnabled(false);
737 }
738 }
739}
void addConnection(Sender sender, Signal signal, Receiver receiver, Method method, Qt::ConnectionType type=Qt::AutoConnection)
void slotUpdateOpacitySlider(quint8 value)
Definition LayerBox.cpp:805
void slotSetCompositeOp(const KoCompositeOp *compositeOp)
Definition LayerBox.cpp:787
KisSignalAutoConnectionsStore m_activeNodeConnections
Definition LayerBox.h:190
void slotSetOpacity(double opacity)
Definition LayerBox.cpp:797
bool isEditable(bool checkVisibility=true) const
virtual KisPaintDeviceSP original() const =0
QString compositeOp
quint8 opacity() const
const KoColorSpace * colorSpace

References KisSignalAutoConnectionsStore::addConnection(), KisSignalAutoConnectionsStore::clear(), KoCompositeOp::colorSpace, KisBaseNode::compositeOp, KisSharedPtr< T >::data(), KisBaseNode::isEditable(), m_activeNode, m_activeNodeConnections, m_canvas, m_image, m_nodeManager, m_wdgLayerBox, KisNode::nextSibling(), KisBaseNode::opacity(), KisBaseNode::original(), KisNode::parent, KisGroupLayer::passThroughMode, KisNode::prevSibling(), KisNodeFacade::root, slotSetCompositeOp(), slotSetOpacity(), slotUpdateOpacitySlider(), and updateUI().

Member Data Documentation

◆ indentationSlider

QSlider* LayerBox::indentationSlider
private

Definition at line 182 of file LayerBox.h.

◆ infoTextCombobox

QComboBox* LayerBox::infoTextCombobox
private

Definition at line 183 of file LayerBox.h.

◆ infoTextInlineChkbox

QCheckBox* LayerBox::infoTextInlineChkbox
private

Definition at line 185 of file LayerBox.h.

◆ infoTextOpacitySlider

KisSliderSpinBox* LayerBox::infoTextOpacitySlider
private

Definition at line 184 of file LayerBox.h.

◆ layerFilterWidget

KisLayerFilterWidget* LayerBox::layerFilterWidget
private

Definition at line 180 of file LayerBox.h.

◆ layerSelectionCheckBox

QCheckBox* LayerBox::layerSelectionCheckBox {nullptr}
private

Definition at line 186 of file LayerBox.h.

186{nullptr};

◆ m_activeNode

KisNodeSP LayerBox::m_activeNode
private

Definition at line 188 of file LayerBox.h.

◆ m_activeNodeConnections

KisSignalAutoConnectionsStore LayerBox::m_activeNodeConnections
private

Definition at line 190 of file LayerBox.h.

◆ m_canvas

QPointer<KisCanvas2> LayerBox::m_canvas
private

Definition at line 155 of file LayerBox.h.

◆ m_changeCloneSourceAction

KisAction* LayerBox::m_changeCloneSourceAction
private

Definition at line 171 of file LayerBox.h.

◆ m_changedOpacityNode

KisNodeSP LayerBox::m_changedOpacityNode
private

Definition at line 167 of file LayerBox.h.

◆ m_colorLabelCompressor

KisSignalCompressor LayerBox::m_colorLabelCompressor
private

Definition at line 174 of file LayerBox.h.

◆ m_colorSelector

QPointer<KisColorLabelSelectorWidgetMenuWrapper> LayerBox::m_colorSelector
private

Definition at line 163 of file LayerBox.h.

◆ m_colorSelectorAction

QPointer<QWidgetAction> LayerBox::m_colorSelectorAction
private

Definition at line 164 of file LayerBox.h.

◆ m_filteringModel

QPointer<KisNodeFilterProxyModel> LayerBox::m_filteringModel
private

Definition at line 161 of file LayerBox.h.

◆ m_image

KisImageWSP LayerBox::m_image
private

Definition at line 159 of file LayerBox.h.

◆ m_infoTextOpacityCompressor

KisSignalCompressor LayerBox::m_infoTextOpacityCompressor
private

Definition at line 177 of file LayerBox.h.

◆ m_layerToggleSolo

KisAction* LayerBox::m_layerToggleSolo
private

Definition at line 172 of file LayerBox.h.

◆ m_newLayerMenu

QMenu* LayerBox::m_newLayerMenu
private

Definition at line 157 of file LayerBox.h.

◆ m_newOpacity

int LayerBox::m_newOpacity
private

Definition at line 166 of file LayerBox.h.

◆ m_nodeManager

QPointer<KisNodeManager> LayerBox::m_nodeManager
private

Definition at line 162 of file LayerBox.h.

◆ m_nodeModel

QPointer<KisNodeModel> LayerBox::m_nodeModel
private

Definition at line 160 of file LayerBox.h.

◆ m_nodeOpacityCompressor

KisSignalCompressor LayerBox::m_nodeOpacityCompressor
private

Definition at line 178 of file LayerBox.h.

◆ m_opLayerMenu

QMenu* LayerBox::m_opLayerMenu
private

Definition at line 158 of file LayerBox.h.

◆ m_propertiesAction

KisAction* LayerBox::m_propertiesAction
private

Definition at line 170 of file LayerBox.h.

◆ m_removeAction

KisAction* LayerBox::m_removeAction
private

Definition at line 169 of file LayerBox.h.

◆ m_savedNodeBeforeEditSelectionMode

KisNodeWSP LayerBox::m_savedNodeBeforeEditSelectionMode
private

Definition at line 189 of file LayerBox.h.

◆ m_screenMigrationTracker

QScopedPointer<KisScreenMigrationTracker> LayerBox::m_screenMigrationTracker
private

Definition at line 191 of file LayerBox.h.

◆ m_selectionActionsAdapter

QScopedPointer<KisSelectionActionsAdapter> LayerBox::m_selectionActionsAdapter
private

Definition at line 156 of file LayerBox.h.

◆ m_showGlobalSelectionMask

KisAction* LayerBox::m_showGlobalSelectionMask
private

Definition at line 173 of file LayerBox.h.

◆ m_thumbnailSizeCompressor

KisSignalCompressor LayerBox::m_thumbnailSizeCompressor
private

Definition at line 175 of file LayerBox.h.

◆ m_treeIndentationCompressor

KisSignalCompressor LayerBox::m_treeIndentationCompressor
private

Definition at line 176 of file LayerBox.h.

◆ m_wdgLayerBox

Ui_WdgLayerBox* LayerBox::m_wdgLayerBox
private

Definition at line 165 of file LayerBox.h.

◆ thumbnailSizeSlider

QSlider* LayerBox::thumbnailSizeSlider
private

Definition at line 181 of file LayerBox.h.


The documentation for this class was generated from the following files: