File indexing completed on 2024-12-22 04:15:37

0001 /*
0002  *  SPDX-FileCopyrightText: 2016 Boudewijn Rempt <boud@valdyas.org>
0003  *  SPDX-FileCopyrightText: 2019 Iván SantaMaría <ghevan@gmail.com>
0004  *
0005  *  SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #include "KisWdgOptionsBrush.h"
0009 
0010 #include <KisViewManager.h>
0011 #include <kis_image.h>
0012 #include <KoProperties.h>
0013 #include <KisDocument.h>
0014 
0015 KisWdgOptionsBrush::KisWdgOptionsBrush(QWidget *parent)
0016     : KisConfigWidget(parent)
0017     , m_currentDimensions(0)
0018     , m_layersCount(0)
0019     , m_view(0)
0020 {
0021     setupUi(this);
0022     connect(this->brushStyle, SIGNAL(currentIndexChanged(int)), SLOT(slotEnableSelectionMethod(int)));
0023     connect(this->dimensionSpin, SIGNAL(valueChanged(int)), SLOT(slotActivateDimensionRanks()));
0024 
0025     slotEnableSelectionMethod(brushStyle->currentIndex());
0026 
0027     BrushPipeSelectionModeHelper *bp;
0028     for (int i = 0; i < this->dimensionSpin->maximum(); i++) {
0029         bp = new BrushPipeSelectionModeHelper(0, i);
0030         connect(bp, SIGNAL(sigRankChanged(int)), SLOT(slotRecalculateRanks(int)));
0031         dimRankLayout->addWidget(bp);
0032     }
0033 
0034     slotActivateDimensionRanks();
0035 }
0036 
0037 void KisWdgOptionsBrush::setConfiguration(const KisPropertiesConfigurationSP cfg)
0038 {
0039     spacingWidget->setSpacing(false, cfg->getDouble("spacing"));
0040     if (!cfg->getString("name").isEmpty()) {
0041         nameLineEdit->setText(cfg->getString("name"));
0042     }
0043     colorAsMask->setChecked(cfg->getBool("mask"));
0044     brushStyle->setCurrentIndex(cfg->getInt("brushStyle"));
0045     dimensionSpin->setValue(cfg->getInt("dimensions"));
0046 
0047     QLayoutItem *item;
0048     BrushPipeSelectionModeHelper *bp;
0049     for (int i = 0; i < dimensionSpin->maximum(); ++i) {
0050         if ((item = dimRankLayout->itemAt(i)) != 0) {
0051             bp = dynamic_cast<BrushPipeSelectionModeHelper*>(item->widget());
0052             bp->cmbSelectionMode.setCurrentIndex(cfg->getInt("selectionMode" + QString::number(i)));
0053             bp->rankSpinBox.setValue(cfg->getInt("rank" + QString::number(i)));
0054         }
0055     }
0056 }
0057 
0058 KisPropertiesConfigurationSP KisWdgOptionsBrush::configuration() const
0059 {
0060     KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration();
0061     cfg->setProperty("spacing", spacingWidget->spacing());
0062     cfg->setProperty("name", nameLineEdit->text());
0063     cfg->setProperty("mask", colorAsMask->isChecked());
0064     cfg->setProperty("brushStyle", brushStyle->currentIndex());
0065     cfg->setProperty("dimensions", dimensionSpin->value());
0066 
0067     QLayoutItem *item;
0068     BrushPipeSelectionModeHelper *bp;
0069     for (int i = 0; i < dimensionSpin->maximum(); ++i) {
0070         if ((item = dimRankLayout->itemAt(i)) != 0) {
0071             bp = dynamic_cast<BrushPipeSelectionModeHelper*>(item->widget());
0072             cfg->setProperty("selectionMode" + QString::number(i), bp->cmbSelectionMode.currentIndex());
0073             cfg->setProperty("rank" + QString::number(i),  bp->rankSpinBox.value());
0074         }
0075     }
0076 
0077     return cfg;
0078 }
0079 
0080 void KisWdgOptionsBrush::setView(KisViewManager *view)
0081 {
0082     if (view) {
0083         m_view = view;
0084         KoProperties properties;
0085         properties.setProperty("visible", true);
0086         m_layersCount = m_view->image()->root()->childNodes(QStringList("KisLayer"), properties).count();
0087 
0088         slotRecalculateRanks();
0089     }
0090 }
0091 
0092 void KisWdgOptionsBrush::slotEnableSelectionMethod(int value)
0093 {
0094     if (value == 0) {
0095         animStyleGroup->setEnabled(false);
0096     } else {
0097         animStyleGroup->setEnabled(true);
0098     }
0099 }
0100 
0101 void KisWdgOptionsBrush::slotActivateDimensionRanks()
0102 {
0103     QLayoutItem *item;
0104     BrushPipeSelectionModeHelper *bp;
0105     int dim = this->dimensionSpin->value();
0106     if (dim >= m_currentDimensions) {
0107         for (int i = m_currentDimensions; i < dim; ++i) {
0108             if ((item = dimRankLayout->itemAt(i)) != 0) {
0109                 bp = dynamic_cast<BrushPipeSelectionModeHelper*>(item->widget());
0110                 bp->setEnabled(true);
0111                 bp->show();
0112             }
0113         }
0114     }
0115     else {
0116         for (int i = m_currentDimensions -1; i >= dim; --i) {
0117             if ((item = dimRankLayout->itemAt(i)) != 0) {
0118                bp = dynamic_cast<BrushPipeSelectionModeHelper*>(item->widget());
0119                bp->setEnabled(false);
0120                bp->hide();
0121             }
0122         }
0123     }
0124     m_currentDimensions = dim;
0125 }
0126 
0127 void KisWdgOptionsBrush::slotRecalculateRanks(int rankDimension)
0128 {
0129     int rankSum = 0;
0130     int maxDim = this->dimensionSpin->maximum();
0131 
0132     QVector<BrushPipeSelectionModeHelper *> bp;
0133     QLayoutItem *item;
0134 
0135     for (int i = 0; i < maxDim; ++i) {
0136         if ((item = dimRankLayout->itemAt(i)) != 0) {
0137             bp.push_back(dynamic_cast<BrushPipeSelectionModeHelper*>(item->widget()));
0138             rankSum += bp.at(i)->rankSpinBox.value();
0139         }
0140     }
0141 
0142     BrushPipeSelectionModeHelper *currentBrushHelper;
0143     BrushPipeSelectionModeHelper *callerBrushHelper = bp.at(rankDimension);
0144     QVectorIterator<BrushPipeSelectionModeHelper*> bpIterator(bp);
0145 
0146     while (rankSum > m_layersCount && bpIterator.hasNext()) {
0147         currentBrushHelper = bpIterator.next();
0148 
0149         if (currentBrushHelper != callerBrushHelper) {
0150             int currentValue = currentBrushHelper->rankSpinBox.value();
0151             currentBrushHelper->rankSpinBox.setValue(currentValue -1);
0152             rankSum -= currentValue;
0153         }
0154     }
0155 
0156     if (rankSum > m_layersCount) {
0157         callerBrushHelper->rankSpinBox.setValue(m_layersCount);
0158     }
0159 
0160     if (rankSum == 0) {
0161         bp.at(0)->rankSpinBox.setValue(m_layersCount);
0162         return;
0163     }
0164 }