plugins/colorblindnesscorrection: support adjusting intensity
Though there are 3 common CVD types, each individual can have different color perception level, and the default intensity might not be suitable for everyone, so add an intensity slider to select how much the filter affects the display.
This commit is contained in:
parent
1f1c54ca6c
commit
f650ebe2fc
12 changed files with 63 additions and 24 deletions
|
@ -6,7 +6,13 @@ kwin_add_builtin_effect(colorblindnesscorrection
|
|||
colorblindnesscorrection.qrc
|
||||
main.cpp
|
||||
)
|
||||
kconfig_add_kcfg_files(colorblindnesscorrection colorblindnesscorrection_settings.kcfgc GENERATE_MOC)
|
||||
set(SETTINGS_HEADER "colorblindnesscorrection_settings_singleton")
|
||||
set(GENERATE_MOC "false")
|
||||
set(USE_SINGLETON "true")
|
||||
set(KCFGFILE_ARGS "arg=\"true\"")
|
||||
configure_file(colorblindnesscorrection_settings.kcfgc.in ${CMAKE_CURRENT_BINARY_DIR}/${SETTINGS_HEADER}.kcfgc @ONLY)
|
||||
configure_file(colorblindnesscorrection_settings.kcfg.in ${CMAKE_CURRENT_BINARY_DIR}/${SETTINGS_HEADER}.kcfg @ONLY)
|
||||
kconfig_add_kcfg_files(colorblindnesscorrection ${CMAKE_CURRENT_BINARY_DIR}/${SETTINGS_HEADER}.kcfgc)
|
||||
target_link_libraries(colorblindnesscorrection PRIVATE
|
||||
kwin
|
||||
|
||||
|
@ -19,14 +25,20 @@ if (NOT KWIN_BUILD_KCMS)
|
|||
return()
|
||||
endif()
|
||||
|
||||
set(SETTINGS_HEADER "colorblindnesscorrection_settings")
|
||||
kcmutils_add_qml_kcm(kwin_colorblindnesscorrection_config SOURCES colorblindnesscorrection_config.cpp INSTALL_NAMESPACE "kwin/effects/configs" DISABLE_DESKTOP_FILE_GENERATION)
|
||||
kcmutils_generate_module_data(kwin_colorblindnesscorrection_config
|
||||
MODULE_DATA_HEADER colorblindnesscorrection_settingsdata.h
|
||||
MODULE_DATA_CLASS_NAME ColorBlindnessCorrectionSettingsData
|
||||
SETTINGS_HEADERS colorblindnesscorrection_settings.h
|
||||
SETTINGS_HEADERS ${SETTINGS_HEADER}.h
|
||||
SETTINGS_CLASSES ColorBlindnessCorrectionSettings
|
||||
)
|
||||
kconfig_add_kcfg_files(kwin_colorblindnesscorrection_config colorblindnesscorrection_settings.kcfgc GENERATE_MOC)
|
||||
set(GENERATE_MOC "true")
|
||||
set(USE_SINGLETON "false")
|
||||
set(KCFGFILE_ARGS "name=\"kwinrc\"")
|
||||
configure_file(colorblindnesscorrection_settings.kcfgc.in ${CMAKE_CURRENT_BINARY_DIR}/${SETTINGS_HEADER}.kcfgc @ONLY)
|
||||
configure_file(colorblindnesscorrection_settings.kcfg.in ${CMAKE_CURRENT_BINARY_DIR}/${SETTINGS_HEADER}.kcfg @ONLY)
|
||||
kconfig_add_kcfg_files(kwin_colorblindnesscorrection_config ${CMAKE_CURRENT_BINARY_DIR}/colorblindnesscorrection_settings.kcfgc GENERATE_MOC)
|
||||
target_link_libraries(kwin_colorblindnesscorrection_config
|
||||
KF6::ConfigCore
|
||||
KF6::KCMUtils
|
||||
|
|
|
@ -6,12 +6,10 @@
|
|||
|
||||
#include "colorblindnesscorrection.h"
|
||||
|
||||
#include <KSharedConfig>
|
||||
|
||||
#include "effect/effecthandler.h"
|
||||
#include "opengl/glshader.h"
|
||||
|
||||
#include "colorblindnesscorrection_settings.h"
|
||||
#include "colorblindnesscorrection_settings_singleton.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(KWIN_COLORBLINDNESS_CORRECTION, "kwin_effect_colorblindnesscorrection", QtWarningMsg)
|
||||
|
||||
|
@ -26,8 +24,11 @@ namespace KWin
|
|||
|
||||
ColorBlindnessCorrectionEffect::ColorBlindnessCorrectionEffect()
|
||||
: OffscreenEffect()
|
||||
, m_mode(static_cast<Mode>(ColorBlindnessCorrectionSettings().mode()))
|
||||
{
|
||||
ColorBlindnessCorrectionSettings::instance(effects->config());
|
||||
m_mode = static_cast<Mode>(ColorBlindnessCorrectionSettings::mode());
|
||||
m_intensity = std::clamp<float>(ColorBlindnessCorrectionSettings::intensity(), 0.0f, 1.0f);
|
||||
|
||||
loadData();
|
||||
}
|
||||
|
||||
|
@ -65,6 +66,10 @@ void ColorBlindnessCorrectionEffect::loadData()
|
|||
return;
|
||||
}
|
||||
|
||||
if (ShaderBinder binder{m_shader.get()}; !m_shader->setUniform("intensity", m_intensity)) {
|
||||
qCWarning(KWIN_COLORBLINDNESS_CORRECTION) << "Failed to set intensity";
|
||||
}
|
||||
|
||||
for (const auto windows = effects->stackingOrder(); EffectWindow * w : windows) {
|
||||
correctColor(w);
|
||||
}
|
||||
|
@ -108,12 +113,15 @@ void ColorBlindnessCorrectionEffect::reconfigure(ReconfigureFlags flags)
|
|||
return;
|
||||
}
|
||||
|
||||
auto newMode = static_cast<Mode>(ColorBlindnessCorrectionSettings().mode());
|
||||
if (m_mode == newMode) {
|
||||
ColorBlindnessCorrectionSettings::self()->read();
|
||||
const auto newMode = static_cast<Mode>(ColorBlindnessCorrectionSettings::mode());
|
||||
const auto newIntensity = std::clamp<float>(ColorBlindnessCorrectionSettings::intensity(), 0.0f, 1.0f);
|
||||
if (m_mode == newMode && qFuzzyCompare(m_intensity, newIntensity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_mode = newMode;
|
||||
m_intensity = newIntensity;
|
||||
|
||||
disconnect(effects, &EffectsHandler::windowDeleted, this, &ColorBlindnessCorrectionEffect::slotWindowDeleted);
|
||||
disconnect(effects, &EffectsHandler::windowAdded, this, &ColorBlindnessCorrectionEffect::correctColor);
|
||||
|
|
|
@ -48,6 +48,7 @@ private:
|
|||
void loadData();
|
||||
|
||||
Mode m_mode = Protanopia;
|
||||
float m_intensity = 1.0f;
|
||||
|
||||
std::unordered_set<KWin::EffectWindow *> m_windows;
|
||||
std::unique_ptr<GLShader> m_shader;
|
||||
|
|
|
@ -7,10 +7,13 @@
|
|||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
|
||||
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
|
||||
<kcfgfile name="kwinrc" />
|
||||
<kcfgfile @KCFGFILE_ARGS@/>
|
||||
<group name="Effect-colorblindnesscorrection">
|
||||
<entry name="Mode" type="UInt">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
<entry name="Intensity" type="Double">
|
||||
<default>1.0</default>
|
||||
</entry>
|
||||
</group>
|
||||
</kcfg>
|
|
@ -1,9 +1,10 @@
|
|||
# SPDX-FileCopyrightText: 2023 Fushan Wen <qydwhotmail@gmail.com>
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
File=colorblindnesscorrection_settings.kcfg
|
||||
File=@SETTINGS_HEADERS@.kcfg
|
||||
ClassName=ColorBlindnessCorrectionSettings
|
||||
DefaultValueGetters=@GENERATE_MOC@
|
||||
GenerateProperties=@GENERATE_MOC@
|
||||
ParentInConstructor=@GENERATE_MOC@
|
||||
Singleton=@USE_SINGLETON@
|
||||
Mutators=true
|
||||
DefaultValueGetters=true
|
||||
GenerateProperties=true
|
||||
ParentInConstructor=true
|
|
@ -3,6 +3,7 @@
|
|||
uniform sampler2D sampler;
|
||||
uniform vec4 modulation;
|
||||
uniform float saturation;
|
||||
uniform float intensity;
|
||||
varying vec2 texcoord0;
|
||||
|
||||
void main()
|
||||
|
@ -27,7 +28,7 @@ void main()
|
|||
vec3 error = vec3((0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s),
|
||||
(-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s),
|
||||
(-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s));
|
||||
vec3 diff = tex.rgb - error;
|
||||
vec3 diff = (tex.rgb - error) * vec3(intensity);
|
||||
vec3 correction = vec3(0.0,
|
||||
(diff.r * 0.7) + (diff.g * 1.0),
|
||||
(diff.r * 0.7) + (diff.b * 1.0));
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
uniform sampler2D sampler;
|
||||
uniform vec4 modulation;
|
||||
uniform float saturation;
|
||||
|
||||
uniform float intensity;
|
||||
in vec2 texcoord0;
|
||||
out vec4 fragColor;
|
||||
|
||||
|
@ -30,7 +30,7 @@ void main()
|
|||
vec3 error = vec3((0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s),
|
||||
(-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s),
|
||||
(-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s));
|
||||
vec3 diff = tex.rgb - error;
|
||||
vec3 diff = (tex.rgb - error) * vec3(intensity);
|
||||
vec3 correction = vec3(0.0,
|
||||
(diff.r * 0.7) + (diff.g * 1.0),
|
||||
(diff.r * 0.7) + (diff.b * 1.0));
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
uniform sampler2D sampler;
|
||||
uniform vec4 modulation;
|
||||
uniform float saturation;
|
||||
uniform float intensity;
|
||||
varying vec2 texcoord0;
|
||||
|
||||
void main()
|
||||
|
@ -27,7 +28,7 @@ void main()
|
|||
vec3 error = vec3((0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s),
|
||||
(-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s),
|
||||
(-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s));
|
||||
vec3 diff = tex.rgb - error;
|
||||
vec3 diff = (tex.rgb - error) * vec3(intensity);
|
||||
vec3 correction = vec3(0.0,
|
||||
(diff.r * 0.7) + (diff.g * 1.0),
|
||||
(diff.r * 0.7) + (diff.b * 1.0));
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
uniform sampler2D sampler;
|
||||
uniform vec4 modulation;
|
||||
uniform float saturation;
|
||||
|
||||
uniform float intensity;
|
||||
in vec2 texcoord0;
|
||||
out vec4 fragColor;
|
||||
|
||||
|
@ -30,7 +30,7 @@ void main()
|
|||
vec3 error = vec3((0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s),
|
||||
(-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s),
|
||||
(-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s));
|
||||
vec3 diff = tex.rgb - error;
|
||||
vec3 diff = (tex.rgb - error) * vec3(intensity);
|
||||
vec3 correction = vec3(0.0,
|
||||
(diff.r * 0.7) + (diff.g * 1.0),
|
||||
(diff.r * 0.7) + (diff.b * 1.0));
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
uniform sampler2D sampler;
|
||||
uniform vec4 modulation;
|
||||
uniform float saturation;
|
||||
uniform float intensity;
|
||||
varying vec2 texcoord0;
|
||||
|
||||
void main()
|
||||
|
@ -27,7 +28,7 @@ void main()
|
|||
vec3 error = vec3((0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s),
|
||||
(-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s),
|
||||
(-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s));
|
||||
vec3 diff = tex.rgb - error;
|
||||
vec3 diff = (tex.rgb - error) * vec3(intensity);
|
||||
vec3 correction = vec3(0.0,
|
||||
(diff.r * 0.7) + (diff.g * 1.0),
|
||||
(diff.r * 0.7) + (diff.b * 1.0));
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
uniform sampler2D sampler;
|
||||
uniform vec4 modulation;
|
||||
uniform float saturation;
|
||||
|
||||
uniform float intensity;
|
||||
in vec2 texcoord0;
|
||||
out vec4 fragColor;
|
||||
|
||||
|
@ -30,7 +30,7 @@ void main()
|
|||
vec3 error = vec3((0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s),
|
||||
(-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s),
|
||||
(-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s));
|
||||
vec3 diff = tex.rgb - error;
|
||||
vec3 diff = (tex.rgb - error) * vec3(intensity);
|
||||
vec3 correction = vec3(0.0,
|
||||
(diff.r * 0.7) + (diff.g * 1.0),
|
||||
(diff.r * 0.7) + (diff.b * 1.0));
|
||||
|
|
|
@ -16,7 +16,7 @@ KCM.SimpleKCM {
|
|||
id: root
|
||||
|
||||
implicitWidth: Kirigami.Units.gridUnit * 30
|
||||
implicitHeight: Kirigami.Units.gridUnit * 22
|
||||
implicitHeight: Kirigami.Units.gridUnit * 24
|
||||
|
||||
RowLayout {
|
||||
id: previewArea
|
||||
|
@ -67,6 +67,7 @@ KCM.SimpleKCM {
|
|||
}
|
||||
|
||||
QQC.ComboBox {
|
||||
id: colorComboBox
|
||||
Kirigami.FormData.label: i18nc("@label", "Mode:")
|
||||
currentIndex: kcm.settings.mode
|
||||
textRole: "text"
|
||||
|
@ -79,5 +80,15 @@ KCM.SimpleKCM {
|
|||
|
||||
onActivated: kcm.settings.mode = currentValue
|
||||
}
|
||||
|
||||
QQC.Slider {
|
||||
Kirigami.FormData.label: i18nc("@label", "Intensity:")
|
||||
Layout.preferredWidth: colorComboBox.implicitWidth
|
||||
from: 0.0
|
||||
to: 1.0
|
||||
value: kcm.settings.intensity
|
||||
|
||||
onMoved: kcm.settings.intensity = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue