Commit b0f16d56 authored by Martin Seher's avatar Martin Seher Committed by Milian Wolff
Browse files

Configurable semantic colors

Add a page under _Color Themes -> Highlighting Text Styles -> KDevelop/Semantic Colors_ that allows the configuration of the semantic highlight colors.
- When the _Local colorization intensity_ is bigger than zero then the rainbow colors are used for local variables like before, overwriting the corresponding configured colors
- A _Global colorization intensity_ less then 255 (max) will still cause a blending of the global colors
- _Bold font for declarations_ will make the declarations bold in addition to the bold settings from the config dialog

So a _Local colorization intensity_ of 0 and a _Global colorization intensity_ of 255 should be set when the exact configured colors are desired.

See also:
https://invent.kde.org/kdevelop/kdevelop/uploads/500467bc355906d363e3a76a9044e138/ColorConfig.png

BUG: 395856
parent 6c2ef5e8
......@@ -151,6 +151,7 @@ set(KDevPlatformLanguage_LIB_SRCS
highlighting/colorcache.cpp
highlighting/configurablecolors.cpp
highlighting/codehighlighting.cpp
highlighting/syntax/syntax.qrc
checks/dataaccessrepository.cpp checks/dataaccess.cpp
checks/controlflowgraph.cpp checks/controlflownode.cpp
......
......@@ -26,12 +26,60 @@
#include <KTextEditor/Document>
#include <KTextEditor/View>
#include <KTextEditor/ConfigInterface>
#include <KSyntaxHighlighting/Definition>
#include <KSyntaxHighlighting/Format>
#define ifDebug(x)
namespace KDevelop {
ColorCache* ColorCache::m_self = nullptr;
CodeHighlightingType getHighlightingTypeFromName(const QString& name)
{
if (name == QLatin1String("Class")) {
return CodeHighlightingType::Class;
} else if (name == QLatin1String("Local Member Variable")) {
return CodeHighlightingType::LocalClassMember;
} else if (name == QLatin1String("Local Member Function")) {
return CodeHighlightingType::LocalMemberFunction;
} else if (name == QLatin1String("Inherited Member Variable")) {
return CodeHighlightingType::InheritedClassMember;
} else if (name == QLatin1String("Inherited Member Function")) {
return CodeHighlightingType::InheritedMemberFunction;
} else if (name == QLatin1String("Function")) {
return CodeHighlightingType::Function;
} else if (name == QLatin1String("Function Argument")) {
return CodeHighlightingType::FunctionVariable;
} else if (name == QLatin1String("Type Alias")) {
return CodeHighlightingType::TypeAlias;
} else if (name == QLatin1String("Forward Declaration")) {
return CodeHighlightingType::ForwardDeclaration;
} else if (name == QLatin1String("Namespace")) {
return CodeHighlightingType::Namespace;
} else if (name == QLatin1String("Local Variable")) {
return CodeHighlightingType::LocalVariable;
} else if (name == QLatin1String("Global Variable")) {
return CodeHighlightingType::GlobalVariable;
} else if (name == QLatin1String("Member Variable")) {
return CodeHighlightingType::MemberVariable;
} else if (name == QLatin1String("Namespace Variable")) {
return CodeHighlightingType::NamespaceVariable;
} else if (name == QLatin1String("Enumeration")) {
return CodeHighlightingType::Enum;
} else if (name == QLatin1String("Enumerator")) {
return CodeHighlightingType::Enumerator;
} else if (name == QLatin1String("Macro")) {
return CodeHighlightingType::Macro;
} else if (name == QLatin1String("Macro Function")) {
return CodeHighlightingType::MacroFunctionLike;
} else if (name == QLatin1String("Highlight Uses")) {
return CodeHighlightingType::HighlightUses;
} else if (name == QLatin1String("Error Variable")) {
return CodeHighlightingType::ErrorVariable;
}
return CodeHighlightingType::Unknown;
}
ColorCache::ColorCache(QObject* parent)
: QObject(parent)
, m_defaultColors(new ConfigurableHighlightingColors)
......@@ -91,7 +139,8 @@ ColorCache* ColorCache::self()
void ColorCache::generateColors()
{
m_defaultColors->reset(this);
// FIXME:
// m_defaultColors->reset(this);
// Primary colors taken from: http://colorbrewer2.org/?type=qualitative&scheme=Paired&n=12
const QColor colors[] = {
......@@ -184,6 +233,7 @@ void ColorCache::updateColorsFromView(KTextEditor::View* view)
#endif
m_view = view;
bool anyAttrChanged = false;
if (!foreground.isValid()) {
// fallback to colorscheme variant
ifDebug(qCDebug(LANGUAGE) << "updating from scheme"; )
......@@ -191,12 +241,89 @@ void ColorCache::updateColorsFromView(KTextEditor::View* view)
} else if (m_foregroundColor != foreground || m_backgroundColor != background) {
m_foregroundColor = foreground;
m_backgroundColor = background;
anyAttrChanged = true;
}
anyAttrChanged |= updateColorsFromTheme(view->theme());
if (anyAttrChanged) {
ifDebug(qCDebug(LANGUAGE) << "updating from document"; )
update();
}
}
bool ColorCache::updateColorsFromTheme(const KSyntaxHighlighting::Theme& theme)
{
// from ktexteditor/src/syntax/kateextendedattribute.h
static const int SelectedBackground = QTextFormat::UserProperty + 2;
const auto schemeDefinition = m_schemeRepo.definitionForName(QStringLiteral("Semantic Colors"));
const auto formats = schemeDefinition.formats();
const bool blendColors = m_globalColorRatio < 255;
bool anyAttrChanged = false;
for (const auto& format : formats) {
const auto type = getHighlightingTypeFromName(format.name());
const auto attr = m_defaultColors->attribute(type);
auto fg = format.textColor(theme);
auto selFg = format.selectedTextColor(theme);
if (blendColors) {
fg = blendGlobalColor(fg);
selFg = blendGlobalColor(selFg);
}
if (attr->fontBold() != format.isBold(theme)) {
attr->setFontBold(format.isBold(theme));
anyAttrChanged = true;
}
if (attr->fontItalic() != format.isItalic(theme)) {
attr->setFontItalic(format.isItalic(theme));
anyAttrChanged = true;
}
if (attr->fontUnderline() != format.isUnderline(theme)) {
attr->setFontUnderline(format.isUnderline(theme));
anyAttrChanged = true;
}
if (attr->fontStrikeOut() != format.isStrikeThrough(theme)) {
attr->setFontStrikeOut(format.isStrikeThrough(theme));
anyAttrChanged = true;
}
if (attr->foreground().color() != fg) {
attr->setForeground(fg);
anyAttrChanged = true;
}
if (attr->selectedForeground().color() != selFg) {
attr->setSelectedForeground(selFg);
anyAttrChanged = true;
}
if (format.hasBackgroundColor(theme)) {
if (attr->background().color() != format.backgroundColor(theme)) {
attr->setBackground(format.backgroundColor(theme));
anyAttrChanged = true;
}
} else if (type == CodeHighlightingType::HighlightUsesType ) {
auto background = QColor(theme.editorColor(KSyntaxHighlighting::Theme::SearchHighlight));
if (attr->background().color() != background) {
attr->setBackground(background);
anyAttrChanged = true;
}
} else if (attr->background() != QBrush()) {
attr->setBackground(QBrush());
anyAttrChanged = true;
}
// from KSyntaxHighlighting::Format::isDefaultTextStyle
if (format.selectedBackgroundColor(theme).rgba() != theme.selectedBackgroundColor(KSyntaxHighlighting::Theme::Normal)) {
if (attr->selectedBackground().color() != format.selectedBackgroundColor(theme)) {
attr->setSelectedBackground(format.selectedBackgroundColor(theme));
anyAttrChanged = true;
}
} else if (attr->hasProperty(SelectedBackground)) {
attr->clearProperty(SelectedBackground);
anyAttrChanged = true;
}
}
return anyAttrChanged;
}
void ColorCache::updateColorsFromScheme()
{
KColorScheme scheme(QPalette::Normal, KColorScheme::View);
......@@ -216,10 +343,14 @@ void ColorCache::updateColorsFromSettings()
int localRatio = ICore::self()->languageController()->completionSettings()->localColorizationLevel();
int globalRatio = ICore::self()->languageController()->completionSettings()->globalColorizationLevel();
bool boldDeclartions = ICore::self()->languageController()->completionSettings()->boldDeclarations();
bool globalRatioChanged = globalRatio != m_globalColorRatio;
if (localRatio != m_localColorRatio || globalRatio != m_globalColorRatio) {
if (localRatio != m_localColorRatio || globalRatioChanged) {
m_localColorRatio = localRatio;
m_globalColorRatio = globalRatio;
if (m_view && globalRatioChanged) {
updateColorsFromTheme(m_view->theme());
}
update();
}
if (boldDeclartions != m_boldDeclarations) {
......
......@@ -11,9 +11,14 @@
#include <QVector>
#include <QColor>
#include <QPointer>
#include <KSyntaxHighlighting/Repository>
#include <language/languageexport.h>
namespace KSyntaxHighlighting {
class Theme;
}
namespace KTextEditor {
class Document;
class View;
......@@ -126,6 +131,8 @@ private:
/// @see generateColors(), updateColorsFromScheme()
void updateColorsFromView(KTextEditor::View* view);
bool updateColorsFromTheme(const KSyntaxHighlighting::Theme& theme);
/// the default colors for the different types
ConfigurableHighlightingColors* m_defaultColors;
......@@ -158,6 +165,8 @@ private:
/// The view we are listening to for setting changes.
QPointer<KTextEditor::View> m_view;
KSyntaxHighlighting::Repository m_schemeRepo;
};
}
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<language
name="Semantic Colors"
section="KDevelop"
version="1"
kateversion="5.0"
mimetype=""
extensions=""
author="Martin Seher (martin.seher@gmail.com)"
hidden="true"
>
<highlighting>
<contexts>
<context attribute="Class" lineEndContext="#stay" name="Normal">
</context>
</contexts>
<itemDatas>
<itemData name="Class" defStyleNum="dsDataType" spellChecking="false" bold="0" italic="0" />
<itemData name="Local Member Variable" defStyleNum="dsVariable" spellChecking="false" />
<itemData name="Local Member Function" defStyleNum="dsFunction" spellChecking="false" />
<itemData name="Inherited Member Variable" defStyleNum="dsVariable" spellChecking="false" />
<itemData name="Inherited Member Function" defStyleNum="dsFunction" spellChecking="false" />
<itemData name="Function" defStyleNum="dsFunction" spellChecking="false" />
<itemData name="Function Argument" defStyleNum="dsNormal" spellChecking="false" />
<itemData name="Type Alias" defStyleNum="dsDataType" spellChecking="false" bold="0" italic="0" />
<itemData name="Forward Declaration" defStyleNum="dsNormal" spellChecking="false" />
<itemData name="Namespace" defStyleNum="dsNormal" spellChecking="false" />
<itemData name="Local Variable" defStyleNum="dsVariable" spellChecking="false" />
<itemData name="Global Variable" defStyleNum="dsVariable" spellChecking="false" />
<itemData name="Member Variable" defStyleNum="dsVariable" spellChecking="false" />
<itemData name="Namespace Variable" defStyleNum="dsVariable" spellChecking="false" />
<itemData name="Enumeration" defStyleNum="dsNormal" spellChecking="false" />
<itemData name="Enumerator" defStyleNum="dsNormal" spellChecking="false" />
<itemData name="Macro" defStyleNum="dsPreprocessor" spellChecking="false" />
<itemData name="Macro Function" defStyleNum="dsPreprocessor" spellChecking="false" />
<itemData name="Highlight Uses" defStyleNum="dsNormal" spellChecking="false" />
<itemData name="Error Variable" defStyleNum="dsError" spellChecking="false" />
</itemDatas>
</highlighting>
</language>
<!-- kate: indent-width 2; tab-width 2; -->
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/org.kde.syntax-highlighting/syntax-addons">
<file>kdevelop-semantic-colors.xml</file>
</qresource>
</RCC>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment