15#include <QApplication>
32#include <QWidgetAction>
34#include <QStyleFactory>
37#include <klocalizedstring.h>
88#include "ui_WdgLayerBox.h"
99 const QStyleOption *option,
101 const QWidget *widget)
const override
103 if (element == QStyle::PE_IndicatorItemViewItemDrop)
105 QColor color(widget->palette().color(QPalette::Highlight).lighter());
107 if (option->rect.height() == 0) {
110 QRect r(option->rect);
111 r.setTop(r.top() - 2);
112 r.setBottom(r.bottom() + 2);
114 painter->fillRect(r, brush);
118 painter->fillRect(option->rect, brush);
123 QProxyStyle::drawPrimitive(element, option, painter, widget);
130 if (!viewManager || !
button)
return;
137 connect(action, SIGNAL(sigEnableSlaves(
bool)),
button, SLOT(setEnabled(
bool)));
144 menu->addAction(
m_canvas->viewManager()->actionManager()->actionByName(
id));
155 return qMin(255,
int(opacity * 2.55 + 0.5));
159 : QDockWidget(i18n(
"Layers"))
161 , m_wdgLayerBox(new Ui_WdgLayerBox)
170 QWidget* mainWidget =
new QWidget(
this);
171 setWidget(mainWidget);
175 QStyle *newStyle = QStyleFactory::create(
m_wdgLayerBox->listLayers->style()->objectName());
183 SIGNAL(contextMenuRequested(QPoint,QModelIndex)),
186 SIGNAL(collapsed(QModelIndex)), SLOT(
slotCollapsed(QModelIndex)));
188 SIGNAL(expanded(QModelIndex)), SLOT(
slotExpanded(QModelIndex)));
208 i18nc(
"{n} is the number value, % is the percent sign",
"Opacity: {n}%"));
211 i18nc(
"{n} is the number value, % is the percent sign",
"{n}%"));
221 m_wdgLayerBox->bnAdd->setPopupMode(QToolButton::MenuButtonPopup);
225 m_wdgLayerBox->bnProperties->setPopupMode(QToolButton::MenuButtonPopup);
255 m_showGlobalSelectionMask->setToolTip(i18nc(
"@info:tooltip",
"Shows global selection as a usual selection mask in <b>Layers</b> docker"));
279 QMenu *layerFilterMenu =
new QMenu(
this);
281 m_wdgLayerBox->bnLayerFilters->setPopupMode(QToolButton::InstantPopup);
286 QPixmap filterEnabledPixmap = filterIcon.pixmap(64,64);
287 const QBitmap filterEnabledBitmask = filterEnabledPixmap.mask();
288 filterEnabledPixmap.fill(
palette().color(QPalette::Highlight));
289 filterEnabledPixmap.setMask(filterEnabledBitmask);
290 const QIcon filterEnabledIcon = QIcon(filterEnabledPixmap);
296 m_wdgLayerBox->bnLayerFilters->setIcon(filterEnabledIcon);
298 m_wdgLayerBox->bnLayerFilters->setIcon(filterIcon);
302 m_wdgLayerBox->bnLayerFilters->setSelectedColors(
QList(activeColors.begin(), activeColors.end()));
306 QWidgetAction *layerFilterMenuAction =
new QWidgetAction(
this);
308 layerFilterMenu->addAction(layerFilterMenuAction);
312 menuStyle->setParent(layerFilterMenu);
313 layerFilterMenu->setStyle(menuStyle);
321 QMenu* configureMenu =
new QMenu(
this);
322 configureMenu->setContentsMargins(6, 6, 6, 6);
323 configureMenu->addSection(i18n(
"Thumbnail Size"));
325 m_wdgLayerBox->configureLayerDockerToolbar->setMenu(configureMenu);
326 m_wdgLayerBox->configureLayerDockerToolbar->setIconSize(QSize(16, 16));
327 m_wdgLayerBox->configureLayerDockerToolbar->setPopupMode(QToolButton::InstantPopup);
328 m_wdgLayerBox->configureLayerDockerToolbar->setAutoRaise(
true);
343 QWidgetAction *sliderAction=
new QWidgetAction(
this);
345 configureMenu->addAction(sliderAction);
351 configureMenu->addSection(i18nc(
"@item:inmenu Layers Docker settings, slider",
"Tree Indentation"));
362 sliderAction=
new QWidgetAction(
this);
364 configureMenu->addAction(sliderAction);
374 configureMenu->addSection(i18nc(
"@item:inmenu Layers Docker settings, combobox",
"Blending Info Style"));
377 "Simple: Show changed opacities or blending modes.\n"
378 "Balanced: Show both opacity and blending mode if either are changed.\n"
379 "Detailed: Show both opacity and blending mode even if unchanged."));
381 i18nc(
"@item:inlistbox Layer Docker blending info style",
"None"),
382 i18nc(
"@item:inlistbox Layer Docker blending info style",
"Simple"),
383 i18nc(
"@item:inlistbox Layer Docker blending info style",
"Balanced"),
384 i18nc(
"@item:inlistbox Layer Docker blending info style",
"Detailed"),
388 QWidgetAction *cmbboxAction =
new QWidgetAction(
this);
390 configureMenu->addAction(cmbboxAction);
396 i18nc(
"{n} is the number value, % is the percent sign",
"Opacity: {n}%"));
408 sliderAction=
new QWidgetAction(
this);
410 configureMenu->addAction(sliderAction);
415 infoTextInlineChkbox =
new QCheckBox(i18nc(
"@item:inmenu Layers Docker settings, checkbox",
"Inline"),
this);
417 infoTextInlineChkbox->setToolTip(i18nc(
"@item:tooltip",
"If enabled, show blending info beside layer names.\n"
418 "If disabled, show below layer names (when enough space)."));
423 QWidgetAction *chkboxAction =
new QWidgetAction(
this);
425 configureMenu->addAction(chkboxAction);
429 i18nc(
"@item:inmenu Layers Docker settings, checkbox",
"Checkbox for Selecting Layers"),
this);
433 QWidgetAction *layerSelectionAction =
new QWidgetAction(
this);
435 configureMenu->addAction(layerSelectionAction);
448 if (filteringModel.isNull())
return;
449 if (!nodeView)
return;
451 nodeView->blockSignals(
true);
455 QModelIndex idx = filteringModel->indexFromNode(node);
457 nodeView->setExpanded(idx, !node->
collapsed());
464 nodeView->blockSignals(
false);
472 if (nodes.size() == 1) {
473 KisAction *action =
m_canvas->viewManager()->actionManager()->actionByName(
"add_new_paint_layer");
476 KisAction *action =
m_canvas->viewManager()->actionManager()->actionByName(
"create_quick_group");
525 action = actionManager->
createAction(
"move_layer_down");
544 setEnabled(canvas != 0);
547 m_canvas->disconnectCanvasObserver(
this);
554 animation->disconnect(
this);
557 disconnect(
m_image, 0,
this, 0);
579 kritaShapeController,
642 disconnect(
m_image, 0,
this, 0);
652 QDockWidget::showEvent(event);
661 QDockWidget::hideEvent(event);
683 if (parentLayerDevice) {
686 parentLayerDevice, SIGNAL(colorSpaceChanged(
const KoColorSpace*)),
691 activeNode, SIGNAL(opacityChanged(quint8)),
706 if (activeNode->inherits(
"KisColorizeMask") || activeNode->inherits(
"KisLayer")) {
724 const KisGroupLayer *group = qobject_cast<const KisGroupLayer*>(activeNode.
data());
727 m_wdgLayerBox->cmbComposite->setEnabled(compositeSelectionActive);
728 }
else if (activeNode->inherits(
"KisMask")) {
758 QModelIndex index = node ?
m_filteringModel->indexFromNode(node) : QModelIndex();
766 QItemSelection selection;
770 QItemSelectionRange selectionRange(idx);
771 selection << selectionRange;
775 m_wdgLayerBox->listLayers->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect);
793 Q_ASSERT(opacity >= 0 && opacity <= 100);
800 double percentage =
value * 100.0 / 255.0;
811 if (nodes.isEmpty() || !activeNode)
return;
869 QString compositeOp =
m_wdgLayerBox->cmbComposite->selectedCompositeOp().id();
905 QAction *action =
m_canvas->viewManager()->actionManager()->actionByName(
"selectopaque");
962 if (!showSelections) {
969 m_nodeModel->setShowGlobalSelection(showSelections);
974 if (!globalSelectionMask) {
978 if (!masks.isEmpty()) {
979 globalSelectionMask =
dynamic_cast<KisSelectionMask*
>(masks.first().data());
984 if (!globalSelectionMask) {
987 if (!masks.isEmpty()) {
988 globalSelectionMask =
dynamic_cast<KisSelectionMask*
>(masks.first().data());
992 if (globalSelectionMask) {
993 if (showSelections) {
994 activateNode = globalSelectionMask;
998 if (activateNode != lastActiveNode) {
1000 }
else if (lastActiveNode) {
1004 if (showSelections && !globalSelectionMask) {
1013 lastActiveNode, 0,
m_image,
false),
1023 }
else if (!showSelections &&
1024 globalSelectionMask &&
1035 if (showSelections) {
1050 QModelIndex selectedIndex =
1054 setCurrentIndex(selectedIndex, QItemSelectionModel::ClearAndSelect);
1059 Q_FOREACH (
const QModelIndex &idx, selection) {
1062 if (idx.column() != 0) {
1087 QModelIndex currentIndex =
m_wdgLayerBox->listLayers->currentIndex();
1090 if (currentIndex.isValid() && parent == currentIndex.parent()
1091 && currentIndex.row() >= start && currentIndex.row() <= end) {
1092 QModelIndex old = currentIndex;
1094 if (model && end < model->rowCount(parent) - 1)
1095 currentIndex = model->index(end + 1, old.column(), parent);
1096 else if (model && start > 0)
1097 currentIndex = model->index(start - 1, old.column(), parent);
1099 currentIndex = QModelIndex();
1101 if (currentIndex.isValid() && currentIndex != old) {
1116 QItemSelectionModel *model =
m_wdgLayerBox->listLayers->selectionModel();
1122 QItemSelection selection;
1123 Q_FOREACH(
const QModelIndex &idx, newSelection) {
1124 selection.select(idx, idx);
1127 model->select(selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
1139 Q_FOREACH(
KisNodeSP selectedNode, selectedNodes) {
1146 auto applyLabelFunc =
1148 if (child->colorLabelIndex() == 0) {
1149 child->setColorLabelIndex(label);
1181 const bool singleNode = nodes.size() == 1;
1183 if (index.isValid()) {
1201 if (node && node->inherits(
"KisCloneLayer")) {
1214 menu.addSeparator();
1229 menu.addSeparator();
1230 QMenu *selectMenu = menu.addMenu(i18n(
"&Select"));
1236 QMenu *groupMenu = menu.addMenu(i18nc(
"A group of layers",
"&Group"));
1240 QMenu *locksMenu = menu.addMenu(i18n(
"&Toggle Locks && Visibility"));
1247 QMenu *addLayerMenu = menu.addMenu(i18n(
"&Add"));
1254 addLayerMenu->addSeparator();
1257 QMenu *convertToMenu = menu.addMenu(i18n(
"&Convert"));
1266 QMenu *splitAlphaMenu = menu.addMenu(i18n(
"S&plit Alpha"));
1271 QMenu *addLayerMenu = menu.addMenu(i18n(
"&Add"));
1275 menu.addSeparator();
1282 if (node && !node->inherits(
"KisTransformMask")) {
1321 if (!index.isValid())
1399#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)
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)
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 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 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()
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)
rgba palette[MAX_PALETTE]
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