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

0001 /*
0002  * SPDX-FileCopyrightText: 2020 Mathias Wein <lynx.mw+kde@gmail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #include "WGShadeSelector.h"
0008 
0009 #include "WGConfig.h"
0010 #include "WGShadeSlider.h"
0011 
0012 #include <QVBoxLayout>
0013 #include <QMouseEvent>
0014 
0015 WGShadeSelector::WGShadeSelector(WGSelectorDisplayConfigSP displayConfig, KisVisualColorModelSP colorModel, QWidget *parent)
0016     : WGSelectorWidgetBase(displayConfig, parent)
0017     , m_model(colorModel)
0018 {
0019     QVBoxLayout* l = new QVBoxLayout(this);
0020     l->setSpacing(1);
0021     l->setMargin(0);
0022     setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
0023 
0024     connectToModel();
0025 }
0026 
0027 void WGShadeSelector::setModel(KisVisualColorModelSP colorModel)
0028 {
0029     if (m_model) {
0030         m_model->disconnect(this);
0031         disconnect(m_model.data());
0032     }
0033     m_model = colorModel;
0034     for (WGShadeSlider *slider : qAsConst(m_sliders)) {
0035         slider->setModel(m_model);
0036     }
0037     connectToModel();
0038     if (m_model->colorModel() != KisVisualColorModel::None) {
0039         slotChannelValuesChanged(m_model->channelValues());
0040     }
0041 }
0042 
0043 void WGShadeSelector::updateSettings()
0044 {
0045     WGConfig::Accessor cfg;
0046     m_lineHeight = cfg.get(WGConfig::shadeSelectorLineHeight);
0047     QVector<WGConfig::ShadeLine> config = cfg.shadeSelectorLines();
0048 
0049     while (config.size() > m_sliders.size()) {
0050         WGShadeSlider *line = new WGShadeSlider(displayConfiguration(), this, m_model);
0051         m_sliders.append(line);
0052         layout()->addWidget(m_sliders.last());
0053         connect(line, SIGNAL(sigChannelValuesChanged(QVector4D)), SLOT(slotSliderValuesChanged(QVector4D)));
0054         connect(line, SIGNAL(sigInteraction(bool)), SLOT(slotSliderInteraction(bool)));
0055     }
0056     while (config.size() < m_sliders.size()) {
0057         layout()->removeWidget(m_sliders.last());
0058         delete m_sliders.takeLast();
0059     }
0060 
0061     for (int i=0; i < config.size(); i++) {
0062         m_sliders[i]->setGradient(config[i].gradient, config[i].offset);
0063         m_sliders[i]->setDisplayMode(config[i].patchCount < 0, config[i].patchCount);
0064         m_sliders[i]->setFixedHeight(m_lineHeight);
0065     }
0066     m_resetOnExternalUpdate = cfg.get(WGConfig::shadeSelectorUpdateOnExternalChanges);
0067     m_resetOnInteractions = cfg.get(WGConfig::shadeSelectorUpdateOnInteractionEnd);
0068     m_resetOnRightClick = cfg.get(WGConfig::shadeSelectorUpdateOnRightClick);
0069 
0070     if (m_model->colorModel() != KisVisualColorModel::None) {
0071         slotReset();
0072         slotChannelValuesChanged(m_model->channelValues());
0073     }
0074 }
0075 
0076 void WGShadeSelector::mousePressEvent(QMouseEvent *event)
0077 {
0078     if (m_resetOnRightClick && event->button() == Qt::RightButton) {
0079         for (WGShadeSlider* slider : qAsConst(m_sliders)) {
0080             slider->slotSetChannelValues(m_model->channelValues());
0081         }
0082     }
0083 }
0084 
0085 void WGShadeSelector::connectToModel()
0086 {
0087     connect(m_model.data(), SIGNAL(sigColorModelChanged()), SLOT(slotReset()));
0088     connect(m_model.data(), SIGNAL(sigColorSpaceChanged()), SLOT(slotReset()));
0089     connect(m_model.data(), SIGNAL(sigChannelValuesChanged(QVector4D,quint32)),
0090             SLOT(slotChannelValuesChanged(QVector4D)));
0091     connect(this, SIGNAL(sigChannelValuesChanged(QVector4D)),
0092             m_model.data(), SLOT(slotSetChannelValues(QVector4D)));
0093 }
0094 
0095 void WGShadeSelector::slotChannelValuesChanged(const QVector4D &values)
0096 {
0097     if (m_allowUpdates && (m_resetOnExternalUpdate || !m_initialized)) {
0098         for (WGShadeSlider* slider : qAsConst(m_sliders)) {
0099             slider->slotSetChannelValues(values);
0100         }
0101         m_initialized = true;
0102     }
0103 }
0104 
0105 void WGShadeSelector::slotSliderValuesChanged(const QVector4D &values)
0106 {
0107     m_allowUpdates = false;
0108     emit sigChannelValuesChanged(values);
0109     m_allowUpdates = true;
0110 }
0111 
0112 void WGShadeSelector::slotSliderInteraction(bool active)
0113 {
0114     if (active) {
0115         const WGShadeSlider* activeLine = qobject_cast<WGShadeSlider*>(sender());
0116         for (WGShadeSlider* slider : qAsConst(m_sliders)) {
0117             if (slider != activeLine) {
0118                 slider->resetHandle();
0119             }
0120         }
0121         emit sigColorInteraction(active);
0122         if (activeLine) {
0123             // the line may have different channel values at any position than the last used one
0124             m_allowUpdates = false;
0125             emit sigChannelValuesChanged(activeLine->channelValues());
0126             m_allowUpdates = true;
0127         }
0128     }
0129     else {
0130         // reset slider base values if configured for automatic reset
0131         if (m_resetOnInteractions) {
0132             for (WGShadeSlider* slider : qAsConst(m_sliders)) {
0133                 slider->slotSetChannelValues(m_model->channelValues());
0134             }
0135         }
0136         emit sigColorInteraction(active);
0137     }
0138 }
0139 
0140 void WGShadeSelector::slotReset()
0141 {
0142     m_initialized = false;
0143 }