File indexing completed on 2024-12-22 04:13:16
0001 /* 0002 * This file is part of Krita 0003 * 0004 * SPDX-FileCopyrightText: 2021 Deif Lou <ginoba@gmail.com> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef KIS_HISTOGRAM_VIEW_H 0010 #define KIS_HISTOGRAM_VIEW_H 0011 0012 #include <QScopedPointer> 0013 #include <QWidget> 0014 0015 #include "kritaui_export.h" 0016 0017 class KisHistogram; 0018 class KoColorSpace; 0019 0020 /** 0021 * @brief A widget that can display different KisHistograms. It renders a 0022 * somewhat smooth shape with different colors (for rgb, cmyk and xyz channels). 0023 * It can also display the different channels of a colorspace overlapped. 0024 */ 0025 class KRITAUI_EXPORT KisHistogramView : public QWidget 0026 { 0027 Q_OBJECT 0028 0029 public: 0030 KisHistogramView(QWidget *parent); 0031 ~KisHistogramView(); 0032 0033 /** 0034 * @brief Sets up the widget by passing a collection of KisHistograms, the 0035 * color space for each histogram and the channels that must be set up for 0036 * each histogram 0037 * @param histograms A collection of KisHistogram pointers to take the info 0038 * from. You can add several histograms and later select which histogram is 0039 * used at any given moment. This prevents calling multiple times the setup 0040 * function with different histograms. That way the shaped to draw are 0041 * computed only once. The histogram pointers are not stored or owned 0042 * internally, so you can safely delete them if you don't need them 0043 * @param colorSpaces The collection of color spaces associated with each 0044 * histogram. They are used to color different channels. For example, the 0045 * histogram for the red channel of a rgb histogram will be painted as a red 0046 * shape 0047 * @param channels A collection of vectors that contain the channel number 0048 * for the channels that must be used to compute the histograms. For example, 0049 * if the second histogram is a Lab histogram, and you are interested only 0050 * in the lightness channel, the second vector in the collection should have 0051 * only one element, the number 0 (index of the lightness channel). If the 0052 * collection is empty or if the vector of channels for any given histogram 0053 * is empty, then all the channels will be used 0054 */ 0055 void setup(const QVector<KisHistogram*> &histograms, 0056 const QVector<const KoColorSpace*> &colorSpaces, 0057 const QVector<QVector<int>> &channels = {}); 0058 /** 0059 * @brief Returns the channels that are available for the currently selected 0060 * histogram 0061 * @see setChannel 0062 * @see setChannels 0063 */ 0064 const QVector<int>& channels() const; 0065 /** 0066 * @brief Returns the color that is being used to paint a generic histogram. 0067 * All the histogram channels will use this color with the exception of the 0068 * red, green and blue channels in a rgba histogram; the cyan, magenta, 0069 * yellow and black channels in a cmyka histogram; and the x, y, and z 0070 * channels in a xyz histogram 0071 * @see setDefaultColor 0072 */ 0073 QColor defaultColor() const; 0074 /** 0075 * @brief Return the vertical scale that is used to paint the histogram 0076 * shape. A scale of 1 will show all the histogram in the widget area. 0077 * Scales less that 1 are not allowed 0078 * @see setScale 0079 * @see setScaleToFit 0080 * @see setScaleToCutLongPeaks 0081 */ 0082 qreal scale() const; 0083 /** 0084 * @brief Returns true if the histogram shape being shown is formed by the 0085 * logarithmic mapping of the original histogram values instead of the values 0086 * themselves 0087 * @see setLogarithmic 0088 */ 0089 bool isLogarithmic() const; 0090 0091 public Q_SLOTS: 0092 /** 0093 * @brief Activates the given channel of the given histogram. This allows to 0094 * change the view between the different histograms and channels passed to 0095 * the setup function 0096 * @see channel 0097 * @see setChannels 0098 * @see setup 0099 */ 0100 void setChannel(int channel, int histogramIndex = 0); 0101 /** 0102 * @brief Activates the given channels of the given histogram. This allows to 0103 * change the view between the different histograms and channels passed to 0104 * the setup function. This function activates multiple channels that will be 0105 * displayed at once in the widget 0106 * @see channel 0107 * @see setChannel 0108 * @see setup 0109 */ 0110 void setChannels(const QVector<int> &channels, int histogramIndex = 0); 0111 /** 0112 * @brief This clears the channel selection. The widget will show a null 0113 * symbol in it's center when there are no activated channels 0114 */ 0115 void clearChannels(); 0116 /** 0117 * @brief Set the default color used when there is no preference to color 0118 * the selected histogram 0119 * @see defaultColor 0120 */ 0121 void setDefaultColor(const QColor &newDefaultColor); 0122 /** 0123 * @brief Set the scale used to paint the widget. The scale can also be 0124 * changed by clicking and dragging up/down in the widget 0125 * @see scale 0126 * @see setScaleToFit 0127 * @see setScaleToCutLongPeaks 0128 */ 0129 void setScale(qreal newScale); 0130 /** 0131 * @brief Set the scale used to paint the widget to 1. You can also return 0132 * to a scale of 1 by double clicking on the widget if the current scale is 0133 * other than 1. If you double click when the scale is one the effect will 0134 * be the same as calling setScaleToCutLongPeaks 0135 * @see scale 0136 * @see setScale 0137 * @see setScaleToCutLongPeaks 0138 */ 0139 void setScaleToFit(); 0140 /** 0141 * @brief Sometimes there can be some outliers in the histogram that show in 0142 * the widget as long vertical peaks. Since a scale of 1 will show all the 0143 * histogram, this can make its interesting parts too small to take any 0144 * valuable information from them. This function will try to come up with a 0145 * scale value that favors those interesting parts over the long peaks, 0146 * which will be pushed and will look cutted 0147 * @see scale 0148 * @see setScale 0149 * @see setScaleToFit 0150 */ 0151 void setScaleToCutLongPeaks(); 0152 /** 0153 * @brief Set if the histogram shape being shown is formed by the 0154 * logarithmic mapping of the original histogram values instead of the 0155 * values themselves 0156 * @see isLogarithmic 0157 */ 0158 void setLogarithmic(bool logarithmic); 0159 0160 protected: 0161 void paintEvent(QPaintEvent *e) override; 0162 void mouseDoubleClickEvent(QMouseEvent *e) override; 0163 void mousePressEvent(QMouseEvent *e) override; 0164 void mouseMoveEvent(QMouseEvent *e) override; 0165 0166 private: 0167 class Private; 0168 QScopedPointer<Private> m_d; 0169 }; 0170 0171 #endif