Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to change Icon Saturation #45924

Merged
merged 1 commit into from
Feb 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions core/io/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2985,6 +2985,26 @@ void Image::set_pixel(int p_x, int p_y, const Color &p_color) {
_set_color_at_ofs(data.ptrw(), ofs, p_color);
}

void Image::adjust_bcs(float p_brightness, float p_contrast, float p_saturation) {
uint8_t *w = data.ptrw();
uint32_t pixel_size = get_format_pixel_size(format);
uint32_t pixel_count = data.size() / pixel_size;

for (uint32_t i = 0; i < pixel_count; i++) {
Color c = _get_color_at_ofs(w, i);
Vector3 rgb(c.r, c.g, c.b);

rgb *= p_brightness;
rgb = Vector3(0.5, 0.5, 0.5).lerp(rgb, p_contrast);
float center = (rgb.x + rgb.y + rgb.z) / 3.0;
rgb = Vector3(center, center, center).lerp(rgb, p_saturation);
c.r = rgb.x;
c.g = rgb.y;
c.b = rgb.z;
_set_color_at_ofs(w, i, c);
}
}

Image::UsedChannels Image::detect_used_channels(CompressSource p_source) {
ERR_FAIL_COND_V(data.size() == 0, USED_CHANNELS_RGBA);
ERR_FAIL_COND_V(is_compressed(), USED_CHANNELS_RGBA);
Expand Down Expand Up @@ -3132,6 +3152,8 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pixelv", "point", "color"), &Image::set_pixelv);
ClassDB::bind_method(D_METHOD("set_pixel", "x", "y", "color"), &Image::set_pixel);

ClassDB::bind_method(D_METHOD("adjust_bcs", "brightness", "contrast", "saturation"), &Image::adjust_bcs);

ClassDB::bind_method(D_METHOD("load_png_from_buffer", "buffer"), &Image::load_png_from_buffer);
ClassDB::bind_method(D_METHOD("load_jpg_from_buffer", "buffer"), &Image::load_jpg_from_buffer);
ClassDB::bind_method(D_METHOD("load_webp_from_buffer", "buffer"), &Image::load_webp_from_buffer);
Expand Down
2 changes: 2 additions & 0 deletions core/io/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,8 @@ class Image : public Resource {
void set_pixelv(const Point2i &p_point, const Color &p_color);
void set_pixel(int p_x, int p_y, const Color &p_color);

void adjust_bcs(float p_brightness, float p_contrast, float p_saturation);

void set_as_black();

void copy_internals_from(const Ref<Image> &p_image) {
Expand Down
2 changes: 2 additions & 0 deletions editor/editor_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["interface/theme/accent_color"] = PropertyInfo(Variant::COLOR, "interface/theme/accent_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/theme/contrast", 0.25);
hints["interface/theme/contrast"] = PropertyInfo(Variant::FLOAT, "interface/theme/contrast", PROPERTY_HINT_RANGE, "0.01, 1, 0.01");
_initial_set("interface/theme/icon_saturation", 1.0);
hints["interface/theme/icon_saturation"] = PropertyInfo(Variant::FLOAT, "interface/theme/icon_saturation", PROPERTY_HINT_RANGE, "0,2,0.01", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/theme/relationship_line_opacity", 0.1);
hints["interface/theme/relationship_line_opacity"] = PropertyInfo(Variant::FLOAT, "interface/theme/relationship_line_opacity", PROPERTY_HINT_RANGE, "0.00, 1, 0.01");
_initial_set("interface/theme/highlight_tabs", false);
Expand Down
22 changes: 17 additions & 5 deletions editor/editor_themes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false,
}

#ifdef MODULE_SVG_ENABLED
static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, bool p_force_filter = false) {
static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, float p_saturation = 1.0) {
Ref<ImageTexture> icon = memnew(ImageTexture);
Ref<Image> img = memnew(Image);

Expand All @@ -116,6 +116,9 @@ static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color,
const bool upsample = !Math::is_equal_approx(Math::round(p_scale), p_scale);
ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], p_scale, upsample, p_convert_color);

if (p_saturation != 1.0) {
img->adjust_bcs(1.0, 1.0, p_saturation);
}
icon->create_from_image(img); // in this case filter really helps

return icon;
Expand All @@ -126,7 +129,7 @@ static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color,
#define ADD_CONVERT_COLOR(dictionary, old_color, new_color) dictionary[Color::html(old_color)] = Color::html(new_color)
#endif

void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = true, int p_thumb_size = 32, bool p_only_thumbs = false) {
void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = true, int p_thumb_size = 32, bool p_only_thumbs = false, float p_icon_saturation = 1.0) {
#ifdef MODULE_SVG_ENABLED
// The default icon theme is designed to be used for a dark theme.
// This dictionary stores color codes to convert to other colors
Expand Down Expand Up @@ -239,14 +242,19 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
if (!p_only_thumbs) {
for (int i = 0; i < editor_icons_count; i++) {
float icon_scale = EDSCALE;
float saturation = p_icon_saturation;

// Always keep the DefaultProjectIcon at the default size
if (strcmp(editor_icons_names[i], "DefaultProjectIcon") == 0) {
icon_scale = 1.0f;
}

if (strcmp(editor_icons_names[i], "DefaultProjectIcon") == 0 || strcmp(editor_icons_names[i], "Godot") == 0 || strcmp(editor_icons_names[i], "Logo") == 0) {
saturation = 1.0;
}

const int is_exception = exceptions.has(editor_icons_names[i]);
const Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception, icon_scale);
const Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception, icon_scale, saturation);

p_theme->set_icon(editor_icons_names[i], "EditorIcons", icon);
}
Expand Down Expand Up @@ -290,6 +298,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
Color accent_color = EDITOR_GET("interface/theme/accent_color");
Color base_color = EDITOR_GET("interface/theme/base_color");
float contrast = EDITOR_GET("interface/theme/contrast");
float icon_saturation = EDITOR_GET("interface/theme/icon_saturation");
float relationship_line_opacity = EDITOR_GET("interface/theme/relationship_line_opacity");

String preset = EDITOR_GET("interface/theme/preset");
Expand Down Expand Up @@ -393,6 +402,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {

const Color highlight_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.2);

float prev_icon_saturation = theme->has_color("icon_saturation", "Editor") ? theme->get_color("icon_saturation", "Editor").r : 1.0;

theme->set_color("icon_saturation", "Editor", Color(icon_saturation, icon_saturation, icon_saturation)); //can't save single float in theme, so using color
theme->set_color("accent_color", "Editor", accent_color);
theme->set_color("highlight_color", "Editor", highlight_color);
theme->set_color("base_color", "Editor", base_color);
Expand Down Expand Up @@ -444,13 +456,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
//Register icons + font

// the resolution and the icon color (dark_theme bool) has not changed, so we do not regenerate the icons
if (p_theme != nullptr && fabs(p_theme->get_constant("scale", "Editor") - EDSCALE) < 0.00001 && (bool)p_theme->get_constant("dark_theme", "Editor") == dark_theme) {
if (p_theme != nullptr && fabs(p_theme->get_constant("scale", "Editor") - EDSCALE) < 0.00001 && (bool)p_theme->get_constant("dark_theme", "Editor") == dark_theme && prev_icon_saturation == icon_saturation) {
// register already generated icons
for (int i = 0; i < editor_icons_count; i++) {
theme->set_icon(editor_icons_names[i], "EditorIcons", p_theme->get_icon(editor_icons_names[i], "EditorIcons"));
}
} else {
editor_register_and_generate_icons(theme, dark_theme, thumb_size);
editor_register_and_generate_icons(theme, dark_theme, thumb_size, false, icon_saturation);
}
// thumbnail size has changed, so we regenerate the medium sizes
if (p_theme != nullptr && fabs((double)p_theme->get_constant("thumb_size", "Editor") - thumb_size) > 0.00001) {
Expand Down