Skip to content

Commit

Permalink
ColorPicker: Add an intensity slider in raw mode for HDR
Browse files Browse the repository at this point in the history
  • Loading branch information
beicause committed Mar 4, 2025
1 parent 1753893 commit b56102d
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 31 deletions.
3 changes: 3 additions & 0 deletions doc/classes/ColorPicker.xml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@
<theme_item name="color_hue" data_type="icon" type="Texture2D">
Custom texture for the hue selection slider on the right.
</theme_item>
<theme_item name="color_script" data_type="icon" type="Texture2D">
The icon for the button that switches color text to hexadecimal.
</theme_item>
<theme_item name="expanded_arrow" data_type="icon" type="Texture2D">
The icon for color preset drop down menu when expanded.
</theme_item>
Expand Down
1 change: 1 addition & 0 deletions editor/themes/editor_theme_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1769,6 +1769,7 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
p_theme->set_icon("bar_arrow", "ColorPicker", p_theme->get_icon(SNAME("ColorPickerBarArrow"), EditorStringName(EditorIcons)));
p_theme->set_icon("picker_cursor", "ColorPicker", p_theme->get_icon(SNAME("PickerCursor"), EditorStringName(EditorIcons)));
p_theme->set_icon("picker_cursor_bg", "ColorPicker", p_theme->get_icon(SNAME("PickerCursorBg"), EditorStringName(EditorIcons)));
p_theme->set_icon("color_script", "ColorPicker", p_theme->get_icon(SNAME("Script"), EditorStringName(EditorIcons)));

// ColorPickerButton.
p_theme->set_icon("bg", "ColorPickerButton", p_theme->get_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons)));
Expand Down
27 changes: 21 additions & 6 deletions scene/gui/color_mode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,26 +210,41 @@ void ColorModeHSV::slider_draw(int p_which) {
}

String ColorModeRAW::get_slider_label(int idx) const {
ERR_FAIL_INDEX_V_MSG(idx, 3, String(), "Couldn't get slider label.");
ERR_FAIL_INDEX_V_MSG(idx, 4, String(), "Couldn't get slider label.");
return labels[idx];
}

float ColorModeRAW::get_slider_max(int idx) const {
ERR_FAIL_INDEX_V_MSG(idx, 4, 0, "Couldn't get slider max value.");
ERR_FAIL_INDEX_V_MSG(idx, 5, 0, "Couldn't get slider max value.");
return slider_max[idx];
}

float ColorModeRAW::get_slider_min(int idx) const {
ERR_FAIL_INDEX_V_MSG(idx, 5, 0, "Couldn't get slider min value.");
return idx == 3 ? intensity_min : 0;
}

float ColorModeRAW::get_slider_value(int idx) const {
ERR_FAIL_INDEX_V_MSG(idx, 4, 0, "Couldn't get slider value.");
return color_picker->get_pick_color().components[idx];
ERR_FAIL_INDEX_V_MSG(idx, 5, 0, "Couldn't get slider value.");
Color color = color_picker->get_pick_color();
float multiplier = MAX(1, MAX(MAX(color.r, color.g), color.b));
if (idx == 3) {
return Math::log2(multiplier);
} else if (idx == 4) {
return color.a;
} else {
return color.components[idx] / multiplier;
}
}

Color ColorModeRAW::get_color() const {
Vector<float> values = color_picker->get_active_slider_values();
Color color;
for (int i = 0; i < 4; i++) {
color.components[i] = values[i];
float intensity = Math::pow(2, values[3]);
for (int i = 0; i < 3; i++) {
color.components[i] = values[i] * intensity;
}
color.a = values[4];
return color;
}

Expand Down
8 changes: 6 additions & 2 deletions scene/gui/color_mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class ColorMode {
virtual float get_spinbox_arrow_step() const { return get_slider_step(); }
virtual String get_slider_label(int idx) const = 0;
virtual float get_slider_max(int idx) const = 0;
virtual float get_slider_min(int idx) const { return 0; }
virtual float get_slider_value(int idx) const = 0;

virtual Color get_color() const = 0;
Expand Down Expand Up @@ -105,15 +106,18 @@ class ColorModeRGB : public ColorMode {

class ColorModeRAW : public ColorMode {
public:
String labels[3] = { "R", "G", "B" };
float slider_max[4] = { 100, 100, 100, 1 };
String labels[4] = { "R", "G", "B", "I" };
float slider_max[5] = { 1, 1, 1, 6, 1 };
float intensity_min = -6;

virtual String get_name() const override { return "RAW"; }

virtual int get_slider_count() const override { return 4; }
virtual float get_slider_step() const override { return 0.001; }
virtual float get_spinbox_arrow_step() const override { return 0.01; }
virtual String get_slider_label(int idx) const override;
virtual float get_slider_max(int idx) const override;
virtual float get_slider_min(int idx) const override;
virtual float get_slider_value(int idx) const override;

virtual Color get_color() const override;
Expand Down
50 changes: 28 additions & 22 deletions scene/gui/color_picker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,8 @@ void ColorPicker::_notification(int p_what) {

_reset_sliders_theme();

if (Engine::get_singleton()->is_editor_hint()) {
// Adjust for the width of the "Script" icon.
text_type->set_custom_minimum_size(Size2(28 * theme_cache.base_scale, 0));
}
// Adjust for the width of the "script" icon.
text_type->set_custom_minimum_size(Size2(28 * theme_cache.base_scale, 0));

_update_presets();
_update_recent_presets();
Expand Down Expand Up @@ -625,7 +623,7 @@ void ColorPicker::_reset_sliders_theme() {
}

void ColorPicker::_html_submitted(const String &p_html) {
if (updating || text_is_constructor || !c_text->is_visible()) {
if (updating || text_is_constructor || !c_text->is_editable()) {
return;
}

Expand Down Expand Up @@ -674,11 +672,13 @@ void ColorPicker::_update_color(bool p_update_sliders) {
float spinbox_arrow_step = modes[current_mode]->get_spinbox_arrow_step();
for (int i = 0; i < current_slider_count; i++) {
sliders[i]->set_max(modes[current_mode]->get_slider_max(i));
sliders[i]->set_min(modes[current_mode]->get_slider_min(i));
sliders[i]->set_step(step);
values[i]->set_custom_arrow_step(spinbox_arrow_step);
sliders[i]->set_value(modes[current_mode]->get_slider_value(i));
}
alpha_slider->set_max(modes[current_mode]->get_slider_max(current_slider_count));
alpha_slider->set_min(modes[current_mode]->get_slider_min(current_slider_count));
alpha_slider->set_step(step);
alpha_slider->set_value(modes[current_mode]->get_slider_value(current_slider_count));
}
Expand Down Expand Up @@ -768,9 +768,7 @@ void ColorPicker::_text_type_toggled() {
text_is_constructor = !text_is_constructor;
if (text_is_constructor) {
text_type->set_text("");
#ifdef TOOLS_ENABLED
text_type->set_button_icon(get_editor_theme_icon(SNAME("Script")));
#endif
text_type->set_button_icon(theme_cache.color_script);

c_text->set_editable(false);
c_text->set_tooltip_text(RTR("Copy this constructor in a script."));
Expand All @@ -781,7 +779,7 @@ void ColorPicker::_text_type_toggled() {
c_text->set_editable(true);
c_text->set_tooltip_text(ETR("Enter a hex code (\"#ff0000\") or named color (\"red\")."));
}
_update_color();
_update_text_value();
}

Color ColorPicker::get_pick_color() const {
Expand Down Expand Up @@ -1236,25 +1234,32 @@ bool ColorPicker::is_deferred_mode() const {
}

void ColorPicker::_update_text_value() {
bool text_visible = true;
if (text_is_constructor) {
bool is_rgb_valid = color.r <= 1 && color.g <= 1 && color.b <= 1 && color.r >= 0 && color.g >= 0 && color.b >= 0;
if (text_is_constructor || !is_rgb_valid) {
String t = "Color(" + String::num(color.r, 3) + ", " + String::num(color.g, 3) + ", " + String::num(color.b, 3);
if (edit_alpha && color.a < 1) {
t += ", " + String::num(color.a, 3) + ")";
} else {
t += ")";
}
text_type->set_text("");
text_type->set_button_icon(theme_cache.color_script);

if (!is_rgb_valid) {
text_type->set_disabled(true);
} else {
text_type->set_disabled(false);
}
c_text->set_text(t);
}
c_text->set_editable(false);
} else {
text_type->set_text("#");
text_type->set_button_icon(nullptr);
text_type->set_disabled(false);

if (color.r > 1 || color.g > 1 || color.b > 1 || color.r < 0 || color.g < 0 || color.b < 0) {
text_visible = false;
} else if (!text_is_constructor) {
c_text->set_text(color.to_html(edit_alpha && color.a < 1));
c_text->set_editable(true);
}

text_type->set_visible(text_visible);
c_text->set_visible(text_visible);
}

void ColorPicker::_sample_input(const Ref<InputEvent> &p_event) {
Expand Down Expand Up @@ -2190,6 +2195,8 @@ void ColorPicker::_bind_methods() {
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, picker_cursor_bg);
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, color_hue);

BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, color_script);

BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_STYLEBOX, ColorPicker, mode_button_normal, "tab_unselected", "TabContainer");
BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_STYLEBOX, ColorPicker, mode_button_pressed, "tab_selected", "TabContainer");
BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_STYLEBOX, ColorPicker, mode_button_hover, "tab_selected", "TabContainer");
Expand Down Expand Up @@ -2305,13 +2312,12 @@ ColorPicker::ColorPicker() {

text_type = memnew(Button);
hex_hbc->add_child(text_type);
text_type->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER);
text_type->set_text("#");
text_type->set_tooltip_text(RTR("Switch between hexadecimal and code values."));
if (Engine::get_singleton()->is_editor_hint()) {
text_type->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_text_type_toggled));
} else {
text_type->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_text_type_toggled));
if (!Engine::get_singleton()->is_editor_hint()) {
text_type->set_flat(true);
text_type->set_mouse_filter(MOUSE_FILTER_IGNORE);
}

c_text = memnew(LineEdit);
Expand Down
4 changes: 3 additions & 1 deletion scene/gui/color_picker.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class ColorPicker : public VBoxContainer {
SHAPE_MAX
};

static const int SLIDER_COUNT = 3;
static const int SLIDER_COUNT = 4;

private:
enum class MenuOption {
Expand Down Expand Up @@ -269,6 +269,8 @@ class ColorPicker : public VBoxContainer {
Ref<Texture2D> picker_cursor_bg;
Ref<Texture2D> color_hue;

Ref<Texture2D> color_script;

/* Mode buttons */
Ref<StyleBox> mode_button_normal;
Ref<StyleBox> mode_button_pressed;
Expand Down
1 change: 1 addition & 0 deletions scene/theme/default_theme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("bar_arrow", "ColorPicker", icons["color_picker_bar_arrow"]);
theme->set_icon("picker_cursor", "ColorPicker", icons["color_picker_cursor"]);
theme->set_icon("picker_cursor_bg", "ColorPicker", icons["color_picker_cursor_bg"]);
theme->set_icon("color_script", "ColorPicker", icons["script"]);

{
const int precision = 7;
Expand Down
1 change: 1 addition & 0 deletions scene/theme/icons/script.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit b56102d

Please sign in to comment.