diff --git a/src/plugins/texteditor/colorscheme.cpp b/src/plugins/texteditor/colorscheme.cpp index 6a4eed7659e..632cf963af8 100644 --- a/src/plugins/texteditor/colorscheme.cpp +++ b/src/plugins/texteditor/colorscheme.cpp @@ -58,6 +58,26 @@ void Format::setBackground(const QColor &background) m_background = background; } +void Format::setRelativeForegroundSaturation(double relativeForegroundSaturation) +{ + m_relativeForegroundSaturation = relativeForegroundSaturation; +} + +void Format::setRelativeForegroundLightness(double relativeForegroundLightness) +{ + m_relativeForegroundLightness = relativeForegroundLightness; +} + +void Format::setRelativeBackgroundSaturation(double relativeBackgroundSaturation) +{ + m_relativeBackgroundSaturation = relativeBackgroundSaturation; +} + +void Format::setRelativeBackgroundLightness(double relativeBackgroundLightness) +{ + m_relativeBackgroundLightness = relativeBackgroundLightness; +} + void Format::setBold(bool bold) { m_bold = bold; @@ -138,7 +158,13 @@ bool Format::equals(const Format &other) const && m_underlineColor == other.m_underlineColor && m_underlineStyle == other.m_underlineStyle && m_bold == other.m_bold - && m_italic == other.m_italic; + && m_italic == other.m_italic + && qFuzzyCompare(m_relativeForegroundSaturation, other.m_relativeForegroundSaturation) + && qFuzzyCompare(m_relativeForegroundLightness, other.m_relativeForegroundLightness) + && qFuzzyCompare(m_relativeBackgroundSaturation, other.m_relativeBackgroundSaturation) + && qFuzzyCompare(m_relativeBackgroundLightness, other.m_relativeBackgroundLightness) + + ; } QString Format::toString() const @@ -148,7 +174,11 @@ QString Format::toString() const m_bold ? QLatin1String(trueString) : QLatin1String(falseString), m_italic ? QLatin1String(trueString) : QLatin1String(falseString), m_underlineColor.name(), - underlineStyleToString(m_underlineStyle)}); + underlineStyleToString(m_underlineStyle), + QString::number(m_relativeForegroundSaturation), + QString::number(m_relativeForegroundLightness), + QString::number(m_relativeBackgroundSaturation), + QString::number(m_relativeBackgroundLightness)}); return text.join(QLatin1Char(';')); } @@ -158,15 +188,23 @@ bool Format::fromString(const QString &str) *this = Format(); const QStringList lst = str.split(QLatin1Char(';')); - if (lst.count() != 4 && lst.count() != 6) + if (lst.size() != 4 && lst.size() != 6 && lst.size() != 10) return false; m_foreground = stringToColor(lst.at(0)); m_background = stringToColor(lst.at(1)); m_bold = lst.at(2) == QLatin1String(trueString); m_italic = lst.at(3) == QLatin1String(trueString); - m_underlineColor = stringToColor(lst.at(4)); - m_underlineStyle = stringToUnderlineStyle(lst.at(5)); + if (lst.size() > 4) { + m_underlineColor = stringToColor(lst.at(4)); + m_underlineStyle = stringToUnderlineStyle(lst.at(5)); + } + if (lst.size() > 6) { + m_relativeForegroundSaturation = lst.at(6).toDouble(); + m_relativeForegroundLightness = lst.at(7).toDouble(); + m_relativeBackgroundSaturation = lst.at(8).toDouble(); + m_relativeBackgroundLightness = lst.at(9).toDouble(); + } return true; } @@ -230,6 +268,14 @@ bool ColorScheme::save(const QString &fileName, QWidget *parent) const w.writeAttribute(QStringLiteral("underlineColor"), format.underlineColor().name().toLower()); if (format.underlineStyle() != QTextCharFormat::NoUnderline) w.writeAttribute(QLatin1String("underlineStyle"), underlineStyleToString(format.underlineStyle())); + if (!qFuzzyIsNull(format.relativeForegroundSaturation())) + w.writeAttribute(QLatin1String("relativeForegroundSaturation"), QString::number(format.relativeForegroundSaturation())); + if (!qFuzzyIsNull(format.relativeForegroundLightness())) + w.writeAttribute(QLatin1String("relativeForegroundLightness"), QString::number(format.relativeForegroundLightness())); + if (!qFuzzyIsNull(format.relativeBackgroundSaturation())) + w.writeAttribute(QLatin1String("relativeBackgroundSaturation"), QString::number(format.relativeBackgroundSaturation())); + if (!qFuzzyIsNull(format.relativeBackgroundLightness())) + w.writeAttribute(QLatin1String("relativeBackgroundLightness"), QString::number(format.relativeBackgroundLightness())); w.writeEndElement(); } @@ -339,6 +385,10 @@ void ColorSchemeReader::readStyle() bool italic = attr.value(QLatin1String("italic")) == QLatin1String(trueString); QString underlineColor = attr.value(QLatin1String("underlineColor")).toString(); QString underlineStyle = attr.value(QLatin1String("underlineStyle")).toString(); + double relativeForegroundSaturation = attr.value(QLatin1String("relativeForegroundSaturation")).toDouble(); + double relativeForegroundLightness = attr.value(QLatin1String("relativeForegroundLightness")).toDouble(); + double relativeBackgroundSaturation = attr.value(QLatin1String("relativeBackgroundSaturation")).toDouble(); + double relativeBackgroundLightness = attr.value(QLatin1String("relativeBackgroundLightness")).toDouble(); Format format; @@ -362,6 +412,11 @@ void ColorSchemeReader::readStyle() format.setUnderlineStyle(stringToUnderlineStyle(underlineStyle)); + format.setRelativeForegroundSaturation(relativeForegroundSaturation); + format.setRelativeForegroundLightness(relativeForegroundLightness); + format.setRelativeBackgroundSaturation(relativeBackgroundSaturation); + format.setRelativeBackgroundLightness(relativeBackgroundLightness); + m_scheme->setFormatFor(Constants::styleFromName(name), format); skipCurrentElement(); diff --git a/src/plugins/texteditor/colorscheme.h b/src/plugins/texteditor/colorscheme.h index f065b186489..b91c44bf16d 100644 --- a/src/plugins/texteditor/colorscheme.h +++ b/src/plugins/texteditor/colorscheme.h @@ -52,6 +52,18 @@ public: QColor background() const { return m_background; } void setBackground(const QColor &background); + double relativeForegroundSaturation() const { return m_relativeForegroundSaturation; } + void setRelativeForegroundSaturation(double relativeForegroundSaturation); + + double relativeForegroundLightness() const { return m_relativeForegroundLightness; } + void setRelativeForegroundLightness(double relativeForegroundLightness); + + double relativeBackgroundSaturation() const { return m_relativeBackgroundSaturation; } + void setRelativeBackgroundSaturation(double relativeBackgroundSaturation); + + double relativeBackgroundLightness() const { return m_relativeBackgroundLightness; } + void setRelativeBackgroundLightness(double relativeBackgroundLightness); + bool bold() const { return m_bold; } void setBold(bool bold); @@ -73,6 +85,10 @@ private: QColor m_foreground = Qt::black; QColor m_background = Qt::white; QColor m_underlineColor; + double m_relativeForegroundSaturation = 0.0; + double m_relativeForegroundLightness = 0.0; + double m_relativeBackgroundSaturation = 0.0; + double m_relativeBackgroundLightness = 0.0; QTextCharFormat::UnderlineStyle m_underlineStyle = QTextCharFormat::NoUnderline; bool m_bold = false; bool m_italic = false; diff --git a/src/plugins/texteditor/colorschemeedit.cpp b/src/plugins/texteditor/colorschemeedit.cpp index 22bbbd27da6..b096c18e674 100644 --- a/src/plugins/texteditor/colorschemeedit.cpp +++ b/src/plugins/texteditor/colorschemeedit.cpp @@ -166,6 +166,14 @@ ColorSchemeEdit::ColorSchemeEdit(QWidget *parent) : this, &ColorSchemeEdit::eraseBackColor); connect(m_ui->eraseForegroundToolButton, &QAbstractButton::clicked, this, &ColorSchemeEdit::eraseForeColor); + connect(m_ui->foregroundSaturationSpinBox, static_cast(&QDoubleSpinBox::valueChanged), + this, &ColorSchemeEdit::changeRelativeForeColor); + connect(m_ui->foregroundLightnessSpinBox, static_cast(&QDoubleSpinBox::valueChanged), + this, &ColorSchemeEdit::changeRelativeForeColor); + connect(m_ui->backgroundSaturationSpinBox, static_cast(&QDoubleSpinBox::valueChanged), + this, &ColorSchemeEdit::changeRelativeBackColor); + connect(m_ui->backgroundLightnessSpinBox, static_cast(&QDoubleSpinBox::valueChanged), + this, &ColorSchemeEdit::changeRelativeBackColor); connect(m_ui->boldCheckBox, &QAbstractButton::toggled, this, &ColorSchemeEdit::checkCheckBoxes); connect(m_ui->italicCheckBox, &QAbstractButton::toggled, @@ -211,6 +219,16 @@ void ColorSchemeEdit::setReadOnly(bool readOnly) m_ui->backgroundToolButton->setEnabled(enabled); m_ui->eraseBackgroundToolButton->setEnabled(enabled); m_ui->eraseForegroundToolButton->setEnabled(enabled); + m_ui->relativeForegroundLabel->setEnabled(enabled); + m_ui->foregroundSaturationLabel->setEnabled(enabled); + m_ui->foregroundLightnessLabel->setEnabled(enabled); + m_ui->foregroundSaturationSpinBox->setEnabled(enabled); + m_ui->foregroundLightnessSpinBox->setEnabled(enabled); + m_ui->relativeBackgroundLabel->setEnabled(enabled); + m_ui->backgroundSaturationLabel->setEnabled(enabled); + m_ui->backgroundLightnessLabel->setEnabled(enabled); + m_ui->backgroundSaturationSpinBox->setEnabled(enabled); + m_ui->backgroundLightnessSpinBox->setEnabled(enabled); m_ui->boldCheckBox->setEnabled(enabled); m_ui->italicCheckBox->setEnabled(enabled); m_ui->underlineColorToolButton->setEnabled(enabled); @@ -244,6 +262,8 @@ void ColorSchemeEdit::updateControls() { updateForegroundControls(); updateBackgroundControls(); + updateRelativeForegroundControls(); + updateRelativeBackgroundControls(); updateFontControls(); updateUnderlineControls(); } @@ -282,6 +302,46 @@ void ColorSchemeEdit::updateBackgroundControls() && format.background().isValid()); } +void ColorSchemeEdit::updateRelativeForegroundControls() +{ + const auto &formatDescription = m_descriptions[m_curItem]; + const Format &format = m_scheme.formatFor(formatDescription.id()); + + QSignalBlocker saturationSignalBlocker(m_ui->foregroundSaturationSpinBox); + QSignalBlocker lightnessSignalBlocker(m_ui->foregroundLightnessSpinBox); + + bool isVisible = formatDescription.showControl(FormatDescription::ShowRelativeForegroundControl); + + m_ui->relativeForegroundLabel->setVisible(isVisible); + m_ui->foregroundSaturationLabel->setVisible(isVisible); + m_ui->foregroundLightnessLabel->setVisible(isVisible); + m_ui->foregroundSaturationSpinBox->setVisible(isVisible); + m_ui->foregroundLightnessSpinBox->setVisible(isVisible); + + m_ui->foregroundSaturationSpinBox->setValue(format.relativeForegroundSaturation()); + m_ui->foregroundLightnessSpinBox->setValue(format.relativeForegroundLightness()); +} + +void ColorSchemeEdit::updateRelativeBackgroundControls() +{ + const auto &formatDescription = m_descriptions[m_curItem]; + const Format &format = m_scheme.formatFor(formatDescription.id()); + + QSignalBlocker saturationSignalBlocker(m_ui->backgroundSaturationSpinBox); + QSignalBlocker lightnessSignalBlocker(m_ui->backgroundLightnessSpinBox); + + bool isVisible = formatDescription.showControl(FormatDescription::ShowRelativeBackgroundControl); + + m_ui->relativeBackgroundLabel->setVisible(isVisible); + m_ui->backgroundSaturationLabel->setVisible(isVisible); + m_ui->backgroundLightnessLabel->setVisible(isVisible); + m_ui->backgroundSaturationSpinBox->setVisible(isVisible); + m_ui->backgroundLightnessSpinBox->setVisible(isVisible); + + m_ui->backgroundSaturationSpinBox->setValue(format.relativeBackgroundSaturation()); + m_ui->backgroundLightnessSpinBox->setValue(format.relativeBackgroundLightness()); +} + void ColorSchemeEdit::updateFontControls() { const auto formatDescription = m_descriptions[m_curItem]; @@ -391,6 +451,70 @@ void ColorSchemeEdit::eraseForeColor() } } +void ColorSchemeEdit::changeRelativeForeColor() +{ + if (m_curItem == -1) + return; + + double saturation = m_ui->foregroundSaturationSpinBox->value(); + double lightness = m_ui->foregroundLightnessSpinBox->value(); + + for (const QModelIndex &index : m_ui->itemList->selectionModel()->selectedRows()) { + const TextStyle category = m_descriptions[index.row()].id(); + m_scheme.formatFor(category).setRelativeForegroundSaturation(saturation); + m_scheme.formatFor(category).setRelativeForegroundLightness(lightness); + m_formatsModel->emitDataChanged(index); + } +} + +void ColorSchemeEdit::changeRelativeBackColor() +{ + if (m_curItem == -1) + return; + + double saturation = m_ui->backgroundSaturationSpinBox->value(); + double lightness = m_ui->backgroundLightnessSpinBox->value(); + + for (const QModelIndex &index : m_ui->itemList->selectionModel()->selectedRows()) { + const TextStyle category = m_descriptions[index.row()].id(); + m_scheme.formatFor(category).setRelativeBackgroundSaturation(saturation); + m_scheme.formatFor(category).setRelativeBackgroundLightness(lightness); + m_formatsModel->emitDataChanged(index); + } +} + +void ColorSchemeEdit::eraseRelativeForeColor() +{ + if (m_curItem == -1) + return; + + m_ui->foregroundSaturationSpinBox->setValue(0.0); + m_ui->foregroundLightnessSpinBox->setValue(0.0); + + foreach (const QModelIndex &index, m_ui->itemList->selectionModel()->selectedRows()) { + const TextStyle category = m_descriptions[index.row()].id(); + m_scheme.formatFor(category).setRelativeForegroundSaturation(0.0); + m_scheme.formatFor(category).setRelativeForegroundLightness(0.0); + m_formatsModel->emitDataChanged(index); + } +} + +void ColorSchemeEdit::eraseRelativeBackColor() +{ + if (m_curItem == -1) + return; + + m_ui->backgroundSaturationSpinBox->setValue(0.0); + m_ui->backgroundLightnessSpinBox->setValue(0.0); + + foreach (const QModelIndex &index, m_ui->itemList->selectionModel()->selectedRows()) { + const TextStyle category = m_descriptions[index.row()].id(); + m_scheme.formatFor(category).setRelativeBackgroundSaturation(0.0); + m_scheme.formatFor(category).setRelativeBackgroundLightness(0.0); + m_formatsModel->emitDataChanged(index); + } +} + void ColorSchemeEdit::checkCheckBoxes() { if (m_curItem == -1) diff --git a/src/plugins/texteditor/colorschemeedit.h b/src/plugins/texteditor/colorschemeedit.h index eb2f50fd3f4..79ce8173537 100644 --- a/src/plugins/texteditor/colorschemeedit.h +++ b/src/plugins/texteditor/colorschemeedit.h @@ -63,8 +63,12 @@ private: void currentItemChanged(const QModelIndex &index); void changeForeColor(); void changeBackColor(); - void eraseBackColor(); void eraseForeColor(); + void eraseBackColor(); + void changeRelativeForeColor(); + void changeRelativeBackColor(); + void eraseRelativeForeColor(); + void eraseRelativeBackColor(); void checkCheckBoxes(); void changeUnderlineColor(); void eraseUnderlineColor(); @@ -73,6 +77,8 @@ private: void updateControls(); void updateForegroundControls(); void updateBackgroundControls(); + void updateRelativeForegroundControls(); + void updateRelativeBackgroundControls(); void updateFontControls(); void updateUnderlineControls(); void setItemListBackground(const QColor &color); diff --git a/src/plugins/texteditor/colorschemeedit.ui b/src/plugins/texteditor/colorschemeedit.ui index 469ec13ca94..f004879a53f 100644 --- a/src/plugins/texteditor/colorschemeedit.ui +++ b/src/plugins/texteditor/colorschemeedit.ui @@ -7,27 +7,45 @@ 0 0 435 - 210 + 261 - - - - - 1 - 0 - - - - QAbstractItemView::ExtendedSelection - - - true + + + + Saturation - + + + + -1.000000000000000 + + + 1.000000000000000 + + + 0.050000000000000 + + + + + + + Lightness + + + + + + + Saturation + + + + @@ -43,7 +61,14 @@ - + + + + Italic + + + + @@ -73,67 +98,37 @@ - - - - - 0 - 0 - + + + + Qt::Vertical + + + 20 + 83 + + + + + + - Background: - - - backgroundToolButton + Relative Foreground - - - - - - - 0 - 0 - - - - - - - - - - - Erase background. - - - x - - - Qt::LeftArrow - - - - - - + Bold - - - - Italic - - + + - + @@ -149,7 +144,23 @@ - + + + + + 1 + 0 + + + + QAbstractItemView::ExtendedSelection + + + true + + + + @@ -179,21 +190,104 @@ - - + + + + -1.000000000000000 + + + 1.000000000000000 + + + 0.050000000000000 + + - - - - Qt::Vertical + + + + + 0 + 0 + - - - 20 - 83 - + + Background: - + + backgroundToolButton + + + + + + + + + + 0 + 0 + + + + + + + + + + + Erase background. + + + x + + + Qt::LeftArrow + + + + + + + + + Lightness + + + + + + + Relative Backgound + + + + + + + -1.000000000000000 + + + 1.000000000000000 + + + 0.050000000000000 + + + + + + + -1.000000000000000 + + + 1.000000000000000 + + + 0.050000000000000 + + diff --git a/src/plugins/texteditor/fontsettings.cpp b/src/plugins/texteditor/fontsettings.cpp index 20c4761aaa2..e0017a4e896 100644 --- a/src/plugins/texteditor/fontsettings.cpp +++ b/src/plugins/texteditor/fontsettings.cpp @@ -39,6 +39,8 @@ #include #include +#include + static const char fontFamilyKey[] = "FontFamily"; static const char fontSizeKey[] = "FontSize"; static const char fontZoomKey[] = "FontZoom"; @@ -193,26 +195,59 @@ bool operator==(const TextStyles &first, const TextStyles &second) && first.mixinStyles == second.mixinStyles; } +namespace { + +double clamp(double value) +{ + return std::max(0.0, std::min(1.0, value)); +} + +QBrush mixBrush(const QBrush &original, double relativeSaturation, double relativeLightness) +{ + const QColor originalColor = original.color().toHsl(); + QColor mixedColor(QColor::Hsl); + + double mixedSaturation = clamp(originalColor.hslSaturationF() + relativeSaturation); + + double mixedLightness = clamp(originalColor.lightnessF() + relativeLightness); + + mixedColor.setHslF(originalColor.hslHueF(), mixedSaturation, mixedLightness); + + return mixedColor; +} +} + void FontSettings::addMixinStyle(QTextCharFormat &textCharFormat, const MixinTextStyles &mixinStyles) const { for (TextStyle mixinStyle : mixinStyles) { - const QTextCharFormat mixinTextCharFormat = toTextCharFormat(mixinStyle); - if (!textCharFormat.hasProperty(QTextFormat::ForegroundBrush)) - textCharFormat.setForeground(mixinTextCharFormat.foreground()); + const Format &format = m_scheme.formatFor(mixinStyle); - if (!textCharFormat.hasProperty(QTextFormat::BackgroundBrush)) - textCharFormat.setBackground(mixinTextCharFormat.background()); + if (textCharFormat.hasProperty(QTextFormat::ForegroundBrush)) { + textCharFormat.setForeground(mixBrush(textCharFormat.foreground(), + format.relativeForegroundSaturation(), + format.relativeForegroundLightness())); + } + + if (textCharFormat.hasProperty(QTextFormat::BackgroundBrush)) { + textCharFormat.setBackground(mixBrush(textCharFormat.background(), + format.relativeBackgroundSaturation(), + format.relativeBackgroundLightness())); + } else { + textCharFormat.setBackground(mixBrush(m_scheme.formatFor(C_TEXT).background(), + format.relativeBackgroundSaturation(), + format.relativeBackgroundLightness())); + } if (!textCharFormat.fontItalic()) - textCharFormat.setFontItalic(mixinTextCharFormat.fontItalic()); + textCharFormat.setFontItalic(format.italic()); if (textCharFormat.fontWeight() == QFont::Normal) - textCharFormat.setFontWeight(mixinTextCharFormat.fontWeight()); + textCharFormat.setFontWeight(format.bold() ? QFont::Bold : QFont::Normal); if (textCharFormat.underlineStyle() == QTextCharFormat::NoUnderline) { - textCharFormat.setUnderlineStyle(mixinTextCharFormat.underlineStyle()); - textCharFormat.setUnderlineColor(mixinTextCharFormat.underlineColor()); + textCharFormat.setUnderlineStyle(format.underlineStyle()); + textCharFormat.setUnderlineColor(format.underlineColor()); } }; } @@ -373,6 +408,10 @@ bool FontSettings::loadColorScheme(const QString &fileName, format.setForeground(descFormat.foreground()); format.setBackground(descFormat.background()); } + format.setRelativeForegroundSaturation(descFormat.relativeForegroundSaturation()); + format.setRelativeForegroundLightness(descFormat.relativeForegroundLightness()); + format.setRelativeBackgroundSaturation(descFormat.relativeBackgroundSaturation()); + format.setRelativeBackgroundLightness(descFormat.relativeBackgroundLightness()); format.setBold(descFormat.bold()); format.setItalic(descFormat.italic()); format.setUnderlineColor(descFormat.underlineColor()); diff --git a/src/plugins/texteditor/fontsettingspage.h b/src/plugins/texteditor/fontsettingspage.h index 6dfb5f1da74..2def49a2a86 100644 --- a/src/plugins/texteditor/fontsettingspage.h +++ b/src/plugins/texteditor/fontsettingspage.h @@ -56,7 +56,12 @@ public: ShowBackgroundControl = 0x2, ShowFontControls = 0x4, ShowUnderlineControl = 0x8, - ShowFontAndUnderlineControls = ShowFontControls | ShowUnderlineControl, + ShowRelativeForegroundControl = 0x10, + ShowRelativeBackgroundControl = 0x20, + ShowFontUnderlineAndRelativeControls = ShowFontControls + | ShowUnderlineControl + | ShowRelativeForegroundControl + | ShowRelativeBackgroundControl, AllControls = 0xF, AllControlsExceptUnderline = AllControls & ~ShowUnderlineControl, }; diff --git a/src/plugins/texteditor/texteditorsettings.cpp b/src/plugins/texteditor/texteditorsettings.cpp index 6a479f9f50e..67270d81bbd 100644 --- a/src/plugins/texteditor/texteditorsettings.cpp +++ b/src/plugins/texteditor/texteditorsettings.cpp @@ -312,7 +312,7 @@ TextEditorSettings::TextEditorSettings(QObject *parent) formatDescr.emplace_back(C_DECLARATION, tr("Declaration"), tr("Declaration of a function, variable, and so on."), - FormatDescription::ShowFontAndUnderlineControls); + FormatDescription::ShowFontUnderlineAndRelativeControls); d->m_fontSettingsPage = new FontSettingsPage(formatDescr, Constants::TEXT_EDITOR_FONT_SETTINGS,