Skip to content

Commit

Permalink
Improve color picking
Browse files Browse the repository at this point in the history
  • Loading branch information
KoBeWi committed May 19, 2023
1 parent 150acef commit b76dded
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 29 deletions.
95 changes: 68 additions & 27 deletions scene/gui/color_picker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
}
}
}

Expand Down Expand Up @@ -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<InputEvent> &p_event) {
if (!is_inside_tree()) {
return;
}

Ref<InputEventMouseButton> 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<InputEventMouseMotion> mev = p_event;
if (mev.is_valid()) {
Ref<Image> 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;
}
Expand All @@ -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;
}
Expand All @@ -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);
Expand Down Expand Up @@ -1529,6 +1540,30 @@ void ColorPicker::_pick_button_pressed() {
picker_window->popup();
}

void ColorPicker::_picker_texture_input(const Ref<InputEvent> &p_event) {
if (!is_inside_tree()) {
return;
}

Ref<InputEventMouseButton> 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<InputEventMouseMotion> mev = p_event;
if (mev.is_valid()) {
Ref<Image> 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;
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 8 additions & 2 deletions scene/gui/color_picker.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,13 @@ class ColorPicker : public VBoxContainer {
Vector<ColorMode *> modes;

Popup *picker_window = nullptr;
// Legacy color picking.
TextureRect *picker_texture_rect = nullptr;
Panel *picker_preview = nullptr;
Label *picker_preview_label = nullptr;
Ref<StyleBoxFlat> picker_preview_style_box;
Color picker_color;

Control *uv_edit = nullptr;
Control *w_edit = nullptr;
AspectRatioContainer *wheel_edit = nullptr;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -259,11 +262,14 @@ class ColorPicker : public VBoxContainer {
void _line_edit_input(const Ref<InputEvent> &p_event);
void _preset_input(const Ref<InputEvent> &p_event, const Color &p_color);
void _recent_preset_pressed(const bool pressed, ColorPresetButton *p_preset);
void _picker_texture_input(const Ref<InputEvent> &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<InputEvent> &p_event);

inline int _get_preset_size();
void _add_preset_button(int p_size, const Color &p_color);
Expand Down

0 comments on commit b76dded

Please sign in to comment.