15#include <QApplication>
32#include <QWidgetAction>
34#include <QStyleFactory>
37#include <klocalizedstring.h>
90#include "ui_WdgLayerBox.h"
101 const QStyleOption *option,
103 const QWidget *widget)
const override
105 if (element == QStyle::PE_IndicatorItemViewItemDrop)
107 QColor color(widget->palette().color(QPalette::Highlight).lighter());
109 if (option->rect.height() == 0) {
112 QRect r(option->rect);
113 r.setTop(r.top() - 2);
114 r.setBottom(r.bottom() + 2);
116 painter->fillRect(r, brush);
120 painter->fillRect(option->rect, brush);
125 QProxyStyle::drawPrimitive(element, option, painter, widget);
132 if (!viewManager || !
button)
return;
138 connect(
button, SIGNAL(clicked()), action, SLOT(trigger()));
139 connect(action, SIGNAL(sigEnableSlaves(
bool)),
button, SLOT(setEnabled(
bool)));
146 menu->addAction(
m_canvas->viewManager()->actionManager()->actionByName(
id));
157 return qMin(255,
int(opacity * 2.55 + 0.5));
161 : QDockWidget(i18n(
"Layers"))
163 , m_wdgLayerBox(new Ui_WdgLayerBox)
172 QWidget* mainWidget =
new QWidget(
this);
173 setWidget(mainWidget);
177 QStyle *newStyle = QStyleFactory::create(
m_wdgLayerBox->listLayers->style()->objectName());
185 SIGNAL(contextMenuRequested(QPoint,QModelIndex)),
188 SIGNAL(collapsed(QModelIndex)), SLOT(
slotCollapsed(QModelIndex)));
190 SIGNAL(expanded(QModelIndex)), SLOT(
slotExpanded(QModelIndex)));
210 i18nc(
"{n} is the number value, % is the percent sign",
"Opacity: {n}%"));
213 i18nc(
"{n} is the number value, % is the percent sign",
"{n}%"));
223 m_wdgLayerBox->bnAdd->setPopupMode(QToolButton::MenuButtonPopup);
227 m_wdgLayerBox->bnProperties->setPopupMode(QToolButton::MenuButtonPopup);
241 connect(
m_nodeModel, SIGNAL(rowsMoved(QModelIndex,
int,
int,QModelIndex,
int)), SLOT(
updateUI()));
257 m_showGlobalSelectionMask->setToolTip(i18nc(
"@info:tooltip",
"Shows global selection as a usual selection mask in <b>Layers</b> docker"));
270 connect(
m_nodeModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
281 QMenu *layerFilterMenu =
new QMenu(
this);
283 m_wdgLayerBox->bnLayerFilters->setPopupMode(QToolButton::InstantPopup);
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);
298 m_wdgLayerBox->bnLayerFilters->setIcon(filterEnabledIcon);
300 m_wdgLayerBox->bnLayerFilters->setIcon(filterIcon);
304 m_wdgLayerBox->bnLayerFilters->setSelectedColors(
QList(activeColors.begin(), activeColors.end()));
308 QWidgetAction *layerFilterMenuAction =
new QWidgetAction(
this);
310 layerFilterMenu->addAction(layerFilterMenuAction);
314 menuStyle->setParent(layerFilterMenu);
315 layerFilterMenu->setStyle(menuStyle);
323 QMenu* configureMenu =
new QMenu(
this);
324 configureMenu->setContentsMargins(6, 6, 6, 6);
325 configureMenu->addSection(i18n(
"Thumbnail Size"));
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);
345 QWidgetAction *sliderAction=
new QWidgetAction(
this);
347 configureMenu->addAction(sliderAction);
353 configureMenu->addSection(i18nc(
"@item:inmenu Layers Docker settings, slider",
"Tree Indentation"));
364 sliderAction=
new QWidgetAction(
this);
366 configureMenu->addAction(sliderAction);
376 configureMenu->addSection(i18nc(
"@item:inmenu Layers Docker settings, combobox",
"Blending Info Style"));
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."));
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"),
390 QWidgetAction *cmbboxAction =
new QWidgetAction(
this);
392 configureMenu->addAction(cmbboxAction);
398 i18nc(
"{n} is the number value, % is the percent sign",
"Opacity: {n}%"));
410 sliderAction=
new QWidgetAction(
this);
412 configureMenu->addAction(sliderAction);
417 infoTextInlineChkbox =
new QCheckBox(i18nc(
"@item:inmenu Layers Docker settings, checkbox",
"Inline"),
this);
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)."));
425 QWidgetAction *chkboxAction =
new QWidgetAction(
this);
427 configureMenu->addAction(chkboxAction);
431 i18nc(
"@item:inmenu Layers Docker settings, checkbox",
"Checkbox for Selecting Layers"),
this);
435 QWidgetAction *layerSelectionAction =
new QWidgetAction(
this);
437 configureMenu->addAction(layerSelectionAction);
454 if (filteringModel.isNull())
return;
455 if (!nodeView)
return;
457 nodeView->blockSignals(
true);
461 QModelIndex idx = filteringModel->indexFromNode(node);
463 nodeView->setExpanded(idx, !node->
collapsed());
470 nodeView->blockSignals(
false);
478 if (nodes.size() == 1) {
479 KisAction *action =
m_canvas->viewManager()->actionManager()->actionByName(
"add_new_paint_layer");
482 KisAction *action =
m_canvas->viewManager()->actionManager()->actionByName(
"create_quick_group");
531 action = actionManager->
createAction(
"move_layer_down");
550 setEnabled(canvas != 0);
553 m_canvas->disconnectCanvasObserver(
this);
560 animation->disconnect(
this);
563 disconnect(
m_image, 0,
this, 0);
585 kritaShapeController,
612 connect(
m_nodeModel, SIGNAL(toggleIsolateActiveNode()),
648 disconnect(
m_image, 0,
this, 0);
658 QDockWidget::showEvent(event);
667 QDockWidget::hideEvent(event);
689 if (parentLayerDevice) {
692 parentLayerDevice, SIGNAL(colorSpaceChanged(
const KoColorSpace*)),
697 activeNode, SIGNAL(opacityChanged(quint8)),
712 if (activeNode->inherits(
"KisColorizeMask") || activeNode->inherits(
"KisLayer")) {
730 const KisGroupLayer *group = qobject_cast<const KisGroupLayer*>(activeNode.
data());
733 m_wdgLayerBox->cmbComposite->setEnabled(compositeSelectionActive);
734 }
else if (activeNode->inherits(
"KisMask")) {
764 QModelIndex index = node ?
m_filteringModel->indexFromNode(node) : QModelIndex();
772 QItemSelection selection;
776 QItemSelectionRange selectionRange(idx);
777 selection << selectionRange;
781 m_wdgLayerBox->listLayers->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect);
799 Q_ASSERT(opacity >= 0 && opacity <= 100);
806 double percentage =
value * 100.0 / 255.0;
817 if (nodes.isEmpty() || !activeNode)
return;
875 QString compositeOp =
m_wdgLayerBox->cmbComposite->selectedCompositeOp().id();
911 QAction *action =
m_canvas->viewManager()->actionManager()->actionByName(
"selectopaque");
968 if (!showSelections) {
975 m_nodeModel->setShowGlobalSelection(showSelections);
980 if (!globalSelectionMask) {
984 if (!masks.isEmpty()) {
985 globalSelectionMask =
dynamic_cast<KisSelectionMask*
>(masks.first().data());
990 if (!globalSelectionMask) {
993 if (!masks.isEmpty()) {
994 globalSelectionMask =
dynamic_cast<KisSelectionMask*
>(masks.first().data());
998 if (globalSelectionMask) {
999 if (showSelections) {
1000 activateNode = globalSelectionMask;
1004 if (activateNode != lastActiveNode) {
1006 }
else if (lastActiveNode) {
1010 if (showSelections && !globalSelectionMask) {
1019 lastActiveNode, 0,
m_image,
false),
1029 }
else if (!showSelections &&
1030 globalSelectionMask &&
1041 if (showSelections) {
1056 QModelIndex selectedIndex =
1060 setCurrentIndex(selectedIndex, QItemSelectionModel::ClearAndSelect);
1065 Q_FOREACH (
const QModelIndex &idx, selection) {
1068 if (idx.column() != 0) {
1093 QModelIndex currentIndex =
m_wdgLayerBox->listLayers->currentIndex();
1096 if (currentIndex.isValid() && parent == currentIndex.parent()
1097 && currentIndex.row() >= start && currentIndex.row() <= end) {
1098 QModelIndex old = currentIndex;
1100 if (model && end < model->rowCount(parent) - 1)
1101 currentIndex = model->index(end + 1, old.column(), parent);
1102 else if (model && start > 0)
1103 currentIndex = model->index(start - 1, old.column(), parent);
1105 currentIndex = QModelIndex();
1107 if (currentIndex.isValid() && currentIndex != old) {
1122 QItemSelectionModel *model =
m_wdgLayerBox->listLayers->selectionModel();
1128 QItemSelection selection;
1129 Q_FOREACH(
const QModelIndex &idx, newSelection) {
1130 selection.select(idx, idx);
1133 model->select(selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
1145 Q_FOREACH(
KisNodeSP selectedNode, selectedNodes) {
1152 auto applyLabelFunc =
1154 if (child->colorLabelIndex() == 0) {
1155 child->setColorLabelIndex(label);
1187 const bool singleNode = nodes.size() == 1;
1189 if (index.isValid()) {
1207 if (node && node->inherits(
"KisCloneLayer")) {
1220 menu.addSeparator();
1235 menu.addSeparator();
1236 QMenu *selectMenu = menu.addMenu(i18n(
"&Select"));
1242 QMenu *groupMenu = menu.addMenu(i18nc(
"A group of layers",
"&Group"));
1246 QMenu *locksMenu = menu.addMenu(i18n(
"&Toggle Locks && Visibility"));
1253 QMenu *addLayerMenu = menu.addMenu(i18n(
"&Add"));
1260 addLayerMenu->addSeparator();
1263 QMenu *convertToMenu = menu.addMenu(i18n(
"&Convert"));
1272 QMenu *splitAlphaMenu = menu.addMenu(i18n(
"S&plit Alpha"));
1277 QMenu *addLayerMenu = menu.addMenu(i18n(
"&Add"));
1281 menu.addSeparator();
1288 if (node && !node->inherits(
"KisTransformMask")) {
1327 if (!index.isValid())
1410#include "moc_LayerBox.cpp"
float value(const T *src, size_t ch)
QVector< KisImageSignalType > KisImageSignalVector
QList< QString > QStringList
bool isSelectionMask(KisNodeSP node)
void expandNodesRecursively(KisNodeSP root, QPointer< KisNodeFilterProxyModel > filteringModel, NodeView *nodeView)
A KisActionManager class keeps track of KisActions. These actions are always associated with the GUI....
KisAction * createAction(const QString &name)
KisAction * actionByName(const QString &name) const
void setActivationFlags(ActivationFlags flags)
@ ACTIVE_IMAGE
Activate if there is at least one image.
static KisClipboard * instance()
LayerInfoTextStyle layerInfoTextStyle(bool defaultValue=false) const
bool showGlobalSelection(bool defaultValue=false) const
bool useInlineLayerInfoText(bool defaultValue=false) const
void setUseInlineLayerInfoText(bool value)
int layerThumbnailSize(bool defaultValue=false) const
void setUseLayerSelectionCheckbox(bool value)
bool useLayerSelectionCheckbox(bool defaultValue=false) const
bool sliderLabels(bool defaultValue=false) const
int layerTreeIndentation(bool defaultValue=false) const
void setLayerThumbnailSize(int size)
void setLayerInfoTextOpacity(int value)
void setLayerInfoTextStyle(LayerInfoTextStyle value)
void setLayerTreeIndentation(int percentage)
int layerInfoTextOpacity(bool defaultValue=false) const
KisShapeController * shapeController
void sigUiTimeChanged(int newTime)
KisGroupLayerSP rootLayer() const
KisImageAnimationInterface * animationInterface() const
void sigBeforeBeginRemoveRows(const QModelIndex &parent, int start, int end)
static bool isNodeHidden(KisNodeSP node, bool isGlobalSelectionHidden)
@ ActiveRole
Whether the section is the active one.
void applyCommand(KUndo2Command *command, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
void sigScreenOrResolutionChanged(QScreen *screen)
void addConnection(Sender sender, Signal signal, Receiver receiver, Method method, Qt::ConnectionType type=Qt::AutoConnection)
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.
KisActionManager * actionManager() const
KisNodeManager * nodeManager() const
The node manager handles everything about nodes.
QWidget * mainWindowAsQWidget() const
static const KoCompositeOpRegistry & instance()
KoID getKoID(const QString &compositeOpID) const
void setProperty(const QString &name, const QVariant &value)
LayerBoxStyle(QStyle *baseStyle=0)
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override
void slotForgetAboutSavedNodeBeforeEditSelectionMode()
QComboBox * infoTextCombobox
void showEvent(QShowEvent *event) override
void slotUpdateOpacitySlider(quint8 value)
void slotImageTimeChanged(int time)
void updateAvailableLabels()
qint32 convertOpacityToInt(qreal opacity)
void addActionToMenu(QMenu *menu, const QString &id)
KisAction * m_changeCloneSourceAction
void slotOpacitySliderMoved(qreal opacity)
void slotCollapsed(const QModelIndex &index)
void slotCompositeOpChanged(int index)
KisSignalCompressor m_colorLabelCompressor
void slotContextMenuRequested(const QPoint &pos, const QModelIndex &index)
KisLayerFilterWidget * layerFilterWidget
void slotSyncThumbnailIconSize()
void connectActionToButton(KisViewManager *view, QAbstractButton *button, const QString &id)
void selectionChanged(const QModelIndexList &selection)
KisNodeSP m_changedOpacityNode
void slotUpdateThumbnailIconSize()
QSlider * thumbnailSizeSlider
KisSignalCompressor m_thumbnailSizeCompressor
void toggleActiveLayerSolo()
QCheckBox * infoTextInlineChkbox
KisAction * m_layerToggleSolo
void slotLayerOpMenuOpened()
void slotUpdateLayerInfoTextStyle()
void slotSetCompositeOp(const KoCompositeOp *compositeOp)
KisAction * m_propertiesAction
void slotUpdateUseInlineLayerInfoText()
QScopedPointer< KisScreenMigrationTracker > m_screenMigrationTracker
void hideEvent(QHideEvent *event) override
QSlider * indentationSlider
void slotAddLayerBnClicked()
KisSignalAutoConnectionsStore m_activeNodeConnections
void slotNodeManagerChangedSelection(const QList< KisNodeSP > &nodes)
void slotPropertiesClicked()
void slotRenameCurrentNode()
void slotEditGlobalSelection(bool showSelections)
void slotExpanded(const QModelIndex &index)
KisSignalCompressor m_infoTextOpacityCompressor
void unsetCanvas() override
KisAction * m_showGlobalSelectionMask
KisSignalCompressor m_nodeOpacityCompressor
void setViewManager(KisViewManager *kisview) override
reimplemented from KisMainwindowObserver
void slotChangeCloneSourceClicked()
void updateLayerFiltering()
void slotOpacityChanged()
QPointer< KisNodeManager > m_nodeManager
QScopedPointer< KisSelectionActionsAdapter > m_selectionActionsAdapter
KisNodeSP findNonHidableNode(KisNodeSP startNode)
KisSliderSpinBox * infoTextOpacitySlider
Ui_WdgLayerBox * m_wdgLayerBox
void updateLayerOpMenu(const QModelIndex &index, QMenu &menu)
QPointer< KisNodeFilterProxyModel > m_filteringModel
void slotUpdateTreeIndentation()
QPointer< QWidgetAction > m_colorSelectorAction
QPointer< KisColorLabelSelectorWidgetMenuWrapper > m_colorSelector
void slotUpdateUseLayerSelectionCheckbox()
KisAction * m_removeAction
void slotUpdateLayerInfoTextOpacity()
void slotColorLabelChanged(int index)
void slotSetOpacity(double opacity)
void setCurrentNode(KisNodeSP node)
void setCanvas(KoCanvasBase *canvas) override
void notifyImageDeleted()
void slotNodeCollapsedChanged()
QPointer< KisNodeModel > m_nodeModel
KisNodeWSP m_savedNodeBeforeEditSelectionMode
void slotAdjustCurrentBeforeRemoveRows(const QModelIndex &parent, int first, int last)
QCheckBox * layerSelectionCheckBox
QPointer< KisCanvas2 > m_canvas
KisSignalCompressor m_treeIndentationCompressor
void slotLayerOpMenuClosed()
void toggleSolo(const QModelIndex &index)
#define KIS_ASSERT_RECOVER_NOOP(cond)
QString button(const QWheelEvent &ev)
QList< KisNodeSP > KisNodeList
KisSharedPtr< KisNode > KisNodeSP
KUndo2MagicString kundo2_i18n(const char *text)
QIcon loadIcon(const QString &name)
void recursiveApplyNodes(NodePointer node, Functor func)
void setText(QSpinBox *spinBox, const QStringView textTemplate)
bool compareListsUnordered(const QList< T > &a, const QList< T > &b)
bool isEditable(bool checkVisibility=true) const
virtual KisPaintDeviceSP original() const =0
void setColorLabelIndex(int index)
void setCollapsed(bool collapsed)
int colorLabelIndex() const
virtual KisSelectionMaskSP selectionMask() const
KisPSDLayerStyleSP layerStyle
KisNodeSP prevSibling() const
KisNodeSP firstChild() const
QList< KisNodeSP > childNodes(const QStringList &nodeTypes, const KoProperties &properties) const
quint32 childCount() const
KisNodeSP lastChild() const
KisNodeSP nextSibling() const
KisNodeGraphListener * graphListener
QRect selectedRect() const
const KoColorSpace * colorSpace