Skip to content

Commit 8128346

Browse files
committed
Merge pull request #105892 from timothyqiu/color-picker-improvements
Improve `ColorPicker`
2 parents 8edf97e + daaf411 commit 8128346

File tree

4 files changed

+81
-70
lines changed

4 files changed

+81
-70
lines changed

editor/editor_node.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3658,7 +3658,7 @@ void EditorNode::_update_file_menu_opened() {
36583658

36593659
void EditorNode::_palette_quick_open_dialog() {
36603660
quick_open_color_palette->popup_dialog({ "ColorPalette" }, palette_file_selected_callback);
3661-
quick_open_color_palette->set_title(TTR("Quick Open Color Palette..."));
3661+
quick_open_color_palette->set_title(TTRC("Quick Open Color Palette..."));
36623662
}
36633663

36643664
void EditorNode::replace_resources_in_object(Object *p_object, const Vector<Ref<Resource>> &p_source_resources, const Vector<Ref<Resource>> &p_target_resource) {

scene/gui/color_mode.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class ColorModeOKHSL : public ColorMode {
132132
float slider_max[4] = { 359, 100, 100, 255 };
133133
float cached_hue = 0.0;
134134
float cached_saturation = 0.0;
135-
Ref<GradientTexture2D> hue_texture = nullptr;
135+
Ref<GradientTexture2D> hue_texture;
136136

137137
virtual String get_name() const override { return "OKHSL"; }
138138

scene/gui/color_picker.cpp

Lines changed: 66 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
#include "color_picker.h"
3232

3333
#include "core/io/image.h"
34-
#include "scene/gui/aspect_ratio_container.h"
3534
#include "scene/gui/color_mode.h"
3635
#include "scene/gui/color_picker_shape.h"
3736
#include "scene/gui/file_dialog.h"
@@ -48,7 +47,6 @@
4847
#include "scene/gui/texture_rect.h"
4948
#include "scene/resources/atlas_texture.h"
5049
#include "scene/resources/color_palette.h"
51-
#include "scene/resources/gradient_texture.h"
5250
#include "scene/resources/image_texture.h"
5351
#include "scene/resources/style_box_flat.h"
5452
#include "scene/resources/style_box_texture.h"
@@ -95,28 +93,13 @@ void ColorPicker::_notification(int p_what) {
9593
}
9694
} break;
9795

98-
case NOTIFICATION_TRANSLATION_CHANGED: {
99-
List<BaseButton *> buttons;
100-
preset_group->get_buttons(&buttons);
101-
for (List<BaseButton *>::Element *E = buttons.front(); E; E = E->next()) {
102-
Color preset_color = ((ColorPresetButton *)E->get())->get_preset_color();
103-
E->get()->set_tooltip_text(vformat(atr(ETR("Color: #%s\nLMB: Apply color\nRMB: Remove preset")), preset_color.to_html(preset_color.a < 1)));
104-
}
105-
106-
buttons.clear();
107-
recent_preset_group->get_buttons(&buttons);
108-
for (List<BaseButton *>::Element *E = buttons.front(); E; E = E->next()) {
109-
Color preset_color = ((ColorPresetButton *)E->get())->get_preset_color();
110-
E->get()->set_tooltip_text(vformat(atr(ETR("Color: #%s\nLMB: Apply color")), preset_color.to_html(preset_color.a < 1)));
111-
}
112-
} break;
113-
11496
case NOTIFICATION_THEME_CHANGED: {
11597
btn_pick->set_button_icon(theme_cache.screen_picker);
11698
_update_drop_down_arrow(btn_preset->is_pressed(), btn_preset);
11799
_update_drop_down_arrow(btn_recent_preset->is_pressed(), btn_recent_preset);
118100
btn_add_preset->set_button_icon(theme_cache.add_preset);
119101
menu_btn->set_button_icon(theme_cache.menu_option);
102+
btn_mode->set_button_icon(theme_cache.menu_option);
120103

121104
btn_pick->set_custom_minimum_size(Size2(28 * theme_cache.base_scale, 0));
122105
btn_shape->set_custom_minimum_size(Size2(28 * theme_cache.base_scale, 0));
@@ -779,7 +762,7 @@ void ColorPicker::_update_presets() {
779762

780763
if (palette_edited) {
781764
palette_name->set_text(vformat("%s*", palette_name->get_text().remove_char('*')));
782-
palette_name->set_tooltip_text(ETR("The changes to this palette have not been saved to a file."));
765+
palette_name->set_tooltip_text(TTRC("The changes to this palette have not been saved to a file."));
783766
}
784767
}
785768
}
@@ -821,16 +804,15 @@ void ColorPicker::_update_recent_presets() {
821804
#endif
822805
}
823806

807+
#ifdef TOOLS_ENABLED
824808
void ColorPicker::_text_type_toggled() {
825809
text_is_constructor = !text_is_constructor;
826810
if (text_is_constructor) {
827811
text_type->set_text("");
828-
#ifdef TOOLS_ENABLED
829812
text_type->set_button_icon(get_editor_theme_icon(SNAME("Script")));
830-
#endif
831813

832814
c_text->set_editable(false);
833-
c_text->set_tooltip_text(RTR("Copy this constructor in a script."));
815+
c_text->set_tooltip_text(TTRC("Copy this constructor in a script."));
834816
} else {
835817
text_type->set_text("#");
836818
text_type->set_button_icon(nullptr);
@@ -840,6 +822,7 @@ void ColorPicker::_text_type_toggled() {
840822
}
841823
_update_color();
842824
}
825+
#endif // TOOLS_ENABLED
843826

844827
Color ColorPicker::get_pick_color() const {
845828
return color;
@@ -886,9 +869,7 @@ inline int ColorPicker::_get_preset_size() {
886869
}
887870

888871
void ColorPicker::_add_preset_button(int p_size, const Color &p_color) {
889-
ColorPresetButton *btn_preset_new = memnew(ColorPresetButton(p_color, p_size));
890-
btn_preset_new->set_tooltip_text(vformat(atr(ETR("Color: #%s\nLMB: Apply color\nRMB: Remove preset")), p_color.to_html(p_color.a < 1)));
891-
btn_preset_new->set_accessibility_name(vformat(atr(ETR("Color: #%s")), p_color.to_html(p_color.a < 1)));
872+
ColorPresetButton *btn_preset_new = memnew(ColorPresetButton(p_color, p_size, false));
892873
SET_DRAG_FORWARDING_GCDU(btn_preset_new, ColorPicker);
893874
btn_preset_new->set_button_group(preset_group);
894875
preset_container->add_child(btn_preset_new);
@@ -897,9 +878,7 @@ void ColorPicker::_add_preset_button(int p_size, const Color &p_color) {
897878
}
898879

899880
void ColorPicker::_add_recent_preset_button(int p_size, const Color &p_color) {
900-
ColorPresetButton *btn_preset_new = memnew(ColorPresetButton(p_color, p_size));
901-
btn_preset_new->set_tooltip_text(vformat(atr(ETR("Color: #%s\nLMB: Apply color")), p_color.to_html(p_color.a < 1)));
902-
btn_preset_new->set_accessibility_name(vformat(atr(ETR("Color: #%s")), p_color.to_html(p_color.a < 1)));
881+
ColorPresetButton *btn_preset_new = memnew(ColorPresetButton(p_color, p_size, true));
903882
btn_preset_new->set_button_group(recent_preset_group);
904883
recent_preset_hbc->add_child(btn_preset_new);
905884
recent_preset_hbc->move_child(btn_preset_new, 0);
@@ -911,7 +890,7 @@ void ColorPicker::_load_palette() {
911890
List<String> extensions;
912891
ResourceLoader::get_recognized_extensions_for_type("ColorPalette", &extensions);
913892

914-
file_dialog->set_title(RTR("Load Color Palette"));
893+
file_dialog->set_title(ETR("Load Color Palette"));
915894
file_dialog->clear_filters();
916895
for (const String &K : extensions) {
917896
file_dialog->add_filter("*." + K);
@@ -931,7 +910,7 @@ void ColorPicker::_save_palette(bool p_is_save_as) {
931910
List<String> extensions;
932911
ResourceLoader::get_recognized_extensions_for_type("ColorPalette", &extensions);
933912

934-
file_dialog->set_title(RTR("Save Color Palette"));
913+
file_dialog->set_title(ETR("Save Color Palette"));
935914
file_dialog->clear_filters();
936915
for (const String &K : extensions) {
937916
file_dialog->add_filter("*." + K);
@@ -943,17 +922,13 @@ void ColorPicker::_save_palette(bool p_is_save_as) {
943922
}
944923
}
945924

925+
#ifdef TOOLS_ENABLED
946926
void ColorPicker::_quick_open_palette_file_selected(const String &p_path) {
947-
if (!file_dialog) {
948-
file_dialog = memnew(FileDialog);
949-
add_child(file_dialog, false, INTERNAL_MODE_FRONT);
950-
file_dialog->connect("file_selected", callable_mp(this, &ColorPicker::_palette_file_selected));
951-
file_dialog->set_access(FileDialog::ACCESS_FILESYSTEM);
952-
file_dialog->set_current_dir(Engine::get_singleton()->is_editor_hint() ? "res://" : "user://");
953-
}
927+
_ensure_file_dialog();
954928
file_dialog->set_file_mode(FileDialog::FILE_MODE_OPEN_FILE);
955929
_palette_file_selected(p_path);
956930
}
931+
#endif // ifdef TOOLS_ENABLED
957932

958933
void ColorPicker::_palette_file_selected(const String &p_path) {
959934
switch (file_dialog->get_file_mode()) {
@@ -1047,7 +1022,7 @@ Variant ColorPicker::_get_drag_data_fw(const Point2 &p_point, Control *p_from_co
10471022
return Variant();
10481023
}
10491024

1050-
ColorPresetButton *drag_preview = memnew(ColorPresetButton(dragged_preset_button->get_preset_color(), _get_preset_size()));
1025+
ColorPresetButton *drag_preview = memnew(ColorPresetButton(dragged_preset_button->get_preset_color(), _get_preset_size(), false));
10511026
set_drag_preview(drag_preview);
10521027

10531028
Dictionary drag_data;
@@ -1082,6 +1057,19 @@ void ColorPicker::_drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
10821057
}
10831058
}
10841059

1060+
void ColorPicker::_ensure_file_dialog() {
1061+
if (file_dialog) {
1062+
return;
1063+
}
1064+
1065+
file_dialog = memnew(FileDialog);
1066+
file_dialog->set_mode_overrides_title(false);
1067+
file_dialog->set_access(FileDialog::ACCESS_FILESYSTEM);
1068+
file_dialog->set_current_dir(Engine::get_singleton()->is_editor_hint() ? "res://" : "user://");
1069+
add_child(file_dialog, false, INTERNAL_MODE_FRONT);
1070+
file_dialog->connect("file_selected", callable_mp(this, &ColorPicker::_palette_file_selected));
1071+
}
1072+
10851073
void ColorPicker::add_preset(const Color &p_color) {
10861074
List<Color>::Element *e = presets.find(p_color);
10871075
if (e) {
@@ -1602,36 +1590,31 @@ void ColorPicker::_update_menu_items() {
16021590
options_menu->clear();
16031591
options_menu->reset_size();
16041592

1605-
if (!presets.is_empty()) {
1606-
options_menu->add_icon_item(get_theme_icon(SNAME("save"), SNAME("FileDialog")), RTR("Save"), static_cast<int>(MenuOption::MENU_SAVE));
1607-
options_menu->set_item_tooltip(-1, ETR("Save the current color palette to reuse later."));
1608-
}
1609-
if (!palette_path.is_empty()) {
1610-
options_menu->add_icon_item(get_theme_icon(SNAME("save"), SNAME("FileDialog")), RTR("Save As"), static_cast<int>(MenuOption::MENU_SAVE_AS));
1611-
options_menu->set_item_tooltip(-1, ETR("Save the current color palette as a new to reuse later."));
1612-
}
1613-
options_menu->add_icon_item(get_theme_icon(SNAME("load"), SNAME("FileDialog")), RTR("Load"), static_cast<int>(MenuOption::MENU_LOAD));
1593+
options_menu->add_icon_item(get_theme_icon(SNAME("save"), SNAME("FileDialog")), ETR("Save"), static_cast<int>(MenuOption::MENU_SAVE));
1594+
options_menu->set_item_tooltip(-1, ETR("Save the current color palette to reuse later."));
1595+
options_menu->set_item_disabled(-1, presets.is_empty());
1596+
1597+
options_menu->add_icon_item(get_theme_icon(SNAME("save"), SNAME("FileDialog")), ETR("Save As"), static_cast<int>(MenuOption::MENU_SAVE_AS));
1598+
options_menu->set_item_tooltip(-1, ETR("Save the current color palette as a new to reuse later."));
1599+
options_menu->set_item_disabled(-1, palette_path.is_empty());
1600+
1601+
options_menu->add_icon_item(get_theme_icon(SNAME("load"), SNAME("FileDialog")), ETR("Load"), static_cast<int>(MenuOption::MENU_LOAD));
16141602
options_menu->set_item_tooltip(-1, ETR("Load existing color palette."));
16151603

1604+
#ifdef TOOLS_ENABLED
16161605
if (Engine::get_singleton()->is_editor_hint()) {
1617-
options_menu->add_icon_item(get_theme_icon(SNAME("load"), SNAME("FileDialog")), RTR("Quick Load"), static_cast<int>(MenuOption::MENU_QUICKLOAD));
1618-
options_menu->set_item_tooltip(-1, ETR("Load existing color palette."));
1606+
options_menu->add_icon_item(get_theme_icon(SNAME("load"), SNAME("FileDialog")), TTRC("Quick Load"), static_cast<int>(MenuOption::MENU_QUICKLOAD));
1607+
options_menu->set_item_tooltip(-1, TTRC("Load existing color palette."));
16191608
}
1609+
#endif // TOOLS_ENABLED
16201610

1621-
if (!presets.is_empty()) {
1622-
options_menu->add_icon_item(get_theme_icon(SNAME("clear"), SNAME("FileDialog")), RTR("Clear"), static_cast<int>(MenuOption::MENU_CLEAR));
1623-
options_menu->set_item_tooltip(-1, ETR("Clear the currently loaded color palettes in the picker."));
1624-
}
1611+
options_menu->add_icon_item(get_theme_icon(SNAME("clear"), SNAME("FileDialog")), ETR("Clear"), static_cast<int>(MenuOption::MENU_CLEAR));
1612+
options_menu->set_item_tooltip(-1, ETR("Clear the currently loaded color palettes in the picker."));
1613+
options_menu->set_item_disabled(-1, presets.is_empty());
16251614
}
16261615

16271616
void ColorPicker::_options_menu_cbk(int p_which) {
1628-
if (!file_dialog) {
1629-
file_dialog = memnew(FileDialog);
1630-
add_child(file_dialog, false, INTERNAL_MODE_FRONT);
1631-
file_dialog->connect("file_selected", callable_mp(this, &ColorPicker::_palette_file_selected));
1632-
file_dialog->set_access(FileDialog::ACCESS_FILESYSTEM);
1633-
file_dialog->set_current_dir(Engine::get_singleton()->is_editor_hint() ? "res://" : "user://");
1634-
}
1617+
_ensure_file_dialog();
16351618

16361619
MenuOption option = static_cast<MenuOption>(p_which);
16371620
switch (option) {
@@ -2087,7 +2070,6 @@ ColorPicker::ColorPicker() {
20872070
mode_btns[0]->set_pressed(true);
20882071

20892072
btn_mode = memnew(MenuButton);
2090-
btn_mode->set_text("...");
20912073
btn_mode->set_flat(false);
20922074
mode_hbc->add_child(btn_mode);
20932075
btn_mode->set_toggle_mode(true);
@@ -2131,12 +2113,20 @@ ColorPicker::ColorPicker() {
21312113

21322114
text_type = memnew(Button);
21332115
hex_hbc->add_child(text_type);
2116+
text_type->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
2117+
text_type->set_tooltip_auto_translate_mode(AUTO_TRANSLATE_MODE_ALWAYS);
21342118
text_type->set_text("#");
2135-
text_type->set_accessibility_name(ETR("Hexadecimal/Code Values"));
2136-
text_type->set_tooltip_text(ETR("Switch between hexadecimal and code values."));
2119+
#ifdef TOOLS_ENABLED
21372120
if (Engine::get_singleton()->is_editor_hint()) {
2121+
text_type->set_accessibility_name(TTRC("Hexadecimal/Code Values"));
2122+
text_type->set_tooltip_text(TTRC("Switch between hexadecimal and code values."));
21382123
text_type->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_text_type_toggled));
21392124
} else {
2125+
text_type->set_accessibility_name(ETR("Hexadecimal Values"));
2126+
#else
2127+
{
2128+
text_type->set_accessibility_name(ETR("Hexadecimal Values"));
2129+
#endif // TOOLS_ENABLED
21402130
text_type->set_flat(true);
21412131
text_type->set_focus_mode(FOCUS_NONE);
21422132
text_type->set_mouse_filter(MOUSE_FILTER_IGNORE);
@@ -2181,7 +2171,7 @@ ColorPicker::ColorPicker() {
21812171
palette_box->add_child(btn_preset);
21822172

21832173
menu_btn = memnew(MenuButton);
2184-
menu_btn->set_flat(true);
2174+
menu_btn->set_flat(false);
21852175
menu_btn->set_focus_mode(FOCUS_ALL);
21862176
menu_btn->set_tooltip_text(ETR("Show all options available."));
21872177
menu_btn->set_accessibility_name(ETR("All Options"));
@@ -2516,17 +2506,28 @@ Color ColorPresetButton::get_preset_color() const {
25162506
return preset_color;
25172507
}
25182508

2509+
String ColorPresetButton::get_tooltip(const Point2 &p_pos) const {
2510+
Color color = get_preset_color();
2511+
if (recent) {
2512+
return vformat(atr(ETR("Color: #%s\nLMB: Apply color")), color.to_html(color.a < 1));
2513+
}
2514+
return vformat(atr(ETR("Color: #%s\nLMB: Apply color\nRMB: Remove preset")), color.to_html(color.a < 1));
2515+
}
2516+
25192517
void ColorPresetButton::_bind_methods() {
25202518
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ColorPresetButton, foreground_style, "preset_fg");
25212519
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ColorPresetButton, focus_style, "preset_focus");
25222520
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, ColorPresetButton, background_icon, "preset_bg");
25232521
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPresetButton, overbright_indicator);
25242522
}
25252523

2526-
ColorPresetButton::ColorPresetButton(Color p_color, int p_size) {
2524+
ColorPresetButton::ColorPresetButton(Color p_color, int p_size, bool p_recent) {
25272525
preset_color = p_color;
2526+
recent = p_recent;
25282527
set_toggle_mode(true);
25292528
set_custom_minimum_size(Size2(p_size, p_size));
2529+
set_accessibility_name(vformat(atr(ETR("Color: #%s")), p_color.to_html(p_color.a < 1)));
2530+
set_tooltip_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
25302531
}
25312532

25322533
ColorPresetButton::~ColorPresetButton() {

scene/gui/color_picker.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class ColorPresetButton : public BaseButton {
5454
GDCLASS(ColorPresetButton, BaseButton);
5555

5656
Color preset_color;
57+
bool recent = false;
5758

5859
struct ThemeCache {
5960
Ref<StyleBox> foreground_style;
@@ -71,7 +72,9 @@ class ColorPresetButton : public BaseButton {
7172
void set_preset_color(const Color &p_color);
7273
Color get_preset_color() const;
7374

74-
ColorPresetButton(Color p_color, int p_size);
75+
virtual String get_tooltip(const Point2 &p_pos) const override;
76+
77+
ColorPresetButton(Color p_color, int p_size, bool p_recent);
7578
~ColorPresetButton();
7679
};
7780

@@ -181,7 +184,7 @@ class ColorPicker : public VBoxContainer {
181184
HBoxContainer *hex_hbc = nullptr;
182185
MenuButton *btn_mode = nullptr;
183186
Button *mode_btns[MODE_BUTTON_COUNT];
184-
Ref<ButtonGroup> mode_group = nullptr;
187+
Ref<ButtonGroup> mode_group;
185188
ColorPresetButton *selected_recent_preset = nullptr;
186189
Ref<ButtonGroup> preset_group;
187190
Ref<ButtonGroup> recent_preset_group;
@@ -301,7 +304,9 @@ class ColorPicker : public VBoxContainer {
301304
void _update_controls();
302305
void _update_color(bool p_update_sliders = true);
303306
void _update_text_value();
307+
#ifdef TOOLS_ENABLED
304308
void _text_type_toggled();
309+
#endif // TOOLS_ENABLED
305310
void _sample_input(const Ref<InputEvent> &p_event);
306311
void _sample_draw();
307312
void _slider_draw(int p_which);
@@ -344,6 +349,8 @@ class ColorPicker : public VBoxContainer {
344349
bool _can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from_control) const;
345350
void _drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from_control);
346351

352+
void _ensure_file_dialog();
353+
347354
protected:
348355
virtual void _update_theme_item_cache() override;
349356

@@ -355,7 +362,10 @@ class ColorPicker : public VBoxContainer {
355362
void set_editor_settings(Object *p_editor_settings);
356363
void set_quick_open_callback(const Callable &p_file_selected);
357364
void set_palette_saved_callback(const Callable &p_palette_saved);
365+
366+
void _quick_open_palette_file_selected(const String &p_path);
358367
#endif
368+
359369
HSlider *get_slider(int idx);
360370
Vector<float> get_active_slider_values();
361371

@@ -373,7 +383,7 @@ class ColorPicker : public VBoxContainer {
373383
Color get_pick_color() const;
374384
void set_old_color(const Color &p_color);
375385
Color get_old_color() const;
376-
void _quick_open_palette_file_selected(const String &p_path);
386+
377387
void _palette_file_selected(const String &p_path);
378388

379389
void set_display_old_color(bool p_enabled);

0 commit comments

Comments
 (0)