File indexing completed on 2024-12-22 04:13:17

0001 /*
0002  * SPDX-FileCopyrightText: 2018 Jouni Pentikäinen <joupent@gmail.com>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #ifndef KISSELECTIONPROPERTYSLIDER_H
0008 #define KISSELECTIONPROPERTYSLIDER_H
0009 
0010 #include <QObject>
0011 
0012 #include <KoShape.h>
0013 #include <kritaui_export.h>
0014 #include <kis_signals_blocker.h>
0015 #include "kis_slider_spin_box.h"
0016 
0017 class KRITAUI_EXPORT KisSelectionPropertySliderBase : public KisDoubleSliderSpinBox
0018 {
0019     Q_OBJECT
0020 
0021 public:
0022     explicit KisSelectionPropertySliderBase(QWidget* parent = 0);
0023     ~KisSelectionPropertySliderBase() override;
0024 
0025     /**
0026      * Set the prefix/suffix using i18n strings in the form of `prefix {n} suffix`.
0027      *
0028      * @param normalTemplate The text in the form of `prefix{n}suffix`, usually
0029      *                       passed through `i18n` or `i18nc`, for when there
0030      *                       is only one selection or multiple selections with
0031      *                       the same value.
0032      * @param mixedTemplate The text in the form of `prefix{n}suffix`, usually
0033      *                      passed through `i18n` or `i18nc`, for when there
0034      *                      are multiple selections with different values.
0035      */
0036     void setTextTemplates(const QString &normalTemplate, const QString &mixedTemplate);
0037 
0038     /**
0039      * **Deleted function** - use `setTextTemplates` instead.
0040      */
0041     void setPrefix(const QString &) = delete;
0042 
0043     /**
0044      * **Deleted function** - use `setTextTemplates` instead.
0045      */
0046     void setSuffix(const QString &) = delete;
0047 
0048 protected:
0049     void setInternalValue(qreal value, bool blockUpdateSignal) override;
0050 
0051     void setSelectionValue(qreal commonValue, bool mixed);
0052 
0053     virtual bool hasSelection() const = 0;
0054     virtual qreal getCommonValue() const = 0;
0055 
0056 private Q_SLOTS:
0057     void slotCompressedUpdate();
0058 
0059 private:
0060     struct Private;
0061     const QScopedPointer<Private> m_d;
0062 };
0063 
0064 /**
0065  * This is a generic slider for adjusting a property across a set of one or
0066  * more items such as a selection.
0067  *
0068  * When using this class, first call the setValueGetter method to allow the
0069  * slider to get values from the items. For example:
0070  * slider->setValueGetter(
0071  *     [](KoShape *s) { return s->transparency(); }
0072  * );
0073  *
0074  * To update the slider, call setSelection with the new set of objects.
0075  *
0076  * When the slider is dragged, valueChanged(qreal) signals are emitted after
0077  * signal compression.
0078  */
0079 template<class T>
0080 class KRITAUI_EXPORT KisSelectionPropertySlider : public KisSelectionPropertySliderBase
0081 {
0082 public:
0083     explicit KisSelectionPropertySlider(QWidget *parent = 0)
0084         : KisSelectionPropertySliderBase(parent)
0085     {}
0086 
0087     void setValueGetter(qreal (*getter)(T))
0088     {
0089         m_valueGetter = getter;
0090     }
0091 
0092     void setSelection(QList<T> newSelection)
0093     {
0094         KisSignalsBlocker b(this);
0095 
0096         m_selection = newSelection;
0097 
0098         const qreal commonValue = getCommonValue();
0099 
0100         setEnabled(!m_selection.isEmpty());
0101         setSelectionValue(commonValue, commonValue < 0.0);
0102     }
0103 
0104     QList<T> selection() const {
0105         return m_selection;
0106     }
0107 
0108 protected:
0109     bool hasSelection() const override
0110     {
0111         return !m_selection.isEmpty();
0112     }
0113 
0114     qreal getCommonValue() const override
0115     {
0116         qreal commonValue = -1.0;
0117 
0118         Q_FOREACH (T item, m_selection) {
0119             const qreal itemValue = m_valueGetter(item);
0120 
0121             if (commonValue < 0) {
0122                 commonValue = itemValue;
0123             } else if (!qFuzzyCompare(commonValue, itemValue)) {
0124                 commonValue = -1.0;
0125                 break;
0126             }
0127         }
0128 
0129         return commonValue;
0130     }
0131 
0132 private:
0133     qreal (*m_valueGetter)(T) {nullptr};
0134     QList<T> m_selection;
0135 };
0136 
0137 class KRITAUI_EXPORT KisShapePropertySlider : public KisSelectionPropertySlider<KoShape*>
0138 {
0139 public:
0140     KisShapePropertySlider(QWidget* parent=nullptr);
0141 };
0142 
0143 #endif