File indexing completed on 2024-06-23 04:26:24

0001 /*
0002  *  LayerBox.h - part of Krita aka Krayon aka KimageShop
0003  *
0004  *  SPDX-FileCopyrightText: 2002 Patrick Julien <freak@codepimps.org>
0005  *  SPDX-FileCopyrightText: 2006 Gábor Lehel <illissius@gmail.com>
0006  *  SPDX-FileCopyrightText: 2007 Thomas Zander <zander@kde.org>
0007  *  SPDX-FileCopyrightText: 2007-2009 Boudewijn Rempt <boud@valdyas.org>
0008  *
0009  *  SPDX-License-Identifier: GPL-2.0-or-later
0010  */
0011 #ifndef KIS_LAYERBOX_H
0012 #define KIS_LAYERBOX_H
0013 
0014 #include <QFrame>
0015 #include <QList>
0016 #include <QDockWidget>
0017 #include <QPointer>
0018 #include <QTimer>
0019 
0020 #include <kis_debug.h>
0021 
0022 #include <KoColorSpace.h>
0023 #include <KoDockFactoryBase.h>
0024 
0025 #include <kis_types.h>
0026 
0027 #include "kis_action.h"
0028 #include "KisViewManager.h"
0029 #include "kis_mainwindow_observer.h"
0030 #include "kis_signal_compressor.h"
0031 #include "kis_layer_filter_widget.h"
0032 #include "kis_signal_auto_connection.h"
0033 #include <QSlider>
0034 #include <QCheckBox>
0035 #include <kis_slider_spin_box.h>
0036 #include <QComboBox>
0037 #include <kis_idle_watcher.h>
0038 
0039 #include "kritalayerdocker_export.h"
0040 
0041 class QModelIndex;
0042 
0043 typedef QList<QModelIndex> QModelIndexList;
0044 
0045 class QMenu;
0046 class QAbstractButton;
0047 class KoCompositeOp;
0048 class KisCanvas2;
0049 class KisNodeModel;
0050 class KisNodeFilterProxyModel;
0051 class Ui_WdgLayerBox;
0052 class KisNodeJugglerCompressed;
0053 class KisColorLabelSelectorWidgetMenuWrapper;
0054 class QWidgetAction;
0055 class KisKeyframeChannel;
0056 class KisSelectionActionsAdapter;
0057 
0058 /**
0059  * A widget that shows a visualization of the layer structure.
0060  *
0061  * The center of the layer box is KisNodeModel, which shows the actual layers.
0062  * This widget adds docking functionality and command buttons.
0063  *
0064  */
0065 class KRITALAYERDOCKER_EXPORT LayerBox : public QDockWidget, public KisMainwindowObserver
0066 {
0067 
0068     Q_OBJECT
0069 
0070 public:
0071 
0072     LayerBox();
0073     ~LayerBox() override;
0074     QString observerName() override { return "LayerBox"; }
0075     /// reimplemented from KisMainwindowObserver
0076     void setViewManager(KisViewManager* kisview) override;
0077     void setCanvas(KoCanvasBase *canvas) override;
0078     void unsetCanvas() override;
0079 
0080 protected:
0081     void showEvent(QShowEvent *event) override;
0082     void hideEvent(QHideEvent *event) override;
0083 
0084 private Q_SLOTS:
0085 
0086     void notifyImageDeleted();
0087 
0088     void slotContextMenuRequested(const QPoint &pos, const QModelIndex &index);
0089 
0090     // From the node manager to the layerbox
0091     void slotSetCompositeOp(const KoCompositeOp* compositeOp);
0092     void slotSetOpacity(double opacity);
0093     void slotUpdateOpacitySlider(quint8 value);
0094     void updateUI();
0095     void setCurrentNode(KisNodeSP node);
0096     void slotModelReset();
0097 
0098     // from the layerbox to the node manager
0099     void slotRmClicked();
0100     void slotRaiseClicked();
0101     void slotLowerClicked();
0102     void slotPropertiesClicked();
0103     void slotChangeCloneSourceClicked();
0104 
0105     void slotCompositeOpChanged(int index);
0106     void slotOpacityChanged();
0107     void slotOpacitySliderMoved(qreal opacity);
0108 
0109     void slotCollapsed(const QModelIndex &index);
0110     void slotExpanded(const QModelIndex &index);
0111 
0112     void slotSelectOpaque();
0113     void slotNodeCollapsedChanged();
0114 
0115     void slotEditGlobalSelection(bool showSelections);
0116     void slotRenameCurrentNode();
0117 
0118     void slotAdjustCurrentBeforeRemoveRows(const QModelIndex &parent, int first, int last);
0119     void selectionChanged(const QModelIndexList &selection);
0120     void slotNodeManagerChangedSelection(const QList<KisNodeSP> &nodes);
0121     void slotColorLabelChanged(int index);
0122     void slotUpdateIcons();
0123     void toggleActiveLayerSolo();
0124     void updateLayerOpMenu(const QModelIndex &index, QMenu &menu);
0125 
0126     void slotAddLayerBnClicked();
0127     void slotLayerOpMenuOpened();
0128     void slotLayerOpMenuClosed();
0129 
0130     void updateAvailableLabels();
0131     void updateLayerFiltering();
0132 
0133     void slotUpdateThumbnailIconSize();
0134     void slotUpdateTreeIndentation();
0135     void slotUpdateLayerInfoTextStyle();
0136     void slotUpdateLayerInfoTextOpacity();
0137     void slotUpdateUseInlineLayerInfoText();
0138     void slotUpdateUseLayerSelectionCheckbox();
0139 
0140     void slotImageTimeChanged(int time);
0141     void slotForgetAboutSavedNodeBeforeEditSelectionMode();
0142 
0143 Q_SIGNALS:
0144     void imageChanged();
0145 
0146 private:
0147     inline void connectActionToButton(KisViewManager* view, QAbstractButton *button, const QString &id);
0148     inline void addActionToMenu(QMenu *menu, const QString &id);
0149     // reimp from KisNodeManager
0150     qint32 convertOpacityToInt(qreal opacity);
0151 
0152     KisNodeSP findNonHidableNode(KisNodeSP startNode);
0153 private:
0154 
0155     QPointer<KisCanvas2> m_canvas;
0156     QScopedPointer<KisSelectionActionsAdapter> m_selectionActionsAdapter;
0157     QMenu *m_newLayerMenu;
0158     QMenu *m_opLayerMenu;
0159     KisImageWSP m_image;
0160     QPointer<KisNodeModel> m_nodeModel;
0161     QPointer<KisNodeFilterProxyModel> m_filteringModel;
0162     QPointer<KisNodeManager> m_nodeManager;
0163     QPointer<KisColorLabelSelectorWidgetMenuWrapper> m_colorSelector;
0164     QPointer<QWidgetAction> m_colorSelectorAction;
0165     Ui_WdgLayerBox* m_wdgLayerBox;
0166     QTimer m_opacityDelayTimer;
0167     int m_newOpacity;
0168     KisNodeSP m_changedOpacityNode;
0169 
0170     KisAction *m_removeAction;
0171     KisAction *m_propertiesAction;
0172     KisAction *m_changeCloneSourceAction;
0173     KisAction *m_layerToggleSolo;
0174     KisAction *m_showGlobalSelectionMask;
0175     KisSignalCompressor m_colorLabelCompressor;
0176     KisSignalCompressor m_thumbnailSizeCompressor;
0177     KisSignalCompressor m_treeIndentationCompressor;
0178     KisSignalCompressor m_infoTextOpacityCompressor;
0179 
0180     KisLayerFilterWidget* layerFilterWidget;
0181     QSlider *thumbnailSizeSlider;
0182     QSlider *indentationSlider;
0183     QComboBox *infoTextCombobox;
0184     KisSliderSpinBox *infoTextOpacitySlider;
0185     QCheckBox *infoTextInlineChkbox;
0186     QCheckBox *layerSelectionCheckBox {nullptr};
0187 
0188     KisNodeSP m_activeNode;
0189     KisNodeWSP m_savedNodeBeforeEditSelectionMode;
0190     bool m_blockOpacityUpdate {false};
0191     KisSignalAutoConnectionsStore m_activeNodeConnections;
0192 };
0193 
0194 class KRITALAYERDOCKER_EXPORT LayerBoxFactory : public KoDockFactoryBase
0195 {
0196 
0197 public:
0198     LayerBoxFactory() { }
0199 
0200     QString id() const override {
0201         return QString("KisLayerBox");
0202     }
0203 
0204     QDockWidget* createDockWidget() override {
0205         LayerBox * dockWidget = new LayerBox();
0206 
0207         dockWidget->setObjectName(id());
0208 
0209         return dockWidget;
0210     }
0211 
0212     DockPosition defaultDockPosition() const override {
0213         return DockRight;
0214     }
0215 
0216 };
0217 
0218 #endif // KIS_LAYERBOX_H
0219