Skip to content

Commit b76dded

Browse files
committed
Improve color picking
1 parent 150acef commit b76dded

File tree

2 files changed

+76
-29
lines changed

2 files changed

+76
-29
lines changed

scene/gui/color_picker.cpp

+68-27
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ void ColorPicker::_notification(int p_what) {
109109
picker_window->hide();
110110
}
111111
} break;
112+
113+
case NOTIFICATION_INTERNAL_PROCESS: {
114+
if (!is_picking_color) {
115+
return;
116+
}
117+
set_pick_color(DisplayServer::get_singleton()->screen_get_pixel(DisplayServer::get_singleton()->mouse_get_position()));
118+
}
112119
}
113120
}
114121

@@ -1421,30 +1428,6 @@ void ColorPicker::_recent_preset_pressed(const bool p_pressed, ColorPresetButton
14211428
emit_signal(SNAME("color_changed"), p_preset->get_preset_color());
14221429
}
14231430

1424-
void ColorPicker::_picker_texture_input(const Ref<InputEvent> &p_event) {
1425-
if (!is_inside_tree()) {
1426-
return;
1427-
}
1428-
1429-
Ref<InputEventMouseButton> bev = p_event;
1430-
if (bev.is_valid() && bev->get_button_index() == MouseButton::LEFT && !bev->is_pressed()) {
1431-
set_pick_color(picker_color);
1432-
emit_signal(SNAME("color_changed"), color);
1433-
picker_window->hide();
1434-
}
1435-
1436-
Ref<InputEventMouseMotion> mev = p_event;
1437-
if (mev.is_valid()) {
1438-
Ref<Image> img = picker_texture_rect->get_texture()->get_image();
1439-
if (img.is_valid() && !img->is_empty()) {
1440-
Vector2 ofs = mev->get_position();
1441-
picker_color = img->get_pixel(ofs.x, ofs.y);
1442-
picker_preview_style_box->set_bg_color(picker_color);
1443-
picker_preview_label->set_self_modulate(picker_color.get_luminance() < 0.5 ? Color(1.0f, 1.0f, 1.0f) : Color(0.0f, 0.0f, 0.0f));
1444-
}
1445-
}
1446-
}
1447-
14481431
void ColorPicker::_text_changed(const String &) {
14491432
text_changed = true;
14501433
}
@@ -1455,6 +1438,34 @@ void ColorPicker::_add_preset_pressed() {
14551438
}
14561439

14571440
void ColorPicker::_pick_button_pressed() {
1441+
is_picking_color = true;
1442+
set_process_internal(true);
1443+
1444+
if (!picker_window) {
1445+
picker_window = memnew(Popup);
1446+
picker_window->set_size(Vector2i(1, 1));
1447+
picker_window->connect("visibility_changed", callable_mp(this, &ColorPicker::_pick_finished));
1448+
add_child(picker_window);
1449+
}
1450+
picker_window->popup();
1451+
}
1452+
1453+
void ColorPicker::_pick_finished() {
1454+
if (picker_window->is_visible()) {
1455+
return;
1456+
}
1457+
1458+
if (Input::get_singleton()->is_key_pressed(Key::ESCAPE)) {
1459+
set_pick_color(old_color);
1460+
} else {
1461+
emit_signal(SNAME("color_changed"), color);
1462+
}
1463+
is_picking_color = false;
1464+
set_process_internal(false);
1465+
picker_window->hide();
1466+
}
1467+
1468+
void ColorPicker::_pick_button_pressed_legacy() {
14581469
if (!is_inside_tree()) {
14591470
return;
14601471
}
@@ -1469,7 +1480,7 @@ void ColorPicker::_pick_button_pressed() {
14691480
picker_texture_rect->set_anchors_preset(Control::PRESET_FULL_RECT);
14701481
picker_window->add_child(picker_texture_rect);
14711482
picker_texture_rect->set_default_cursor_shape(CURSOR_POINTING_HAND);
1472-
picker_texture_rect->connect(SNAME("gui_input"), callable_mp(this, &ColorPicker::_picker_texture_input));
1483+
picker_texture_rect->connect("gui_input", callable_mp(this, &ColorPicker::_picker_texture_input));
14731484

14741485
picker_preview = memnew(Panel);
14751486
picker_preview->set_anchors_preset(Control::PRESET_CENTER_TOP);
@@ -1529,6 +1540,30 @@ void ColorPicker::_pick_button_pressed() {
15291540
picker_window->popup();
15301541
}
15311542

1543+
void ColorPicker::_picker_texture_input(const Ref<InputEvent> &p_event) {
1544+
if (!is_inside_tree()) {
1545+
return;
1546+
}
1547+
1548+
Ref<InputEventMouseButton> bev = p_event;
1549+
if (bev.is_valid() && bev->get_button_index() == MouseButton::LEFT && !bev->is_pressed()) {
1550+
set_pick_color(picker_color);
1551+
emit_signal(SNAME("color_changed"), color);
1552+
picker_window->hide();
1553+
}
1554+
1555+
Ref<InputEventMouseMotion> mev = p_event;
1556+
if (mev.is_valid()) {
1557+
Ref<Image> img = picker_texture_rect->get_texture()->get_image();
1558+
if (img.is_valid() && !img->is_empty()) {
1559+
Vector2 ofs = mev->get_position();
1560+
picker_color = img->get_pixel(ofs.x, ofs.y);
1561+
picker_preview_style_box->set_bg_color(picker_color);
1562+
picker_preview_label->set_self_modulate(picker_color.get_luminance() < 0.5 ? Color(1.0f, 1.0f, 1.0f) : Color(0.0f, 0.0f, 0.0f));
1563+
}
1564+
}
1565+
}
1566+
15321567
void ColorPicker::_html_focus_exit() {
15331568
if (c_text->is_menu_visible()) {
15341569
return;
@@ -1692,8 +1727,14 @@ ColorPicker::ColorPicker() {
16921727

16931728
btn_pick = memnew(Button);
16941729
sample_hbc->add_child(btn_pick);
1695-
btn_pick->set_tooltip_text(RTR("Pick a color from the application window."));
1696-
btn_pick->connect(SNAME("pressed"), callable_mp(this, &ColorPicker::_pick_button_pressed));
1730+
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_SCREEN_CAPTURE)) {
1731+
btn_pick->set_tooltip_text(RTR("Pick a color from the screen."));
1732+
btn_pick->connect(SNAME("pressed"), callable_mp(this, &ColorPicker::_pick_button_pressed));
1733+
} else {
1734+
// On unsupported platforms, use a legacy method for color picking.
1735+
btn_pick->set_tooltip_text(RTR("Pick a color from the application window."));
1736+
btn_pick->connect(SNAME("pressed"), callable_mp(this, &ColorPicker::_pick_button_pressed_legacy));
1737+
}
16971738

16981739
sample = memnew(TextureRect);
16991740
sample_hbc->add_child(sample);

scene/gui/color_picker.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,13 @@ class ColorPicker : public VBoxContainer {
122122
Vector<ColorMode *> modes;
123123

124124
Popup *picker_window = nullptr;
125+
// Legacy color picking.
125126
TextureRect *picker_texture_rect = nullptr;
126127
Panel *picker_preview = nullptr;
127128
Label *picker_preview_label = nullptr;
128129
Ref<StyleBoxFlat> picker_preview_style_box;
129130
Color picker_color;
131+
130132
Control *uv_edit = nullptr;
131133
Control *w_edit = nullptr;
132134
AspectRatioContainer *wheel_edit = nullptr;
@@ -183,6 +185,7 @@ class ColorPicker : public VBoxContainer {
183185

184186
Color color;
185187
Color old_color;
188+
bool is_picking_color = false;
186189

187190
bool display_old_color = false;
188191
bool deferred_mode_enabled = false;
@@ -259,11 +262,14 @@ class ColorPicker : public VBoxContainer {
259262
void _line_edit_input(const Ref<InputEvent> &p_event);
260263
void _preset_input(const Ref<InputEvent> &p_event, const Color &p_color);
261264
void _recent_preset_pressed(const bool pressed, ColorPresetButton *p_preset);
262-
void _picker_texture_input(const Ref<InputEvent> &p_event);
263265
void _text_changed(const String &p_new_text);
264266
void _add_preset_pressed();
265-
void _pick_button_pressed();
266267
void _html_focus_exit();
268+
void _pick_button_pressed();
269+
void _pick_finished();
270+
// Legacy color picking.
271+
void _pick_button_pressed_legacy();
272+
void _picker_texture_input(const Ref<InputEvent> &p_event);
267273

268274
inline int _get_preset_size();
269275
void _add_preset_button(int p_size, const Color &p_color);

0 commit comments

Comments
 (0)