6#include "colordialog.h"
8#include "colordialog_p.h"
10#include "absolutecolor.h"
11#include "chromahuediagram.h"
12#include "cielchd50values.h"
13#include "colorpatch.h"
14#include "constpropagatingrawpointer.h"
15#include "constpropagatinguniquepointer.h"
16#include "gradientslider.h"
18#include "helperconstants.h"
19#include "helperconversion.h"
20#include "helperqttypes.h"
21#include "initializetranslation.h"
22#include "multispinbox.h"
23#include "multispinboxsection.h"
24#include "oklchvalues.h"
26#include "rgbcolorspace.h"
27#include "rgbcolorspacefactory.h"
28#include "screencolorpicker.h"
30#include "swatchbook.h"
31#include "wheelcolorpicker.h"
36#include <qapplication.h>
37#include <qboxlayout.h>
38#include <qbytearray.h>
41#include <qcoreapplication.h>
42#include <qcoreevent.h>
45#include <qdialogbuttonbox.h>
46#include <qfontmetrics.h>
47#include <qformlayout.h>
48#include <qgridlayout.h>
50#include <qguiapplication.h>
52#include <qkeysequence.h>
60#include <qpushbutton.h>
61#include <qregularexpression.h>
62#include <qscopedpointer.h>
64#include <qsharedpointer.h>
67#include <qsizepolicy.h>
69#include <qstackedlayout.h>
70#include <qstringbuilder.h>
71#include <qstringliteral.h>
72#include <qtabwidget.h>
73#include <qtoolbutton.h>
74#include <qvalidator.h>
75#include <qversionnumber.h>
80#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
81#include <qcontainerfwd.h>
82#include <qobjectdefs.h>
84#include <qstringlist.h>
87#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
88#include <qstylehints.h>
101QString ColorDialogPrivate::translateColorModel(cmsColorSpaceSignature model)
116 case cmsSigYCbCrData:
137 case cmsSigNamedData:
138 case cmsSig2colorData:
139 case cmsSig3colorData:
140 case cmsSig4colorData:
141 case cmsSig5colorData:
142 case cmsSig6colorData:
143 case cmsSig7colorData:
144 case cmsSig8colorData:
145 case cmsSig9colorData:
146 case cmsSig10colorData:
147 case cmsSig11colorData:
148 case cmsSig12colorData:
149 case cmsSig13colorData:
150 case cmsSig14colorData:
151 case cmsSig15colorData:
154 case cmsSig1colorData:
207void ColorDialogPrivate::retranslateUi()
210 const QPair<QString, QString> percentageInSpinbox =
211 getPrefixSuffix(
tr(
"%1%"));
214 const QPair<QString, QString> arcDegreeInSpinbox =
215 getPrefixSuffix(
tr(
"%1°"));
219 m_rgbColorSpace->profileName().toHtmlEscaped();
223 profileInfo.
append(tableRow.
arg(
tr(
"Name:"), name));
226 const QString maximumCielchD50Chroma =
227 tr(
"%L1 (estimated)")
228 .
arg(m_rgbColorSpace->profileMaximumCielchD50Chroma(),
235 tableRow.
arg(
tr(
"Maximum CIELCh-D50 chroma:"), maximumCielchD50Chroma));
237 const QString maximumOklchChroma =
238 tr(
"%L1 (estimated)")
239 .
arg(m_rgbColorSpace->profileMaximumOklchChroma(),
246 tableRow.
arg(
tr(
"Maximum Oklch chroma:"), maximumOklchChroma));
248 switch (m_rgbColorSpace->profileClass()) {
249 case cmsSigDisplayClass:
251 profileClass =
tr(
"Display profile");
253 case cmsSigAbstractClass:
258 case cmsSigColorSpaceClass:
259 case cmsSigInputClass:
260 case cmsSigLinkClass:
261 case cmsSigNamedColorClass:
262 case cmsSigOutputClass:
270 tableRow.
arg(
tr(
"Profile class:"), profileClass));
273 translateColorModel(m_rgbColorSpace->profileColorModel());
279 profileInfo.
append(tableRow.
arg(
tr(
"Color model:"), colorModel));
282 m_rgbColorSpace->profileManufacturer().toHtmlEscaped();
288 profileInfo.
append(tableRow.
arg(
tr(
"Manufacturer:"), manufacturer));
291 m_rgbColorSpace->profileModel().toHtmlEscaped();
297 profileInfo.
append(tableRow.
arg(
tr(
"Device model:"), (model)));
300 m_rgbColorSpace->profileCreationDateTime();
301 if (!creationDateTime.
isNull()) {
311 tableRow.
arg(
tr(
"Created:"), (creationDateTimeString)));
313 const QVersionNumber iccVersion = m_rgbColorSpace->profileIccVersion();
319 const bool hasMatrixShaper =
320 m_rgbColorSpace->profileHasMatrixShaper();
322 m_rgbColorSpace->profileHasClut();
323 if (hasMatrixShaper || hasClut) {
324 const QString matrixShaperString = tableRow.
arg(
329 tr(
"Implementation:"));
330 if (hasMatrixShaper && hasClut) {
336 matrixShaperString.
arg(
tr(
"Matrices and color lookup tables")));
337 }
else if (hasMatrixShaper) {
342 profileInfo.
append(matrixShaperString.
arg(
tr(
"Matrices")));
343 }
else if (hasClut) {
349 matrixShaperString.
arg(
tr(
"Color lookup tables")));
352 const QString pcsColorModelText =
353 translateColorModel(m_rgbColorSpace->profilePcsColorModel());
354 if (!pcsColorModelText.
isEmpty()) {
360 tableRow.
arg(
tr(
"PCS color model:"), pcsColorModelText));
362 const QString copyright = m_rgbColorSpace->profileCopyright();
367 profileInfo.
append(tableRow.
arg(
tr(
"Copyright:"), copyright));
369 const qint64 fileSize =
370 m_rgbColorSpace->profileFileSize();
376 QLocale().formattedDataSize(fileSize)));
379 m_rgbColorSpace->profileAbsoluteFilePath();
383 profileInfo.
append(tableRow.
arg(
tr(
"File name:"), fileName));
386 m_rgbGroupBox->setToolTip(
QString());
388 const QString tableString = QStringLiteral(
390 "<table border=\"0\" cellpadding=\"2\" cellspacing=\"0\">"
393 m_rgbGroupBox->setToolTip(richTextMarker
399 tr(
"Color space information"),
405 m_ciehlcD50SpinBoxLabel->setText(
tr(
"CIEHL&C D50:"));
409 m_oklchSpinBoxLabel->setText(
tr(
"O&klch:"));
412 m_rgbSpinBoxLabel->setText(
tr(
"&RGB:"));
415 m_rgbLineEditLabel->setText(
tr(
"He&x:"));
417 const int swatchBookIndex = m_tabWidget->indexOf(m_swatchBookWrapperWidget);
418 if (swatchBookIndex >= 0) {
421 const auto mnemonic =
tr(
"&Swatch book");
422 m_tabWidget->setTabToolTip(
424 richTextMarker + fromMnemonicToRichText(mnemonic));
428 const int hueFirstIndex = m_tabWidget->indexOf(m_hueFirstWrapperWidget);
429 if (hueFirstIndex >= 0) {
433 const auto mnemonic =
tr(
"&Hue-based");
434 m_tabWidget->setTabToolTip(
436 richTextMarker + fromMnemonicToRichText(mnemonic));
439 const int lightnessFirstIndex =
440 m_tabWidget->indexOf(m_lightnessFirstWrapperWidget);
441 if (lightnessFirstIndex >= 0) {
447 const auto mnemonic =
tr(
"&Lightness-based");
448 m_tabWidget->setTabToolTip(
450 richTextMarker + fromMnemonicToRichText(mnemonic));
453 const int numericIndex =
454 m_tabWidget->indexOf(m_numericalWidget);
455 if (numericIndex >= 0) {
459 const auto mnemonic =
tr(
"&Numeric");
460 m_tabWidget->setTabToolTip(
462 richTextMarker + fromMnemonicToRichText(mnemonic));
467 m_hslSpinBoxLabel->setText(
tr(
"HS&L:"));
471 m_hsvSpinBoxLabel->setText(
tr(
"HS&V/HSB:"));
474 m_hwbSpinBoxLabel->setText(
tr(
"H&WB:"));
477 m_buttonOK->setText(
tr(
"&OK"));
480 m_buttonCancel->setText(
tr(
"&Cancel"));
482 m_rgbSpinBox->setToolTip(
484 +
tr(
"<p>Red: 0–255</p>"
485 "<p>Green: 0–255</p>"
486 "<p>Blue: 0–255</p>"));
489 m_rgbLineEdit->setToolTip(
491 +
tr(
"<p>Hexadecimal color code, as used in HTML: #RRGGBB</p>"
492 "<p>RR: two-digit code for red: 00–FF</p>"
493 "<p>GG: two-digit code for green: 00–FF</p>"
494 "<p>BB: two-digit code for blue: 00–FF</p>"));
503 m_hslSpinBox->setToolTip(richTextMarker
504 +
tr(
"<p>Hue: 0°–360°</p>"
505 "<p>HSL-Saturation: 0%–100%</p>"
506 "<p>Lightness: 0%–100%</p>"));
517 m_hwbSpinBox->setToolTip(richTextMarker
518 +
tr(
"<p>Hue: 0°–360°</p>"
519 "<p>Whiteness: 0%–100%</p>"
520 "<p>Blackness: 0%–100%</p>"));
530 m_hsvSpinBox->setToolTip(richTextMarker
531 +
tr(
"<p>Hue: 0°–360°</p>"
532 "<p>HSV/HSB-Saturation: 0%–100%</p>"
533 "<p>Brightness/Value: 0%–100%</p>"));
535 m_alphaSpinBox->setPrefix(percentageInSpinbox.first);
536 m_alphaSpinBox->setSuffix(percentageInSpinbox.second);
541 m_lchLightnessSelector->setAccessibleName(
tr(
"Lightness"));
545 m_ciehlcD50SpinBox->setToolTip(richTextMarker
546 +
tr(
"<p>Hue: 0°–360°</p>"
547 "<p>Lightness: 0%–100%</p>"
548 "<p>Chroma: 0–%L1</p>")
549 .arg(CielchD50Values::maximumChroma));
551 constexpr double maxOklchChroma = OklchValues::maximumChroma;
554 m_oklchSpinBox->setToolTip(richTextMarker
555 +
tr(
"<p>Lightness: %L1–%L2</p>"
556 "<p>Chroma: %L3–%L4</p>"
557 "<p>Hue: 0°–360°</p>"
558 "<p>Whitepoint: D65</p>")
559 .arg(0., 0,
'f', okdecimals)
560 .arg(1., 0,
'f', okdecimals)
561 .arg(0., 0,
'f', okdecimals)
562 .arg(maxOklchChroma, 0,
'f', okdecimals));
568 const QString opacityLabel =
tr(
"Op&acity:");
569 m_alphaGradientSlider->setAccessibleName(opacityLabel);
570 m_alphaLabel->setText(opacityLabel);
574 m_hslSpinBox->sectionConfigurations();
575 if (hslSections.
count() != 3) {
577 <<
"Expected 3 sections in HSV MultiSpinBox, but got"
578 << hslSections.
count()
579 <<
"instead. This is a bug in libperceptualcolor.";
581 hslSections[0].setPrefix(arcDegreeInSpinbox.first);
582 hslSections[0].setSuffix(
583 arcDegreeInSpinbox.second + m_multispinboxSectionSeparator);
584 hslSections[1].setPrefix(
585 m_multispinboxSectionSeparator + percentageInSpinbox.first);
586 hslSections[1].setSuffix(
587 percentageInSpinbox.second + m_multispinboxSectionSeparator);
588 hslSections[2].setPrefix(
589 m_multispinboxSectionSeparator + percentageInSpinbox.first);
590 hslSections[2].setSuffix(percentageInSpinbox.second);
591 m_hslSpinBox->setSectionConfigurations(hslSections);
596 m_hwbSpinBox->sectionConfigurations();
597 if (hwbSections.
count() != 3) {
599 <<
"Expected 3 sections in HSV MultiSpinBox, but got"
600 << hwbSections.
count()
601 <<
"instead. This is a bug in libperceptualcolor.";
603 hwbSections[0].setPrefix(arcDegreeInSpinbox.first);
604 hwbSections[0].setSuffix(
605 arcDegreeInSpinbox.second + m_multispinboxSectionSeparator);
606 hwbSections[1].setPrefix(
607 m_multispinboxSectionSeparator + percentageInSpinbox.first);
608 hwbSections[1].setSuffix(
609 percentageInSpinbox.second + m_multispinboxSectionSeparator);
610 hwbSections[2].setPrefix(
611 m_multispinboxSectionSeparator + percentageInSpinbox.first);
612 hwbSections[2].setSuffix(
613 percentageInSpinbox.second);
614 m_hwbSpinBox->setSectionConfigurations(hwbSections);
619 m_hsvSpinBox->sectionConfigurations();
620 if (hsvSections.
count() != 3) {
622 <<
"Expected 3 sections in HSV MultiSpinBox, but got"
623 << hsvSections.
count()
624 <<
"instead. This is a bug in libperceptualcolor.";
626 hsvSections[0].setPrefix(arcDegreeInSpinbox.first);
627 hsvSections[0].setSuffix(
628 arcDegreeInSpinbox.second + m_multispinboxSectionSeparator);
629 hsvSections[1].setPrefix(
630 m_multispinboxSectionSeparator + percentageInSpinbox.first);
631 hsvSections[1].setSuffix(
632 percentageInSpinbox.second + m_multispinboxSectionSeparator);
633 hsvSections[2].setPrefix(
634 m_multispinboxSectionSeparator + percentageInSpinbox.first);
635 hsvSections[2].setSuffix(percentageInSpinbox.second);
636 m_hsvSpinBox->setSectionConfigurations(hsvSections);
641 m_ciehlcD50SpinBox->sectionConfigurations();
642 if (ciehlcD50Sections.
count() != 3) {
644 <<
"Expected 3 sections in HLC MultiSpinBox, but got"
645 << ciehlcD50Sections.
count()
646 <<
"instead. This is a bug in libperceptualcolor.";
648 ciehlcD50Sections[0].setPrefix(arcDegreeInSpinbox.first);
649 ciehlcD50Sections[0].setSuffix(
650 arcDegreeInSpinbox.second + m_multispinboxSectionSeparator);
651 ciehlcD50Sections[1].setPrefix(
652 m_multispinboxSectionSeparator + percentageInSpinbox.first);
653 ciehlcD50Sections[1].setSuffix(
654 percentageInSpinbox.second + m_multispinboxSectionSeparator);
655 ciehlcD50Sections[2].setPrefix(m_multispinboxSectionSeparator);
656 ciehlcD50Sections[2].setSuffix(
QString());
657 m_ciehlcD50SpinBox->setSectionConfigurations(ciehlcD50Sections);
662 m_oklchSpinBox->sectionConfigurations();
663 if (oklchSections.
count() != 3) {
665 <<
"Expected 3 sections in HLC MultiSpinBox, but got"
666 << oklchSections.
count()
667 <<
"instead. This is a bug in libperceptualcolor.";
669 oklchSections[0].setPrefix(
QString());
670 oklchSections[0].setSuffix(m_multispinboxSectionSeparator);
671 oklchSections[1].setPrefix(m_multispinboxSectionSeparator);
672 oklchSections[1].setSuffix(m_multispinboxSectionSeparator);
673 oklchSections[2].setPrefix(
674 m_multispinboxSectionSeparator + arcDegreeInSpinbox.first);
675 oklchSections[2].setSuffix(arcDegreeInSpinbox.second);
676 m_oklchSpinBox->setSectionConfigurations(oklchSections);
679 if (m_screenColorPickerButton) {
684 const auto mnemonic =
tr(
"&Pick screen color");
685 m_screenColorPickerButton->setToolTip(
686 richTextMarker + fromMnemonicToRichText(mnemonic));
687 m_screenColorPickerButton->setShortcut(
696 const auto gamutMnemonic =
697 tr(
"Click to snap to nearest in-&gamut color");
699 richTextMarker + fromMnemonicToRichText(gamutMnemonic);
701 m_ciehlcD50SpinBoxGamutAction->setToolTip(gamutTooltip);
702 m_ciehlcD50SpinBoxGamutAction->setShortcut(gamutShortcut);
703 m_oklchSpinBoxGamutAction->setToolTip(gamutTooltip);
704 m_oklchSpinBoxGamutAction->setShortcut(gamutShortcut);
709 m_swatchBookSelector->setItemText(0,
tr(
"Basic colors"));
714 m_swatchBookSelector->setItemText(1,
tr(
"History"));
734void ColorDialogPrivate::reloadIcons()
737 label->setText(QStringLiteral(
"abc"));
742 m_currentIconThemeType = newType;
745 {QStringLiteral(
"paint-swatch"),
748 QStringLiteral(
"palette"),
749 QStringLiteral(
"palette-symbolic")};
750 const int swatchBookIndex =
751 m_tabWidget->indexOf(m_swatchBookWrapperWidget);
752 if (swatchBookIndex >= 0) {
753 m_tabWidget->setTabIcon(swatchBookIndex,
754 qIconFromTheme(swatchBookIcons,
755 QStringLiteral(
"color-swatch"),
761 QStringLiteral(
"color-mode-hue-shift-positive"),
763 const int hueFirstIndex =
764 m_tabWidget->indexOf(m_hueFirstWrapperWidget);
765 if (hueFirstIndex >= 0) {
766 m_tabWidget->setTabIcon(hueFirstIndex,
767 qIconFromTheme(hueFirstIcons,
768 QStringLiteral(
"steering-wheel"),
774 QStringLiteral(
"brightness-high"),
776 const int lightnessFirstIndex =
777 m_tabWidget->indexOf(m_lightnessFirstWrapperWidget);
778 if (lightnessFirstIndex >= 0) {
779 m_tabWidget->setTabIcon(lightnessFirstIndex,
780 qIconFromTheme(lightnessFirstIcons,
781 QStringLiteral(
"brightness-2"),
787 QStringLiteral(
"black_sum"),
789 const int numericIndex =
790 m_tabWidget->indexOf(m_numericalWidget);
791 if (numericIndex >= 0) {
792 m_tabWidget->setTabIcon(numericIndex,
793 qIconFromTheme(numericIcons,
794 QStringLiteral(
"123"),
801 QStringLiteral(
"data-warning"),
802 QStringLiteral(
"dialog-warning-symbolic"),
804 const QIcon gamutIcon = qIconFromTheme(gamutIconNames,
805 QStringLiteral(
"eye-exclamation"),
807 m_ciehlcD50SpinBoxGamutAction->setIcon(gamutIcon);
808 m_oklchSpinBoxGamutAction->setIcon(gamutIcon);
812 QStringLiteral(
"color-picker"),
813 QStringLiteral(
"gtk-color-picker"),
814 QStringLiteral(
"tool_color_picker"),
816 if (!m_screenColorPickerButton.
isNull()) {
817 m_screenColorPickerButton->setIcon(
818 qIconFromTheme(candidates,
819 QStringLiteral(
"color-picker"),
845 m_rgbColorSpace = colorSpace;
847 m_wcsBasicDefaultColor = m_wcsBasicColors.value(4, 2);
850 m_swatchBookBasicColors =
new SwatchBook(m_rgbColorSpace,
852 Qt::Orientation::Horizontal);
853 auto swatchBookBasicColorsLayout =
new QGridLayout();
854 auto swatchBookBasicColorsLayoutWidget =
new QWidget();
855 swatchBookBasicColorsLayoutWidget->setLayout(swatchBookBasicColorsLayout);
856 swatchBookBasicColorsLayoutWidget->setContentsMargins(0, 0, 0, 0);
857 swatchBookBasicColorsLayout->setContentsMargins(0, 0, 0, 0);
858 swatchBookBasicColorsLayout->addWidget(m_swatchBookBasicColors);
859 swatchBookBasicColorsLayout->setRowStretch(1, 1);
860 swatchBookBasicColorsLayout->setColumnStretch(1, 1);
861 m_swatchBookHistory =
new SwatchBook(m_rgbColorSpace,
863 Qt::Orientation::Vertical);
865 auto swatchBookHistoryLayoutWidget =
new QWidget();
866 swatchBookHistoryLayoutWidget->setLayout(swatchBookHistoryLayout);
867 swatchBookHistoryLayoutWidget->setContentsMargins(0, 0, 0, 0);
868 swatchBookHistoryLayout->setContentsMargins(0, 0, 0, 0);
869 swatchBookHistoryLayout->addWidget(m_swatchBookHistory);
870 swatchBookHistoryLayout->setRowStretch(1, 1);
871 swatchBookHistoryLayout->setColumnStretch(1, 1);
872 loadHistoryFromSettingsToSwatchBook();
874 m_swatchBookStack->addWidget(swatchBookBasicColorsLayoutWidget);
875 m_swatchBookStack->addWidget(swatchBookHistoryLayoutWidget);
877 swatchBookInnerLayout->
addLayout(m_swatchBookStack);
881 m_swatchBookSelector->addItem(
QString());
882 m_swatchBookSelector->addItem(
QString());
889 m_swatchBookStack->setCurrentIndex(0);
890 m_settings.swatchBookPage.setValue(
891 PerceptualSettings::SwatchBookPage::BasicColors);
894 m_swatchBookStack->setCurrentIndex(1);
895 m_settings.swatchBookPage.setValue(
896 PerceptualSettings::SwatchBookPage::History);
900 swatchBookOuterLayout->
addWidget(m_swatchBookSelector);
901 swatchBookOuterLayout->
addLayout(swatchBookInnerLayout);
903 m_swatchBookWrapperWidget =
new QWidget();
904 m_swatchBookWrapperWidget->setLayout(swatchBookOuterLayout);
906 &Setting<PerceptualSettings::ColorList>::valueChanged,
908 &ColorDialogPrivate::loadHistoryFromSettingsToSwatchBook);
909 m_wheelColorPicker =
new WheelColorPicker(m_rgbColorSpace);
910 m_hueFirstWrapperWidget =
new QWidget;
912 tempHueFirstLayout->
addWidget(m_wheelColorPicker);
913 m_hueFirstWrapperWidget->setLayout(tempHueFirstLayout);
915 m_lchLightnessSelector =
new GradientSlider(m_rgbColorSpace);
916 GenericColor blackCielchD50;
917 blackCielchD50.first = 0;
918 blackCielchD50.second = 0;
919 blackCielchD50.third = 0;
920 blackCielchD50.fourth = 1;
921 GenericColor whiteCielchD50;
922 whiteCielchD50.first = 100;
923 whiteCielchD50.second = 0;
924 whiteCielchD50.third = 0;
925 whiteCielchD50.fourth = 1;
926 m_lchLightnessSelector->setColors(blackCielchD50, whiteCielchD50);
927 m_chromaHueDiagram =
new ChromaHueDiagram(m_rgbColorSpace);
929 tempLightnesFirstLayout->
addWidget(m_lchLightnessSelector);
930 tempLightnesFirstLayout->
addWidget(m_chromaHueDiagram);
931 m_lightnessFirstWrapperWidget =
new QWidget();
932 m_lightnessFirstWrapperWidget->setLayout(tempLightnesFirstLayout);
934 initializeScreenColorPicker();
948 m_tabWidget->addTab(m_swatchBookWrapperWidget,
QString());
949 m_swatchBookTabShortcut =
new QShortcut(q_pointer);
950 connect(m_swatchBookTabShortcut,
954 m_tabWidget->setCurrentIndex(
955 m_tabWidget->indexOf(m_swatchBookWrapperWidget));
957 connect(m_swatchBookTabShortcut,
961 m_tabWidget->setCurrentIndex(
962 m_tabWidget->indexOf(m_swatchBookWrapperWidget));
965 m_tabWidget->addTab(m_hueFirstWrapperWidget,
QString());
966 m_hueFirstTabShortcut =
new QShortcut(q_pointer);
971 m_tabWidget->setCurrentIndex(
972 m_tabWidget->indexOf(m_hueFirstWrapperWidget));
978 m_tabWidget->setCurrentIndex(
979 m_tabWidget->indexOf(m_hueFirstWrapperWidget));
982 m_tabWidget->addTab(m_lightnessFirstWrapperWidget,
QString());
983 m_lightnessFirstTabShortcut =
new QShortcut(q_pointer);
984 connect(m_lightnessFirstTabShortcut,
988 m_tabWidget->setCurrentIndex(
989 m_tabWidget->indexOf(m_lightnessFirstWrapperWidget));
991 connect(m_lightnessFirstTabShortcut,
995 m_tabWidget->setCurrentIndex(
996 m_tabWidget->indexOf(m_lightnessFirstWrapperWidget));
999 m_tabTable.
insert(&m_swatchBookWrapperWidget,
1000 QStringLiteral(
"swatch"));
1001 m_tabTable.
insert(&m_hueFirstWrapperWidget,
1002 QStringLiteral(
"hue-based"));
1003 m_tabTable.
insert(&m_lightnessFirstWrapperWidget,
1004 QStringLiteral(
"lightness-based"));
1005 m_tabTable.
insert(&m_numericalWidget,
1006 QStringLiteral(
"numerical"));
1010 &ColorDialogPrivate::saveCurrentTab);
1013 m_colorPatch =
new ColorPatch();
1014 m_colorPatch->setMinimumSize(m_colorPatch->minimumSizeHint() * 1.5);
1017 headerLayout->
addWidget(m_colorPatch, 1);
1020 headerLayout->
addWidget(m_screenColorPickerButton,
1028 m_numericalWidget = initializeNumericPage();
1029 m_numericalTabShortcut =
new QShortcut(q_pointer);
1030 connect(m_numericalTabShortcut,
1034 m_tabWidget->setCurrentIndex(
1035 m_tabWidget->indexOf(m_numericalWidget));
1037 connect(m_numericalTabShortcut,
1041 m_tabWidget->setCurrentIndex(
1042 m_tabWidget->indexOf(m_numericalWidget));
1047 m_selectorLayout->addWidget(m_tabWidget);
1048 m_selectorLayout->addWidget(m_numericalWidget);
1052 m_alphaGradientSlider =
new GradientSlider(m_rgbColorSpace,
1053 Qt::Orientation::Horizontal);
1054 m_alphaGradientSlider->setSingleStep(singleStepAlpha);
1055 m_alphaGradientSlider->setPageStep(pageStepAlpha);
1057 m_alphaSpinBox->setAlignment(Qt::AlignmentFlag::AlignRight);
1058 m_alphaSpinBox->setMinimum(0);
1059 m_alphaSpinBox->setMaximum(100);
1061 m_alphaSpinBox->setDecimals(decimals);
1062 m_alphaSpinBox->setSingleStep(singleStepAlpha * 100);
1065 m_alphaLabel =
new QLabel();
1066 m_alphaLabel->setBuddy(m_alphaSpinBox);
1068 m_alphaLayout->
addWidget(m_alphaGradientSlider);
1069 m_alphaLayout->
addWidget(m_alphaSpinBox);
1098 m_buttonBox->installEventFilter(&m_languageChangeEventFilter);
1099 m_buttonOK->installEventFilter(&m_languageChangeEventFilter);
1100 m_buttonCancel->installEventFilter(&m_languageChangeEventFilter);
1112 tempMainLayout->
addLayout(headerLayout);
1113 tempMainLayout->
addLayout(m_selectorLayout);
1114 tempMainLayout->
addLayout(m_alphaLayout);
1116 q_pointer->setLayout(tempMainLayout);
1122 &ColorDialogPrivate::readColorPatchValue
1124 connect(m_swatchBookBasicColors,
1125 &SwatchBook::currentColorChanged,
1127 &ColorDialogPrivate::readSwatchBookBasicColorsValue
1130 &SwatchBook::currentColorChanged,
1132 &ColorDialogPrivate::readSwatchBookHistoryValue
1137 &ColorDialogPrivate::readRgbNumericValues
1142 &ColorDialogPrivate::readRgbHexValues
1147 &ColorDialogPrivate::updateRgbHexButBlockSignals
1152 &ColorDialogPrivate::readHslNumericValues
1157 &ColorDialogPrivate::readHwbNumericValues
1162 &ColorDialogPrivate::readHsvNumericValues
1167 &ColorDialogPrivate::readHlcNumericValues
1172 &ColorDialogPrivate::updateHlcButBlockSignals
1177 &ColorDialogPrivate::readOklchNumericValues
1182 &ColorDialogPrivate::updateOklchButBlockSignals
1184 connect(m_lchLightnessSelector,
1187 &ColorDialogPrivate::readLightnessValue
1192 &ColorDialogPrivate::readWheelColorPickerValues
1197 &ColorDialogPrivate::readChromaHueDiagramValue
1199 connect(m_alphaGradientSlider,
1202 &ColorDialogPrivate::updateColorPatch
1204 connect(m_alphaGradientSlider,
1207 [
this](
const qreal newFraction) {
1209 m_alphaSpinBox->setValue(newFraction * 100);
1214 [
this](
const double newValue) {
1217 m_alphaGradientSlider->setValue(newValue / 100);
1221 q_pointer->setOptions(QColorDialog::ColorDialogOption::DontUseNativeDialog);
1229 q_pointer->setWindowTitle(
tr(
"Select color"));
1244 q_pointer->setSizeGripEnabled(
true);
1249 m_ciehlcD50SpinBoxGamutAction =
new QAction(q_pointer);
1250 connect(m_ciehlcD50SpinBoxGamutAction,
1253 &ColorDialogPrivate::updateHlcButBlockSignals
1255 m_oklchSpinBoxGamutAction =
new QAction(q_pointer);
1256 connect(m_oklchSpinBoxGamutAction,
1259 &ColorDialogPrivate::updateOklchButBlockSignals
1264 m_ciehlcD50SpinBoxGamutAction->setVisible(
false);
1265 m_ciehlcD50SpinBox->addActionButton(
1266 m_ciehlcD50SpinBoxGamutAction,
1267 QLineEdit::ActionPosition::TrailingPosition);
1268 m_oklchSpinBoxGamutAction->setVisible(
false);
1269 m_oklchSpinBox->addActionButton(
1270 m_oklchSpinBoxGamutAction,
1271 QLineEdit::ActionPosition::TrailingPosition);
1278 std::optional<QStringList>());
1282#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
1283 connect(qGuiApp->styleHints(),
1286 &ColorDialogPrivate::reloadIcons);
1296 , d_pointer(new ColorDialogPrivate(this))
1314 , d_pointer(new ColorDialogPrivate(this))
1333 , d_pointer(new ColorDialogPrivate(this))
1335 d_pointer->initialize(colorSpace);
1343QColor ColorDialogPrivate::defaultColor()
const
1345 const auto history = m_settings.history.value();
1346 return history.value(0, m_wcsBasicDefaultColor);
1363 , d_pointer(new ColorDialogPrivate(this))
1365 d_pointer->initialize(colorSpace);
1388ColorDialogPrivate::ColorDialogPrivate(
ColorDialog *backLink)
1389 : q_pointer(backLink)
1397 QColor temp = d_pointer->m_currentOpaqueColorRgb.rgbQColor;
1399 static_cast<QColorFloatType
>(
1400 d_pointer->m_alphaGradientSlider->value()));
1422 temp = color.
toRgb();
1427 if (
testOption(ColorDialog::ColorDialogOption::ShowAlphaChannel)) {
1428 d_pointer->m_alphaGradientSlider->setValue(
1429 static_cast<double>(temp.
alphaF()));
1431 d_pointer->m_alphaGradientSlider->setValue(1);
1435 const RgbColor myRgbColor = RgbColor::fromRgbQColor(temp);
1436 d_pointer->setCurrentOpaqueColor(myRgbColor,
nullptr);
1449void ColorDialog::open(
QObject *receiver,
const char *member)
1455 d_pointer->m_receiverToBeDisconnected = receiver;
1456 d_pointer->m_memberToBeDisconnected = member;
1465void ColorDialogPrivate::updateColorPatch()
1467 QColor tempRgbQColor = m_currentOpaqueColorRgb.rgbQColor;
1469 static_cast<QColorFloatType
>(m_alphaGradientSlider->value()));
1470 m_colorPatch->setColor(tempRgbQColor);
1477 const auto rgb1 = m_rgbColorSpace->fromCielchD50ToRgb1(cielchD50);
1478 const auto rgb255 = GenericColor(rgb1.first * 255,
1481 const auto rgbColor = RgbColor::fromRgb255(rgb255);
1482 setCurrentOpaqueColor(abs, rgbColor, ignoreWidget);
1486void ColorDialogPrivate::setCurrentOpaqueColor(
const PerceptualColor::RgbColor &rgb,
QWidget *
const ignoreWidget)
1488 const auto temp = rgb.rgb255;
1490 static_cast<QColorFloatType
>(temp.first / 255.),
1491 static_cast<QColorFloatType
>(temp.second / 255.),
1492 static_cast<QColorFloatType
>(temp.third / 255.));
1493 const auto cielchD50 = GenericColor(
1494 m_rgbColorSpace->toCielchD50(myQColor.
rgba64()));
1495 setCurrentOpaqueColor(
1519 const PerceptualColor::RgbColor &rgb,
1522 const bool isIdentical =
1523 (abs == m_currentOpaqueColorAbs) && (rgb == m_currentOpaqueColorRgb);
1524 if (m_isColorChangeInProgress || isIdentical) {
1531 m_isColorChangeInProgress =
true;
1535 QColor oldQColor = q_pointer->currentColor();
1538 m_currentOpaqueColorAbs = abs;
1539 m_currentOpaqueColorRgb = rgb;
1542 if (m_swatchBookBasicColors != ignoreWidget) {
1543 m_swatchBookBasicColors->setCurrentColor(
1544 m_currentOpaqueColorRgb.rgbQColor);
1548 if (m_swatchBookHistory != ignoreWidget) {
1549 m_swatchBookHistory->setCurrentColor(m_currentOpaqueColorRgb.rgbQColor);
1553 if (m_rgbSpinBox != ignoreWidget) {
1554 m_rgbSpinBox->setSectionValues(
1555 m_currentOpaqueColorRgb.rgb255.toQList3());
1559 if (m_hslSpinBox != ignoreWidget) {
1560 m_hslSpinBox->setSectionValues(
1561 m_currentOpaqueColorRgb.hsl.toQList3());
1565 if (m_hwbSpinBox != ignoreWidget) {
1566 m_hwbSpinBox->setSectionValues(
1567 m_currentOpaqueColorRgb.hwb.toQList3());
1571 if (m_hsvSpinBox != ignoreWidget) {
1572 m_hsvSpinBox->setSectionValues(
1573 m_currentOpaqueColorRgb.hsv.toQList3());
1581 if (m_ciehlcD50SpinBox != ignoreWidget) {
1582 m_ciehlcD50SpinBox->setSectionValues(ciehlcD50);
1587 if (m_oklchSpinBox != ignoreWidget) {
1588 m_oklchSpinBox->setSectionValues(oklch.toQList3());
1592 if (m_rgbLineEdit != ignoreWidget) {
1593 updateRgbHexButBlockSignals();
1597 if (m_lchLightnessSelector != ignoreWidget) {
1598 m_lchLightnessSelector->setValue(
1599 cielchD50.first /
static_cast<qreal
>(100));
1603 if (m_chromaHueDiagram != ignoreWidget) {
1604 m_chromaHueDiagram->setCurrentColorCielchD50(cielchD50);
1608 if (m_wheelColorPicker != ignoreWidget) {
1609 m_wheelColorPicker->setCurrentColorCielchD50(cielchD50);
1613 if (m_alphaGradientSlider != ignoreWidget) {
1614 GenericColor tempColor;
1615 tempColor.first = cielchD50.first;
1616 tempColor.second = cielchD50.second;
1617 tempColor.third = cielchD50.third;
1618 tempColor.fourth = 0;
1619 m_alphaGradientSlider->setFirstColorCieLchD50A(tempColor);
1620 tempColor.fourth = 1;
1621 m_alphaGradientSlider->setSecondColorCieLchD50A(tempColor);
1625 if (m_colorPatch != ignoreWidget) {
1630 if (q_pointer->currentColor() != oldQColor) {
1631 Q_EMIT q_pointer->currentColorChanged(q_pointer->currentColor());
1636 m_isColorChangeInProgress =
false;
1641void ColorDialogPrivate::readLightnessValue()
1643 if (m_isColorChangeInProgress) {
1648 cielchD50.first = m_lchLightnessSelector->value() * 100;
1649 cielchD50 = GenericColor(
1650 m_rgbColorSpace->reduceCielchD50ChromaToFitIntoGamut(cielchD50));
1651 setCurrentOpaqueColor(
1653 m_lchLightnessSelector);
1658void ColorDialogPrivate::readHslNumericValues()
1660 if (m_isColorChangeInProgress) {
1664 const auto temp = RgbColor::fromHsl(
1665 GenericColor(m_hslSpinBox->sectionValues()));
1666 setCurrentOpaqueColor(temp, m_hslSpinBox);
1671void ColorDialogPrivate::readHwbNumericValues()
1673 if (m_isColorChangeInProgress) {
1677 const auto temp = RgbColor::fromHwb(
1678 GenericColor(m_hwbSpinBox->sectionValues()));
1679 setCurrentOpaqueColor(temp, m_hwbSpinBox);
1684void ColorDialogPrivate::readHsvNumericValues()
1686 if (m_isColorChangeInProgress) {
1690 const auto temp = RgbColor::fromHsv(
1691 GenericColor(m_hsvSpinBox->sectionValues()));
1692 setCurrentOpaqueColor(temp, m_hsvSpinBox);
1697void ColorDialogPrivate::readRgbNumericValues()
1699 if (m_isColorChangeInProgress) {
1703 const auto temp = RgbColor::fromRgb255(
1704 GenericColor(m_rgbSpinBox->sectionValues()));
1705 setCurrentOpaqueColor(temp, m_rgbSpinBox);
1710void ColorDialogPrivate::readColorPatchValue()
1712 if (m_isColorChangeInProgress) {
1716 const QColor temp = m_colorPatch->color();
1721 const auto myRgbColor = RgbColor::fromRgbQColor(temp);
1722 setCurrentOpaqueColor(myRgbColor, m_colorPatch);
1727void ColorDialogPrivate::readSwatchBookBasicColorsValue()
1729 if (m_isColorChangeInProgress) {
1733 const QColor temp = m_swatchBookBasicColors->currentColor();
1738 const auto myRgbColor = RgbColor::fromRgbQColor(temp);
1739 setCurrentOpaqueColor(myRgbColor, m_swatchBookBasicColors);
1744void ColorDialogPrivate::readSwatchBookHistoryValue()
1746 if (m_isColorChangeInProgress) {
1750 const QColor temp = m_swatchBookHistory->currentColor();
1755 const auto myRgbColor = RgbColor::fromRgbQColor(temp);
1756 setCurrentOpaqueColor(myRgbColor, m_swatchBookHistory);
1761void ColorDialogPrivate::readWheelColorPickerValues()
1763 if (m_isColorChangeInProgress) {
1767 const auto cielchD50 = GenericColor(m_wheelColorPicker->currentColorCielchD50());
1768 setCurrentOpaqueColor(
1770 m_wheelColorPicker);
1775void ColorDialogPrivate::readChromaHueDiagramValue()
1777 if (m_isColorChangeInProgress) {
1781 const auto cielchD50 = GenericColor(m_chromaHueDiagram->currentColorCielchD50());
1782 setCurrentOpaqueColor(
1784 m_chromaHueDiagram);
1789void ColorDialogPrivate::readRgbHexValues()
1791 if (m_isColorChangeInProgress) {
1795 QString temp = m_rgbLineEdit->text();
1796 if (!temp.
startsWith(QStringLiteral(u
"#"))) {
1797 temp = QStringLiteral(u
"#") + temp;
1802 const auto myRgbColor = RgbColor::fromRgbQColor(rgb);
1803 setCurrentOpaqueColor(myRgbColor, m_rgbLineEdit);
1805 m_isDirtyRgbLineEdit =
true;
1813void ColorDialogPrivate::updateRgbHexButBlockSignals()
1821 const auto &rgbFloat = m_currentOpaqueColorRgb.rgb255;
1834 QStringLiteral(u
"#%1%2%3")
1835 .
arg(qBound(0, qRound(rgbFloat.first), 255),
1839 .
arg(qBound(0, qRound(rgbFloat.second), 255),
1843 .
arg(qBound(0, qRound(rgbFloat.third), 255),
1848 m_rgbLineEdit->setText(hexString);
1856void ColorDialogPrivate::updateHlcButBlockSignals()
1863 m_ciehlcD50SpinBox->setSectionValues(ciehlcD50List);
1864 m_ciehlcD50SpinBoxGamutAction->setVisible(
false);
1872void ColorDialogPrivate::updateOklchButBlockSignals()
1876 m_oklchSpinBox->setSectionValues(oklch.toQList3());
1877 m_oklchSpinBoxGamutAction->setVisible(
false);
1882void ColorDialogPrivate::readHlcNumericValues()
1884 if (m_isColorChangeInProgress) {
1888 QList<double> hlcValues = m_ciehlcD50SpinBox->sectionValues();
1890 lch.third = hlcValues.
at(0);
1891 lch.first = hlcValues.
at(1);
1892 lch.second = hlcValues.
at(2);
1893 if (m_rgbColorSpace->isCielchD50InGamut(lch)) {
1894 m_ciehlcD50SpinBoxGamutAction->setVisible(
false);
1896 m_ciehlcD50SpinBoxGamutAction->setVisible(
true);
1898 const auto myColor = GenericColor(
1899 m_rgbColorSpace->reduceCielchD50ChromaToFitIntoGamut(lch));
1900 setCurrentOpaqueColor(
1903 m_ciehlcD50SpinBox);
1908void ColorDialogPrivate::readOklchNumericValues()
1910 if (m_isColorChangeInProgress) {
1918 GenericColor originalOklch;
1919 originalOklch.first = m_oklchSpinBox->sectionValues().value(0);
1920 originalOklch.second = m_oklchSpinBox->sectionValues().value(1);
1921 originalOklch.third = m_oklchSpinBox->sectionValues().value(2);
1922 if (m_rgbColorSpace->isOklchInGamut(originalOklch)) {
1923 m_oklchSpinBoxGamutAction->setVisible(
false);
1925 m_oklchSpinBoxGamutAction->setVisible(
true);
1927 const auto inGamutOklch = GenericColor(
1928 m_rgbColorSpace->reduceOklchChromaToFitIntoGamut(originalOklch));
1929 const auto inGamutColor =
1931 setCurrentOpaqueColor(inGamutColor,
1940void ColorDialogPrivate::initializeScreenColorPicker()
1942 auto screenPicker =
new ScreenColorPicker(q_pointer);
1943 if (!screenPicker->isAvailable()) {
1947 screenPicker->
setParent(m_screenColorPickerButton);
1948 connect(m_screenColorPickerButton,
1952 [&, screenPicker]() {
1953 const auto myColor = q_pointer->currentColor();
1958 screenPicker->startPicking(
1959 fromFloatingToEightBit(myColor.redF()),
1960 fromFloatingToEightBit(myColor.greenF()),
1961 fromFloatingToEightBit(myColor.blueF()));
1964 &ScreenColorPicker::newColor,
1966 [
this](
const double red,
const double green,
const double blue,
const bool isSRgbGuaranteed) {
1967 Q_UNUSED(isSRgbGuaranteed)
1973 const GenericColor rgb255
1974 {qBound<double>(0, red * 255, 255),
1975 qBound<double>(0, green * 255, 255),
1976 qBound<double>(0, blue * 255, 255)};
1977 setCurrentOpaqueColor(RgbColor::fromRgb255(rgb255),
nullptr);
1984QWidget *ColorDialogPrivate::initializeNumericPage()
1988 m_rgbSpinBox =
new MultiSpinBox();
1990 MultiSpinBoxSection mySection;
1991 mySection.setDecimals(decimals);
1992 mySection.setMinimum(0);
1993 mySection.setMaximum(255);
1995 mySection.setPrefix(
QString());
1996 mySection.setSuffix(m_multispinboxSectionSeparator);
1997 rgbSections.
append(mySection);
1999 mySection.setPrefix(m_multispinboxSectionSeparator);
2000 mySection.setSuffix(m_multispinboxSectionSeparator);
2001 rgbSections.
append(mySection);
2003 mySection.setPrefix(m_multispinboxSectionSeparator);
2004 mySection.setSuffix(
QString());
2005 rgbSections.
append(mySection);
2007 m_rgbSpinBox->setSectionConfigurations(rgbSections);
2013 m_rgbLineEdit->setMaxLength(7);
2015 QStringLiteral(u
"#?[0-9A-Fa-f]{0,6}"));
2017 tempRegularExpression,
2019 m_rgbLineEdit->setValidator(validator);
2024 m_hslSpinBox =
new MultiSpinBox();
2026 MultiSpinBoxSection mySection;
2027 mySection.setDecimals(decimals);
2029 mySection.setMinimum(0);
2030 mySection.setMaximum(360);
2031 mySection.setWrapping(
true);
2032 hslSections.
append(mySection);
2034 mySection.setMinimum(0);
2035 mySection.setMaximum(100);
2036 mySection.setWrapping(
false);
2037 hslSections.
append(mySection);
2039 mySection.setMinimum(0);
2040 mySection.setMaximum(100);
2041 mySection.setWrapping(
false);
2042 hslSections.
append(mySection);
2044 m_hslSpinBox->setSectionConfigurations(hslSections);
2049 m_hwbSpinBox =
new MultiSpinBox();
2051 MultiSpinBoxSection mySection;
2052 mySection.setDecimals(decimals);
2054 mySection.setMinimum(0);
2055 mySection.setMaximum(360);
2056 mySection.setWrapping(
true);
2057 hwbSections.
append(mySection);
2059 mySection.setMinimum(0);
2060 mySection.setMaximum(100);
2061 mySection.setWrapping(
false);
2062 hwbSections.
append(mySection);
2064 mySection.setMinimum(0);
2065 mySection.setMaximum(100);
2066 mySection.setWrapping(
false);
2067 hwbSections.
append(mySection);
2069 m_hwbSpinBox->setSectionConfigurations(hwbSections);
2074 m_hsvSpinBox =
new MultiSpinBox();
2076 MultiSpinBoxSection mySection;
2077 mySection.setDecimals(decimals);
2079 mySection.setMinimum(0);
2080 mySection.setMaximum(360);
2081 mySection.setWrapping(
true);
2082 hsvSections.
append(mySection);
2084 mySection.setMinimum(0);
2085 mySection.setMaximum(100);
2086 mySection.setWrapping(
false);
2087 hsvSections.
append(mySection);
2089 mySection.setMinimum(0);
2090 mySection.setMaximum(100);
2091 mySection.setWrapping(
false);
2092 hsvSections.
append(mySection);
2094 m_hsvSpinBox->setSectionConfigurations(hsvSections);
2100 m_rgbSpinBoxLabel =
new QLabel();
2101 m_rgbSpinBoxLabel->setBuddy(m_rgbSpinBox);
2102 tempRgbFormLayout->
addRow(m_rgbSpinBoxLabel, m_rgbSpinBox);
2103 m_rgbLineEditLabel =
new QLabel();
2104 m_rgbLineEditLabel->setBuddy(m_rgbLineEdit);
2105 tempRgbFormLayout->
addRow(m_rgbLineEditLabel, m_rgbLineEdit);
2106 m_hslSpinBoxLabel =
new QLabel();
2107 m_hslSpinBoxLabel->setBuddy(m_hslSpinBox);
2108 tempRgbFormLayout->
addRow(m_hslSpinBoxLabel, m_hslSpinBox);
2109 m_hwbSpinBoxLabel =
new QLabel();
2110 m_hwbSpinBoxLabel->setBuddy(m_hwbSpinBox);
2111 tempRgbFormLayout->
addRow(m_hwbSpinBoxLabel, m_hwbSpinBox);
2112 m_hsvSpinBoxLabel =
new QLabel();
2113 m_hsvSpinBoxLabel->setBuddy(m_hsvSpinBox);
2114 tempRgbFormLayout->
addRow(m_hsvSpinBoxLabel, m_hsvSpinBox);
2116 m_rgbGroupBox->setLayout(tempRgbFormLayout);
2123 const auto elidedProfileName = fontMetrics.elidedText(
2124 m_rgbColorSpace->profileName(),
2125 Qt::TextElideMode::ElideRight,
2128 m_rgbGroupBox->setTitle(elidedProfileName);
2134 m_ciehlcD50SpinBox =
new MultiSpinBox;
2135 MultiSpinBoxSection mySection;
2136 mySection.setDecimals(decimals);
2138 mySection.setMinimum(0);
2139 mySection.setMaximum(360);
2140 mySection.setWrapping(
true);
2141 ciehlcD50Sections.
append(mySection);
2143 mySection.setMinimum(0);
2144 mySection.setMaximum(100);
2145 mySection.setWrapping(
false);
2146 ciehlcD50Sections.
append(mySection);
2148 mySection.setMinimum(0);
2149 mySection.setMaximum(CielchD50Values::maximumChroma);
2150 mySection.setWrapping(
false);
2151 ciehlcD50Sections.
append(mySection);
2153 m_ciehlcD50SpinBox->setSectionConfigurations(ciehlcD50Sections);
2159 MultiSpinBoxSection mySection;
2160 m_oklchSpinBox =
new MultiSpinBox;
2162 mySection.setMinimum(0);
2163 mySection.setMaximum(1);
2164 mySection.setSingleStep(singleStepOklabc);
2165 mySection.setWrapping(
false);
2166 mySection.setDecimals(okdecimals);
2167 oklchSections.
append(mySection);
2169 mySection.setMinimum(0);
2170 mySection.setMaximum(OklchValues::maximumChroma);
2171 mySection.setSingleStep(singleStepOklabc);
2172 mySection.setWrapping(
false);
2173 mySection.setDecimals(okdecimals);
2174 oklchSections.
append(mySection);
2176 mySection.setMinimum(0);
2177 mySection.setMaximum(360);
2178 mySection.setSingleStep(1);
2179 mySection.setWrapping(
true);
2180 mySection.setDecimals(decimals);
2181 oklchSections.
append(mySection);
2183 m_oklchSpinBox->setSectionConfigurations(oklchSections);
2192 m_ciehlcD50SpinBoxLabel =
new QLabel();
2193 m_ciehlcD50SpinBoxLabel->setBuddy(m_ciehlcD50SpinBox);
2194 cielabFormLayout->
addRow(m_ciehlcD50SpinBoxLabel, m_ciehlcD50SpinBox);
2195 m_oklchSpinBoxLabel =
new QLabel();
2196 m_oklchSpinBoxLabel->setBuddy(m_oklchSpinBox);
2197 cielabFormLayout->
addRow(m_oklchSpinBoxLabel, m_oklchSpinBox);
2198 tempMainLayout->
addLayout(cielabFormLayout);
2199 tempMainLayout->
addWidget(m_rgbGroupBox);
2210 return d_pointer->m_options;
2221 temp.setFlag(option, on);
2231 if (newOptions == d_pointer->m_options) {
2236 d_pointer->m_options = newOptions;
2239 d_pointer->m_options.setFlag(
2240 QColorDialog::ColorDialogOption::DontUseNativeDialog,
2244 const bool alphaVisibility = d_pointer->m_options.testFlag(
2245 QColorDialog::ColorDialogOption::ShowAlphaChannel);
2246 d_pointer->m_alphaLabel->setVisible(alphaVisibility);
2247 d_pointer->m_alphaGradientSlider->setVisible(alphaVisibility);
2248 d_pointer->m_alphaSpinBox->setVisible(alphaVisibility);
2251 d_pointer->m_buttonBox->setVisible(!d_pointer->m_options.testFlag(
2252 QColorDialog::ColorDialogOption::NoButtons));
2267 return d_pointer->m_options.testFlag(option);
2339 return d_pointer->m_selectedColor;
2355 d_pointer->m_selectedColor =
QColor();
2356 d_pointer->applyLayoutDimensions();
2364 d_pointer->m_buttonOK->setDefault(
true);
2373 if (
result == QDialog::DialogCode::Accepted) {
2375 auto history = d_pointer->m_settings.history.value();
2376 const auto maxHistoryLenght = std::max(d_pointer->historySwatchCount,
2379 history.removeAll(d_pointer->m_selectedColor);
2381 history.prepend(d_pointer->m_selectedColor);
2383 while (history.count() > maxHistoryLenght) {
2384 history.removeLast();
2386 d_pointer->m_settings.history.setValue(history);
2389 d_pointer->m_selectedColor =
QColor();
2392 if (d_pointer->m_receiverToBeDisconnected) {
2401 d_pointer->m_receiverToBeDisconnected,
2402 d_pointer->m_memberToBeDisconnected.
constData()
2404 d_pointer->m_receiverToBeDisconnected =
nullptr;
2412 return d_pointer->m_layoutDimensions;
2419 if (newLayoutDimensions == d_pointer->m_layoutDimensions) {
2422 d_pointer->m_layoutDimensions = newLayoutDimensions;
2423 d_pointer->applyLayoutDimensions();
2432void ColorDialogPrivate::applyLayoutDimensions()
2437 constexpr auto screenSizeDependent =
2439 int effectivelyAvailableScreenWidth;
2440 int widthThreeshold;
2441 switch (m_layoutDimensions) {
2443 m_layoutDimensionsEffective = collapsed;
2446 m_layoutDimensionsEffective = expanded;
2448 case screenSizeDependent:
2455 effectivelyAvailableScreenWidth = qRound(
2462 widthThreeshold = qMax(
2463 m_wheelColorPicker->sizeHint().width(),
2464 m_lightnessFirstWrapperWidget->sizeHint().width());
2466 widthThreeshold += m_numericalWidget->sizeHint().width();
2468 widthThreeshold = qRound(widthThreeshold * 1.2);
2471 if (effectivelyAvailableScreenWidth < widthThreeshold) {
2472 m_layoutDimensionsEffective = collapsed;
2474 m_layoutDimensionsEffective = expanded;
2483 if (m_layoutDimensionsEffective == collapsed) {
2484 if (m_selectorLayout->indexOf(m_numericalWidget) >= 0) {
2487 const bool oldUpdatesEnabled = m_tabWidget->updatesEnabled();
2488 m_tabWidget->setUpdatesEnabled(
false);
2492 m_tabWidget->addTab(m_numericalWidget,
QString());
2493 m_tabWidget->setUpdatesEnabled(oldUpdatesEnabled);
2499 q_pointer->adjustSize();
2502 if (m_selectorLayout->indexOf(m_numericalWidget) < 0) {
2505 m_selectorLayout->addWidget(m_numericalWidget);
2508 m_numericalWidget->show();
2510 q_pointer->adjustSize();
2524 const auto type =
event->type();
2533 d_pointer->retranslateUi();
2538 &eventForSwatchBookBasicColors);
2543 &eventForSwatchBookHistory);
2553 &eventForButtonCancel);
2558 d_pointer->reloadIcons();
2576 if (!d_pointer->everShown) {
2578 const bool exp = d_pointer->m_layoutDimensionsEffective == expValue;
2579 const auto tabString = exp
2580 ? d_pointer->m_settings.tabExpanded.value()
2581 : d_pointer->m_settings.tab.value();
2582 const auto key = d_pointer->m_tabTable.
key(tabString,
nullptr);
2583 if (key !=
nullptr) {
2584 d_pointer->m_tabWidget->setCurrentWidget(*key);
2591 d_pointer->saveCurrentTab();
2593 switch (d_pointer->m_settings.swatchBookPage.value()) {
2594 case PerceptualSettings::SwatchBookPage::History:
2595 d_pointer->m_settings.swatchBookPage.setValue(
2596 PerceptualSettings::SwatchBookPage::History);
2597 d_pointer->m_swatchBookSelector->setCurrentIndex(1);
2598 d_pointer->m_swatchBookStack->setCurrentIndex(1);
2600 case PerceptualSettings::SwatchBookPage::BasicColors:
2602 d_pointer->m_settings.swatchBookPage.setValue(
2603 PerceptualSettings::SwatchBookPage::BasicColors);
2604 d_pointer->m_swatchBookSelector->setCurrentIndex(0);
2605 d_pointer->m_swatchBookStack->setCurrentIndex(0);
2609 d_pointer->everShown =
true;
2615void ColorDialogPrivate::saveCurrentTab()
2617 const auto currentIndex = m_tabWidget->currentIndex();
2618 QWidget const *
const widget = m_tabWidget->widget(currentIndex);
2619 const auto keyList = m_tabTable.
keys();
2620 auto it = std::find_if(
2623 [widget](
const auto &key) {
2624 return ((*key) == widget);
2627 if (it != keyList.end()) {
2628 const auto tabString = m_tabTable.
value(*it);
2630 if (m_layoutDimensionsEffective == expValue) {
2631 m_settings.tabExpanded.setValue(tabString);
2633 m_settings.tab.setValue(tabString);
2640void ColorDialogPrivate::loadHistoryFromSettingsToSwatchBook()
2642 Swatches historyArray(historyHSwatchCount,
2643 historyVSwatchCount,
2644 m_settings.history.value());
2645 m_swatchBookHistory->setSwatchGrid(historyArray);
void currentColorCielchD50Changed(const PerceptualColor::GenericColor &newCurrentColorCielchD50)
Notify signal for property currentColorCielchD50.
A perceptually uniform color picker dialog.
void colorSelected(const QColor &color)
This signal is emitted just after the user has clicked OK to select a color to use.
static QColor getColor(const QColor &initial=Qt::white, QWidget *parent=nullptr, const QString &title=QString(), ColorDialogOptions options=ColorDialogOptions())
Pops up a modal color dialog, lets the user choose a color, and returns that color.
virtual void showEvent(QShowEvent *event) override
Handle show events.
virtual void setVisible(bool visible) override
Setter for property visible
Q_INVOKABLE ColorDialog(QWidget *parent=nullptr)
Constructor.
ColorDialogOptions options
Various options that affect the look and feel of the dialog.
Q_INVOKABLE bool testOption(PerceptualColor::ColorDialog::ColorDialogOption option) const
Getter for KConfig Entry Options.
Q_INVOKABLE void setOption(PerceptualColor::ColorDialog::ColorDialogOption option, bool on=true)
Setter for KConfig Entry Options.
QColor currentColor
Currently selected color in the dialog.
void setCurrentColor(const QColor &color)
Setter for currentColor property.
virtual void done(int result) override
Various updates when closing the dialog.
virtual ~ColorDialog() noexcept override
Destructor.
void optionsChanged(const PerceptualColor::ColorDialog::ColorDialogOptions newOptions)
Notify signal for property KConfig Entry Options.
void setOptions(PerceptualColor::ColorDialog::ColorDialogOptions newOptions)
Setter for KConfig Entry Options.
void setLayoutDimensions(const PerceptualColor::ColorDialog::DialogLayoutDimensions newLayoutDimensions)
Setter for property layoutDimensions.
DialogLayoutDimensions
Layout dimensions.
@ Expanded
Use the large, “expanded” layout of this dialog.
@ Collapsed
Use the small, “collapsed“ layout of this dialog.
@ ScreenSizeDependent
Decide automatically between collapsed and expanded layout: collapsed is used on small screens,...
QColorDialog::ColorDialogOptions ColorDialogOptions
Local alias for QColorDialog::ColorDialogOptions.
virtual void changeEvent(QEvent *event) override
Handle state changes.
void layoutDimensionsChanged(const PerceptualColor::ColorDialog::DialogLayoutDimensions newLayoutDimensions)
Notify signal for property layoutDimensions.
Q_INVOKABLE QColor selectedColor() const
The color that was actually selected by the user.
DialogLayoutDimensions layoutDimensions
Layout dimensions.
void colorChanged(const QColor &color)
Notify signal for property color.
void valueChanged(const qreal newValue)
Signal for value property.
void sectionValuesChanged(const QList< double > &newSectionValues)
Notify signal for property sectionValues.
static QSharedPointer< PerceptualColor::RgbColorSpace > createSrgb()
Create an sRGB color space object.
void currentColorCielchD50Changed(const PerceptualColor::GenericColor &newCurrentColorCielchD50)
Notify signal for property currentColorCielchD50.
QString name(StandardAction id)
QString label(StandardShortcut id)
The namespace of this library.
Array2D< QColor > Swatches
Swatches organized in a grid.
ColorSchemeType
Represents the appearance of a theme.
Swatches wcsBasicColors(const QSharedPointer< PerceptualColor::RgbColorSpace > &colorSpace)
Swatch grid derived from the basic colors as by WCS (World color survey).
@ OklchD65
The Oklch color space, which by definition always and exclusively uses a D65 illuminant.
@ CielchD50
The Cielch color space using a D50 illuminant.
void triggered(bool checked)
void addLayout(QLayout *layout, int stretch)
void addStretch(int stretch)
const char * constData() const const
void setNamedColor(QLatin1StringView name)
float alphaF() const const
QColor fromRgbF(float r, float g, float b, float a)
bool isValid() const const
QRgba64 rgba64() const const
void setAlphaF(float alpha)
QColor toRgb() const const
void currentIndexChanged(int index)
QCoreApplication * instance()
bool sendEvent(QObject *receiver, QEvent *event)
bool isNull() const const
virtual void setVisible(bool visible) override
virtual void showEvent(QShowEvent *event) override
void valueChanged(double d)
iterator insert(const Key &key, const T &value)
Key key(const T &value) const const
QList< Key > keys() const const
T value(const Key &key) const const
QKeySequence mnemonic(const QString &text)
void textChanged(const QString &text)
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
qsizetype count() const const
bool isEmpty() const const
QString toString(QDate date, FormatType format) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
QObject * parent() const const
QString tr(const char *sourceText, const char *disambiguation, int n)
bool isNull() const const
void activatedAmbiguously()
QString arg(Args &&... args) const const
bool isEmpty() const const
void resize(qsizetype newSize, QChar fillChar)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QString toUpper() const const
QString join(QChar separator) const const
void colorSchemeChanged(Qt::ColorScheme colorScheme)
WindowContextHelpButtonHint
QString toString() const const