File indexing completed on 2024-05-12 04:44:31

0001 // SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com>
0002 // SPDX-License-Identifier: BSD-2-Clause OR MIT
0003 
0004 #ifndef COLORDIALOG_H
0005 #define COLORDIALOG_H
0006 
0007 #include "constpropagatinguniquepointer.h"
0008 #include "importexport.h"
0009 #include <qcolor.h>
0010 #include <qcolordialog.h>
0011 #include <qdialog.h>
0012 #include <qglobal.h>
0013 #include <qmetatype.h>
0014 #include <qnamespace.h>
0015 #include <qsharedpointer.h>
0016 #include <qstring.h>
0017 class QEvent;
0018 class QObject;
0019 class QShowEvent;
0020 class QWidget;
0021 
0022 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0023 #include <qtmetamacros.h>
0024 #else
0025 #include <qobjectdefs.h>
0026 #endif
0027 
0028 namespace PerceptualColor
0029 {
0030 class ColorDialogPrivate;
0031 
0032 class RgbColorSpace;
0033 
0034 /** @brief A perceptually uniform color picker dialog
0035  *
0036  * The color dialog’s function is to allow users to choose colors intuitively.
0037  * For example, you might use this in a drawing program to allow the user to
0038  * set the brush color.
0039  *
0040  * At difference to QColorDialog, this
0041  * dialog’s graphical components are perceptually uniform and therefore more
0042  * intuitive. It’s internally based on the LCH color model, which does reflect
0043  * the human perception much better than RGB or its transforms like HSV. At
0044  * the same time, this dialog does not require the user itself to know
0045  * anything about LCH at all, because the graphical representations is
0046  * intuitive.
0047  *
0048  * @image html ColorDialog.png "ColorDialog" width=500
0049  * @image html ColorDialogTab1.png "ColorDialog" width=500
0050  * @image html ColorDialogTab2.png "ColorDialog" width=500
0051  *
0052  * It is an @ref qdialogsourceompatibility "mostly source-compatible"
0053  * replacement for QColorDialog. It also adds some extra functionality
0054  * that is not available in QColorDialog.
0055  *
0056  * Just as with QColorDialog, the static functions provide a modal color
0057  * dialog. The static getColor() function shows the dialog, and allows
0058  * the user to specify a color:
0059  *
0060  * @snippet testcolordialog.cpp ColorDialog Get color
0061  *
0062  * The function can also be used to let
0063  * users choose a color with a level of transparency: pass the alpha channel
0064  * option as an additional argument:
0065  *
0066  * @snippet testcolordialog.cpp ColorDialog Get color with alpha channel
0067  *
0068  * @image html ColorDialogAlpha.png "ColorDialog with alpha channel" width=500
0069  *
0070  * More features:
0071  *
0072  * - A screen color picker is provided on many platforms.
0073  *
0074  * - For a non-modal dialog, use the normal constructors of this class.
0075  *
0076  * - The default window title is <em>Select Color</em>, and not the title of
0077  * your application. It can of course be customized with
0078  * <tt>QWidget::setWindowTitle()</tt>. The window title will
0079  * <em>not</em> be updated on <tt>QEvent::LanguageChange</tt> events.
0080  *
0081  * - At difference to the usual native platform color dialog, <em>this</em>
0082  * dialog can be resized. That makes sense, because it allows to see better
0083  * the gamut image. Therefore, this dialog is by default bigger than the usual
0084  * native platform color dialog. You can of course customize the dialog
0085  * size with QWidget::resize() or force a more space-saving layout through
0086  * the @ref layoutDimensions property.
0087  *
0088  * - The @ref ColorPatch that indicates the selected color is placed prominently
0089  * at the top of the widget. That is also useful for touch screens as the
0090  * @ref ColorPatch will not be hidden by the hand of the user when the user
0091  * is touching the above color selection widgets.
0092  *
0093  * - This dialog uses icons. See @ref hidpisupport "High DPI support"
0094  * about how to enable support for high-DPI icons.
0095  *
0096  * @note @anchor qdialogsourceompatibility The API of this class is mostly
0097  * source-compatible to the API of QColorDialog. This is a list of
0098  * incompatibilities:
0099  * - The constructors and also @ref getColor() require a color space
0100  *   as argument.
0101  * - As this dialog does not provide functionality for custom colors and
0102  *   standard color, the corresponding static functions of QColorDialog are
0103  *   not available in this class.
0104  * - The option <tt>ColorDialogOption::DontUseNativeDialog</tt>
0105  *   will always remain <tt>false</tt> (even if set explicitly), because it’s
0106  *   just the point of this library to provide an own, non-native dialog.
0107  * - While the enum declaration @ref ColorDialogOption itself is aliased
0108  *   here, this isn't possible for the enum values itself. Therefor, when
0109  *   working with @ref options, you cannot use <tt>ShowAlphaChannel</tt> but
0110  *   you have to use the fully qualified identifier (either
0111  *   <tt>PerceptualColor::ColorDialog::ColorDialogOption::ShowAlphaChannel</tt>
0112  *   or <tt>QColorDialog::ShowAlphaChannel</tt>, at your option.
0113  * - Calling @ref setCurrentColor() with colors that
0114  *   are <em>not</em> <tt>QColor::Spec::Rgb</tt> will lead to an automatic
0115  *   conversion like QColorDialog does, but at difference to QColorDialog, it
0116  *   is done with more precision, therefor the resulting
0117  *   @ref currentColor() might be slightly different. The same is true
0118  *   for <tt>QColor::Spec::Rgb</tt> types with floating point precision:
0119  *   While QColorDialog would round to full integers, <em>this</em> dialog
0120  *   preserves the floating point precision.
0121  * - When the default constructor is used, unlike QColorDialog, the default
0122  *   color is <em>not</em> guaranteed to be <tt>Qt::white</tt>.
0123  *
0124  * @internal
0125  *
0126  * @note In the QColorDialog API, the function <tt>QColorDialog::getRgba()</tt>
0127  * has been deprecated during the Qt5 life cycle. This class does not provide
0128  * source compatibility with obsolete functions of the QColorDialog API.
0129  *
0130  * @todo The @ref ColorDialogPrivate::m_lchLightnessSelector has a different
0131  * scale than the @ref ColorDialogPrivate::m_chromaHueDiagram, but both are
0132  * directly side-by-side in the dialog. Would it make sense to use the
0133  * same scale for both?
0134  *
0135  * @todo Provide an option to enable labels for the
0136  * <a href="https://www.handprint.com/HP/WCL/color12.html">warm-cool</a>
0137  * contrast, maybe outside the wheel around the position 45° (warm) and
0138  * 135° (cool).
0139  *
0140  * @todo In web design, CSS4 is often used. CSS4 also supports the
0141  * <a href="https://www.w3.org/TR/css-color-4/#the-hsl-notation"> HSL</a> and
0142  * the  <a href="https://www.w3.org/TR/css-color-4/#the-hwb-notation">HBW</a>
0143  * color space. We should do the same.
0144  *
0145  * @todo Provide <tt>setResizable(bool resizable)</tt>. Do not provide
0146  * a property, because in the background this is setting <em>two</em>
0147  * different values, which might be conflicting in the moment when read
0148  * access is done. Code within ColorDialog to enable:
0149  * <tt><br/>
0150  *  layout()->setSizeConstraint(QLayout::SetFixedSize);
0151  * <br/>
0152  *  setSizeGripEnabled(false);
0153  * <br/></tt>
0154  * Document the performance impact: When resizing is allowed (which is the
0155  * default), the user can make the window very big, which might increase
0156  * the rendering time considerable.
0157  *
0158  * @todo Use <tt>QSignalBlocker</tt> instead of m_updateIsRunning in
0159  * ColorDialog. Attention: The connection alpha-slider and alpha-spinbox
0160  * is special and would not work anymore, which has to be fixed.
0161  *
0162  * @todo In KDE’s systemsettings, in the “Fonts” settings, there are small
0163  * buttons showing a “i” symbol (for “information”) that has no functionality,
0164  * but a tooltip for the widget at the left. Would this be also good for
0165  * @ref ColorDialog?
0166  *
0167  * @todo Recently KDE merged something that displays tooltips and integrates a
0168  * link that calls the <tt>QWhatsThis</tt> which has more information. Would
0169  * this be helpful here also?
0170  *
0171  * @todo Since August 2021 <a href="https://phabricator.kde.org/T9460">the
0172  * Breeze styling of spin boxes has changed</a>. Is or should be the
0173  * new default horizontal alignment “center”?
0174  *
0175  * @todo Make sure that @ref ChromaHueDiagram always shows at least at the
0176  * central physical pixel with an in-gamut color. Solution: Limit the range
0177  * of the lightness selector? Or a better algorithm in @ref ChromaHueDiagram?
0178  *
0179  * @todo Provide (on demand) two patches, like Scribus also does: One for the
0180  * old color (cannot be modified by the user) and another one for the new
0181  * color (same behavior as the yet existing color patch). One could be
0182  * named “before” and the other “after”. Or maybe make this configurable?
0183  * And put an arrow between the patches, from “before” to “after”. (Be aware:
0184  * RTL support necessary!)
0185  *
0186  * @section uireview Review of the user interface
0187  *
0188  * @todo The HLC widget accepts values that are out-of-gamut; the dialog
0189  * shows the nearest in-gamut color during this moment. Also, the RGB Hex
0190  * widget accepts intermediatly invalid values (for example, 4-digit-values);
0191  * the dialog displays the last previously displayed valid color during
0192  * this moment. Those two situations do not have consiteend behaviour,
0193  * but there are no good alternatives. However: Would it make sense to
0194  * keep this behaviour, but display in the @ref ColorPatch an empty
0195  * value during editing an out-of-gamut HLC value or an invalid RGB Hex values?
0196  *
0197  * @todo For the tab widget, use rather icons instead of the text “hue-baded”
0198  * and “lightness-based”!?
0199  *
0200  * @todo Provide more <tt>tooltip()</tt> help for widgets. For
0201  * @ref WheelColorPicker and @ref ChromaLightnessDiagram, this
0202  * help text could describe the keyboard controls and be integrated
0203  * as default value in the class itself. For the other widgets, a
0204  * help text could be defined here within <em>this</em> class,
0205  * if appropriate.
0206  *
0207  * @todo Touch screen compatibility: In general: What would mean better
0208  * support for touch-screen and convertible? More things to do? For example,
0209  * A spin box can also be used on mobile phone (putting the numbers
0210  * with on-screen keyboard). But the + and - button for increasing
0211  * or decreasing the values might be too small. And mobile UI uses
0212  * often wheels for this use case…
0213  *
0214  * @section additionalcolordialogfeatures Proposals for additional features
0215  *
0216  * @todo The QLineEdit for the hexadecimal RGB values should change lower-case
0217  * letters on-the-fly (as-you-type) to upper-case letters. And: Maybe it
0218  * could even be switched to @ref MultiSpinBox (but that would mean implement
0219  * support for hexadecimal digits in @ref MultiSpinBox).
0220  *
0221  * @todo Accept <tt>F5</tt> and <tt>Ctrl+R</tt> just with the same
0222  * functionality as the gamut button in the HCL @ref MultiSpinBox.
0223  * But attention: If a library user <em>embeds</em> the dialog, he does
0224  * not want his shortcuts to be intercepted!
0225  *
0226  * @todo It might be nice to support keyboard shortcuts for switching tabs
0227  * like in browsers, which is a concept many users might be familiar to.
0228  * Crtl+Tab to switch to the next tab in the list. Crtl+Shift+Tab to switch
0229  * to the previous tab in the list.
0230  *
0231  * @todo Start with dialog with Qt::yellow. You get HLC 100° 98% 95.
0232  * Push the apply button. Actual result: HLC 100° 98% 94 which has a slightly
0233  * different chroma value. Expected result: Ideally there would be no rounding
0234  * difference at all: Every once displayed value is always recognized as
0235  * valid. When the color space conversion takes place, we could (and should)
0236  * make this sure for HLC values. But then comes the also the rounding
0237  * in @ref MultiSpinBox. Is there any solution?
0238  *
0239  * @todo If there is no alpha widget <em>and</em> the actual layout is
0240  * expanded (either explicitly by @ref DialogLayoutDimensions::Expanded
0241  * or implicitly by @ref DialogLayoutDimensions::ScreenSizeDependent on
0242  * bigger screens) <em>than</em> it would make sense to move
0243  * the @ref ColorDialogPrivate::m_buttonBox into the same column as
0244  * the @ref ColorDialogPrivate::m_numericalWidget, namely <em>below</em>
0245  * the @ref ColorDialogPrivate::m_numericalWidget. This saves screen
0246  * space and does not confuse the user.
0247  *
0248  * @todo Provide an overloaded version of @ref open() that accepts
0249  * arguments for new-style connect statements, making use of compiler
0250  * checks.
0251  *
0252  * @todo Use the <em>actual</em> color profile of the monitor.
0253  *
0254  * @todo The LCh-hue (and so the graphical widgets) jumps forward and backward
0255  * when changing RGB-based values (also HSV) when entering and leaving the gray
0256  * axis, due to lack of hue information. Would it be an option to store the
0257  * old hue to get a meaningful hue?
0258  * Should it be only really for the gray axis, or allow a certain tolerance
0259  * around the gray axis is necessary to make this work well - and if so,
0260  * how much tolerance? Would it be useful to define a certain hue, for
0261  * example 0°, as default hue for when no old hue is available but the
0262  * new value is on the gray axis?
0263  *
0264  * @todo Custom layout management that has a specific height-per-width ratio
0265  * considering the @ref ChromaHueDiagram and and @ref WheelColorPicker
0266  * and <em>their</em> useful height-per-width ratio.
0267  *
0268  * @todo Support for other models like HSL (HSB is yet identical to HSV?),
0269  * Munsell? With an option to enable or disable them? (NCS not, because
0270  * it is not free…)
0271  *
0272  * @todo Would CMYK support make sense? Would it integrate intuitively into
0273  * the user interface? If we would have CMYK support, we would have two
0274  * different profiles (RGB and CMYK) active simultaniously. Which one is the
0275  * profile that defines the available color space? Would this be intuitive?
0276  * Also, when using two different profiles, it will be possible to have
0277  * out-of-gamut colors in one of the profiles. How to represent this in the
0278  * UI?
0279  *
0280  * @todo Provide more palettes in our swatch books? Include there a palette
0281  * with QColorDialog’s standard colors as RGB values without
0282  * a specific color space, with the name “Default”? Add
0283  * <a href="https://www.w3.org/TR/css-color-4/#named-colors">CSS colors</a>
0284  * as defined as sRGB values?
0285  * <a href="https://en.wikipedia.org/wiki/Web_colors#Web-safe_colors">
0286  * Web-safe colors</a> (but with another name, maybe “216 colors”)
0287  * as bigger palette, without a specific color space – does
0288  * not make sense, since we provide a perceptual color dialog,
0289  * which allows things much beyond 216 colors, and 216 colors
0290  * isn’t a useful standard anymore, and not a nice palette either.
0291  *
0292  * @todo Discrete widgets, that have
0293  * a fixed (quite limited) number of fields to chose for the user?
0294  */
0295 class PERCEPTUALCOLOR_IMPORTEXPORT ColorDialog : public QDialog
0296 {
0297     Q_OBJECT
0298 
0299     /** @brief Currently selected color in the dialog
0300      *
0301      * @invariant This property is provided as an RGB value.
0302      * <tt>QColor::isValid()</tt> is always <tt>true</tt> and
0303      * <tt>QColor::spec()</tt> is always <tt>QColor::Spec::Rgb</tt>.
0304      *
0305      * @invariant The signal @ref currentColorChanged() is emitted always and
0306      * only when the value of this property changes.
0307      *
0308      * @note The setter @ref setCurrentColor() does not accept all QColor
0309      * values. See its documentation for details.
0310      *
0311      * @sa READ @ref currentColor() const
0312      * @sa WRITE @ref setCurrentColor()
0313      * @sa NOTIFY @ref currentColorChanged()
0314      *
0315      * @internal
0316      *
0317      * @note This property does not have <tt>USER true</tt>. While it would
0318      * be nice to have it, we do not do this because of conformance with
0319      * QColorDialog, which doesn’t have it either. */
0320     Q_PROPERTY(QColor currentColor READ currentColor WRITE setCurrentColor NOTIFY currentColorChanged)
0321 
0322     /** @brief Layout dimensions
0323      *
0324      * Defines if the dialog uses a rather collapsed (small) or a rather
0325      * expanded (large) layout. In both cases, all elements are present.
0326      * But for the collapsed variant, more elements are put in
0327      * tab widgets, while for the expanded variant, more elements are
0328      * visible at the same time.
0329      *
0330      * @image html ColorDialogCollapsed.png "collapsed" height=300
0331      * @image html ColorDialogExpanded.png "expanded" height=300
0332      *
0333      * Default value:
0334      * @snippet src/colordialog_p.h layoutDimensionsDefaultValue
0335      *
0336      * When the layout dimension effectively changes, also the dialog size
0337      * is adapted.
0338      *
0339      * @sa @ref DialogLayoutDimensions
0340      * @sa READ @ref layoutDimensions() const
0341      * @sa WRITE @ref setLayoutDimensions()
0342      * @sa NOTIFY @ref layoutDimensionsChanged
0343      *
0344      * @internal
0345      *
0346      * @sa @ref ColorDialogPrivate::m_layoutDimensionsEffective
0347      *
0348      * @todo Remove this property? Instead, implement a truly convertible
0349      * layout: Show/hide the widget for numbers depending on dialog size,
0350      * and maybe even re-arrange even more of the widgets with varying
0351      * sizes. */
0352     Q_PROPERTY(DialogLayoutDimensions layoutDimensions READ layoutDimensions WRITE setLayoutDimensions NOTIFY layoutDimensionsChanged)
0353 
0354     /** @brief Various options that affect the look and feel of the dialog
0355      *
0356      * These are the same settings as for QColorDialog. For compatibility
0357      * reasons, they are also of the same type: @ref ColorDialogOptions
0358      *
0359      * | Option              | Default value | Description
0360      * | :------------------ | :------------ | :----------
0361      * | ShowAlphaChannel    | false         | Allow the user to select the alpha component of a color.
0362      * | NoButtons           | false         | Don't display OK and Cancel buttons. (Useful for “live dialogs”.)
0363      * | DontUseNativeDialog | true          | Use Qt’s standard color dialog instead of the operating system native color dialog.
0364      *
0365      *   @invariant The option <tt>ColorDialogOption::DontUseNativeDialog</tt>
0366      *   will always be <tt>true</tt> because it’s just the point of
0367      *   this library to provide an own, non-native dialog. (If you
0368      *   set  <tt>ColorDialogOption::DontUseNativeDialog</tt> explicitly
0369      *   to <tt>false</tt>, this will silently be ignored, while the
0370      *   other options that you might have set, will be correctly applied.)
0371      *
0372      * Example:
0373      * @snippet testcolordialog.cpp setOptionsWithLocalEnum
0374      * Or:
0375      * @snippet testcolordialog.cpp setOptionsWithQColorDialogEnum
0376      * @note At difference to QColorDialog, you need a fully qualified
0377      * identifier for the enum values. The following code would therefore
0378      * fail:<br/>
0379      * <tt>myDialog->setOption(ShowAlphaChannel, false);</tt>
0380      *
0381      * @sa READ @ref options() const
0382      * @sa @ref testOption()
0383      * @sa WRITE @ref setOptions()
0384      * @sa @ref setOption()
0385      * @sa NOTIFY @ref optionsChanged()*/
0386     Q_PROPERTY(ColorDialogOptions options READ options WRITE setOptions NOTIFY optionsChanged)
0387 
0388 public:
0389     /** @brief Local alias for QColorDialog::ColorDialogOption
0390      *
0391      * This type is declared as type to Qt’s type system via
0392      * <tt>Q_DECLARE_METATYPE</tt>. Depending on your use case (for
0393      * example if you want to use for <em>queued</em> signal-slot connections),
0394      * you might consider calling <tt>qRegisterMetaType()</tt> for
0395      * this type, once you have a QApplication object. */
0396     typedef QColorDialog::ColorDialogOption ColorDialogOption;
0397     /** @brief Local alias for QColorDialog::ColorDialogOptions
0398      *
0399      * This type is declared as type to Qt’s type system via
0400      * <tt>Q_DECLARE_METATYPE</tt>. Depending on your use case (for
0401      * example if you want to use for <em>queued</em> signal-slot connections),
0402      * you might consider calling <tt>qRegisterMetaType()</tt> for
0403      * this type, once you have a QApplication object. */
0404     typedef QColorDialog::ColorDialogOptions ColorDialogOptions;
0405     /** @brief Layout dimensions
0406      *
0407      * This enum is declared to the meta-object system with <tt>Q_ENUM</tt>.
0408      * This happens automatically. You do not need to make any manual calls.
0409      *
0410      * This type is declared as type to Qt’s type system via
0411      * <tt>Q_DECLARE_METATYPE</tt>. Depending on your use case (for
0412      * example if you want to use for <em>queued</em> signal-slot connections),
0413      * you might consider calling <tt>qRegisterMetaType()</tt> for
0414      * this type, once you have a QApplication object. */
0415     enum class DialogLayoutDimensions {
0416         ScreenSizeDependent, /**< Decide automatically between
0417             <tt>collapsed</tt> and <tt>expanded</tt> layout: <tt>collapsed</tt>
0418             is used on small screens, and <tt>expanded</tt> on big screens. The
0419             decision is based on the screen size of the <em>default screen</em>
0420             of the widget (see <tt>QGuiApplication::primaryScreen()</tt> for
0421             details). The decision is evaluated at the moment when setting this
0422             value, and again each time the widget is shown again. It is
0423             <em>not</em> evaluated again when a yet existing dialog is just
0424             moved to another screen. */
0425         Collapsed, /**< Use the small, “collapsed“ layout of this dialog. */
0426         Expanded /**< Use the large, “expanded” layout of this dialog.  */
0427     };
0428     Q_ENUM(DialogLayoutDimensions)
0429     Q_INVOKABLE explicit ColorDialog(QWidget *parent = nullptr);
0430     Q_INVOKABLE explicit ColorDialog(const QColor &initial, QWidget *parent = nullptr);
0431     Q_INVOKABLE explicit ColorDialog(const QSharedPointer<PerceptualColor::RgbColorSpace> &colorSpace, QWidget *parent = nullptr);
0432     Q_INVOKABLE explicit ColorDialog(const QSharedPointer<PerceptualColor::RgbColorSpace> &colorSpace, const QColor &initial, QWidget *parent = nullptr);
0433     virtual ~ColorDialog() noexcept override;
0434     /** @brief Getter for property @ref currentColor
0435      *  @returns the property @ref currentColor */
0436     [[nodiscard]] QColor currentColor() const;
0437     [[nodiscard]] static QColor
0438     getColor(const QColor &initial = Qt::white, QWidget *parent = nullptr, const QString &title = QString(), ColorDialogOptions options = ColorDialogOptions());
0439     [[nodiscard]] static QColor getColor(const QSharedPointer<PerceptualColor::RgbColorSpace> &colorSpace,
0440                                          const QColor &initial = Qt::white,
0441                                          QWidget *parent = nullptr,
0442                                          const QString &title = QString(),
0443                                          ColorDialogOptions options = ColorDialogOptions());
0444     /** @brief Getter for property @ref layoutDimensions
0445      *  @returns the property @ref layoutDimensions */
0446     [[nodiscard]] ColorDialog::DialogLayoutDimensions layoutDimensions() const;
0447     // Make sure not to override the base class’s “open“ function:
0448     using QDialog::open;
0449     Q_INVOKABLE void open(QObject *receiver, const char *member);
0450     /** @brief Getter for property @ref options
0451      * @returns the current @ref options */
0452     [[nodiscard]] ColorDialogOptions options() const;
0453     [[nodiscard]] Q_INVOKABLE QColor selectedColor() const;
0454     virtual void setVisible(bool visible) override;
0455     [[nodiscard]] Q_INVOKABLE bool testOption(PerceptualColor::ColorDialog::ColorDialogOption option) const;
0456 
0457 public Q_SLOTS:
0458     void setCurrentColor(const QColor &color);
0459     void setLayoutDimensions(const PerceptualColor::ColorDialog::DialogLayoutDimensions newLayoutDimensions);
0460     Q_INVOKABLE void setOption(PerceptualColor::ColorDialog::ColorDialogOption option, bool on = true);
0461     void setOptions(PerceptualColor::ColorDialog::ColorDialogOptions newOptions);
0462 
0463 Q_SIGNALS:
0464     /** @brief This signal is emitted just after the user has clicked OK to
0465      * select a color to use.
0466      *  @param color the chosen color */
0467     void colorSelected(const QColor &color);
0468     /** @brief Notify signal for property @ref currentColor.
0469      *
0470      * This signal is emitted whenever the “current color” changes in the
0471      * dialog.
0472      * @param color the new “current color” */
0473     void currentColorChanged(const QColor &color);
0474     /** @brief Notify signal for property @ref layoutDimensions.
0475      * @param newLayoutDimensions the new layout dimensions */
0476     void layoutDimensionsChanged(const PerceptualColor::ColorDialog::DialogLayoutDimensions newLayoutDimensions);
0477     /** @brief Notify signal for property @ref options.
0478      * @param newOptions the new options */
0479     void optionsChanged(const PerceptualColor::ColorDialog::ColorDialogOptions newOptions);
0480 
0481 protected:
0482     virtual void changeEvent(QEvent *event) override;
0483     virtual void done(int result) override;
0484     virtual void showEvent(QShowEvent *event) override;
0485 
0486 private:
0487     Q_DISABLE_COPY(ColorDialog)
0488 
0489     /** @internal
0490      *
0491      * @brief Declare the private implementation as friend class.
0492      *
0493      * This allows the private class to access the protected members and
0494      * functions of instances of <em>this</em> class. */
0495     friend class ColorDialogPrivate;
0496     /** @brief Pointer to implementation (pimpl) */
0497     ConstPropagatingUniquePointer<ColorDialogPrivate> d_pointer;
0498 
0499     /** @internal @brief Only for unit tests. */
0500     friend class TestColorDialog;
0501 };
0502 
0503 } // namespace PerceptualColor
0504 
0505 Q_DECLARE_METATYPE(PerceptualColor::ColorDialog::ColorDialogOption)
0506 Q_DECLARE_METATYPE(PerceptualColor::ColorDialog::ColorDialogOptions)
0507 Q_DECLARE_METATYPE(PerceptualColor::ColorDialog::DialogLayoutDimensions)
0508 
0509 #endif // COLORDIALOG_H