diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 5e861ba45d4c..f79557aded9d 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -109,6 +109,13 @@ void ColorPicker::_notification(int p_what) { picker_window->hide(); } } break; + + case NOTIFICATION_INTERNAL_PROCESS: { + if (!is_picking_color) { + return; + } + set_pick_color(DisplayServer::get_singleton()->screen_get_pixel(DisplayServer::get_singleton()->mouse_get_position())); + } } } @@ -1421,30 +1428,6 @@ void ColorPicker::_recent_preset_pressed(const bool p_pressed, ColorPresetButton emit_signal(SNAME("color_changed"), p_preset->get_preset_color()); } -void ColorPicker::_picker_texture_input(const Ref &p_event) { - if (!is_inside_tree()) { - return; - } - - Ref bev = p_event; - if (bev.is_valid() && bev->get_button_index() == MouseButton::LEFT && !bev->is_pressed()) { - set_pick_color(picker_color); - emit_signal(SNAME("color_changed"), color); - picker_window->hide(); - } - - Ref mev = p_event; - if (mev.is_valid()) { - Ref img = picker_texture_rect->get_texture()->get_image(); - if (img.is_valid() && !img->is_empty()) { - Vector2 ofs = mev->get_position(); - picker_color = img->get_pixel(ofs.x, ofs.y); - picker_preview_style_box->set_bg_color(picker_color); - 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)); - } - } -} - void ColorPicker::_text_changed(const String &) { text_changed = true; } @@ -1455,6 +1438,34 @@ void ColorPicker::_add_preset_pressed() { } void ColorPicker::_pick_button_pressed() { + is_picking_color = true; + set_process_internal(true); + + if (!picker_window) { + picker_window = memnew(Popup); + picker_window->set_size(Vector2i(1, 1)); + picker_window->connect("visibility_changed", callable_mp(this, &ColorPicker::_pick_finished)); + add_child(picker_window); + } + picker_window->popup(); +} + +void ColorPicker::_pick_finished() { + if (picker_window->is_visible()) { + return; + } + + if (Input::get_singleton()->is_key_pressed(Key::ESCAPE)) { + set_pick_color(old_color); + } else { + emit_signal(SNAME("color_changed"), color); + } + is_picking_color = false; + set_process_internal(false); + picker_window->hide(); +} + +void ColorPicker::_pick_button_pressed_legacy() { if (!is_inside_tree()) { return; } @@ -1469,7 +1480,7 @@ void ColorPicker::_pick_button_pressed() { picker_texture_rect->set_anchors_preset(Control::PRESET_FULL_RECT); picker_window->add_child(picker_texture_rect); picker_texture_rect->set_default_cursor_shape(CURSOR_POINTING_HAND); - picker_texture_rect->connect(SNAME("gui_input"), callable_mp(this, &ColorPicker::_picker_texture_input)); + picker_texture_rect->connect("gui_input", callable_mp(this, &ColorPicker::_picker_texture_input)); picker_preview = memnew(Panel); picker_preview->set_anchors_preset(Control::PRESET_CENTER_TOP); @@ -1529,6 +1540,30 @@ void ColorPicker::_pick_button_pressed() { picker_window->popup(); } +void ColorPicker::_picker_texture_input(const Ref &p_event) { + if (!is_inside_tree()) { + return; + } + + Ref bev = p_event; + if (bev.is_valid() && bev->get_button_index() == MouseButton::LEFT && !bev->is_pressed()) { + set_pick_color(picker_color); + emit_signal(SNAME("color_changed"), color); + picker_window->hide(); + } + + Ref mev = p_event; + if (mev.is_valid()) { + Ref img = picker_texture_rect->get_texture()->get_image(); + if (img.is_valid() && !img->is_empty()) { + Vector2 ofs = mev->get_position(); + picker_color = img->get_pixel(ofs.x, ofs.y); + picker_preview_style_box->set_bg_color(picker_color); + 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)); + } + } +} + void ColorPicker::_html_focus_exit() { if (c_text->is_menu_visible()) { return; @@ -1692,8 +1727,14 @@ ColorPicker::ColorPicker() { btn_pick = memnew(Button); sample_hbc->add_child(btn_pick); - btn_pick->set_tooltip_text(RTR("Pick a color from the application window.")); - btn_pick->connect(SNAME("pressed"), callable_mp(this, &ColorPicker::_pick_button_pressed)); + if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_SCREEN_CAPTURE)) { + btn_pick->set_tooltip_text(RTR("Pick a color from the screen.")); + btn_pick->connect(SNAME("pressed"), callable_mp(this, &ColorPicker::_pick_button_pressed)); + } else { + // On unsupported platforms, use a legacy method for color picking. + btn_pick->set_tooltip_text(RTR("Pick a color from the application window.")); + btn_pick->connect(SNAME("pressed"), callable_mp(this, &ColorPicker::_pick_button_pressed_legacy)); + } sample = memnew(TextureRect); sample_hbc->add_child(sample); diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 018ae1095524..711a37168869 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -122,11 +122,13 @@ class ColorPicker : public VBoxContainer { Vector modes; Popup *picker_window = nullptr; + // Legacy color picking. TextureRect *picker_texture_rect = nullptr; Panel *picker_preview = nullptr; Label *picker_preview_label = nullptr; Ref picker_preview_style_box; Color picker_color; + Control *uv_edit = nullptr; Control *w_edit = nullptr; AspectRatioContainer *wheel_edit = nullptr; @@ -183,6 +185,7 @@ class ColorPicker : public VBoxContainer { Color color; Color old_color; + bool is_picking_color = false; bool display_old_color = false; bool deferred_mode_enabled = false; @@ -259,11 +262,14 @@ class ColorPicker : public VBoxContainer { void _line_edit_input(const Ref &p_event); void _preset_input(const Ref &p_event, const Color &p_color); void _recent_preset_pressed(const bool pressed, ColorPresetButton *p_preset); - void _picker_texture_input(const Ref &p_event); void _text_changed(const String &p_new_text); void _add_preset_pressed(); - void _pick_button_pressed(); void _html_focus_exit(); + void _pick_button_pressed(); + void _pick_finished(); + // Legacy color picking. + void _pick_button_pressed_legacy(); + void _picker_texture_input(const Ref &p_event); inline int _get_preset_size(); void _add_preset_button(int p_size, const Color &p_color);