Add clear text button to LineEdit

- Add pressed state to clear button
- Enable clear button on all inputs with search icon
- Remove duplicate clear buttons
- Fix rendering of icon for center and right alignments
- Add clear button to more search fields
- Add clear icon to default theme
- Add method to control enabled state of clear button
- Add property to enable clear button from inspector
This commit is contained in:
Łukasz Rutkowski 2018-07-26 13:45:38 +02:00
parent 0fc1c4eda8
commit e8a435c8cd
23 changed files with 250 additions and 194 deletions

View file

@ -66,6 +66,12 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
_reset_caret_blink_timer();
if (b->is_pressed()) {
if (!text.empty() && is_editable() && _is_over_clear_button(b->get_position())) {
clear_button_status.press_attempt = true;
clear_button_status.pressing_inside = true;
return;
}
shift_selection_check_pre(b->get_shift());
set_cursor_at_pixel_pos(b->get_position().x);
@ -102,6 +108,15 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
} else {
if (!text.empty() && is_editable() && clear_button_enabled) {
bool press_attempt = clear_button_status.press_attempt;
clear_button_status.press_attempt = false;
if (press_attempt && clear_button_status.pressing_inside && _is_over_clear_button(b->get_position())) {
clear();
return;
}
}
if ((!selection.creating) && (!selection.doubleclick)) {
deselect();
}
@ -119,6 +134,14 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (m.is_valid()) {
if (!text.empty() && is_editable() && clear_button_enabled) {
bool last_press_inside = clear_button_status.pressing_inside;
clear_button_status.pressing_inside = clear_button_status.press_attempt && _is_over_clear_button(m->get_position());
if (last_press_inside != clear_button_status.pressing_inside) {
update();
}
}
if (m->get_button_mask() & BUTTON_LEFT) {
if (selection.creating) {
@ -550,6 +573,25 @@ void LineEdit::drop_data(const Point2 &p_point, const Variant &p_data) {
}
}
Control::CursorShape LineEdit::get_cursor_shape(const Point2 &p_pos) const {
if (!text.empty() && is_editable() && _is_over_clear_button(p_pos)) {
return CURSOR_ARROW;
}
return Control::get_cursor_shape(p_pos);
}
bool LineEdit::_is_over_clear_button(const Point2 &p_pos) const {
if (!clear_button_enabled || !has_point(p_pos)) {
return false;
}
Ref<Texture> icon = Control::get_icon("clear");
int x_ofs = get_stylebox("normal")->get_offset().x;
if (p_pos.x > get_size().width - icon->get_width() - x_ofs) {
return true;
}
return false;
}
void LineEdit::_notification(int p_what) {
switch (p_what) {
@ -657,10 +699,26 @@ void LineEdit::_notification(int p_what) {
font_color.a *= placeholder_alpha;
font_color.a *= disabled_alpha;
if (has_icon("right_icon")) {
Ref<Texture> r_icon = Control::get_icon("right_icon");
ofs_max -= r_icon->get_width();
r_icon->draw(ci, Point2(width - r_icon->get_width() - x_ofs, height / 2 - r_icon->get_height() / 2), Color(1, 1, 1, disabled_alpha * .9));
bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled;
if (has_icon("right_icon") || display_clear_icon) {
Ref<Texture> r_icon = Control::get_icon(display_clear_icon ? "clear" : "right_icon");
Color color_icon(1, 1, 1, disabled_alpha * .9);
if (display_clear_icon) {
if (clear_button_status.press_attempt && clear_button_status.pressing_inside) {
color_icon = get_color("clear_button_color_pressed");
} else {
color_icon = get_color("clear_button_color");
}
}
r_icon->draw(ci, Point2(width - r_icon->get_width() - style->get_margin(MARGIN_RIGHT), height / 2 - r_icon->get_height() / 2), color_icon);
if (align == ALIGN_CENTER) {
if (window_pos == 0) {
x_ofs = MAX(style->get_margin(MARGIN_LEFT), int(size.width - cached_text_width - r_icon->get_width() - style->get_margin(MARGIN_RIGHT) * 2) / 2);
}
} else {
x_ofs = MAX(style->get_margin(MARGIN_LEFT), x_ofs - r_icon->get_width() - style->get_margin(MARGIN_RIGHT));
}
}
int caret_height = font->get_height() > y_area ? y_area : font->get_height();
@ -1385,10 +1443,18 @@ void LineEdit::set_expand_to_text_length(bool p_enabled) {
}
bool LineEdit::get_expand_to_text_length() const {
return expand_to_text_length;
}
void LineEdit::set_clear_button_enabled(bool p_enabled) {
clear_button_enabled = p_enabled;
update();
}
bool LineEdit::is_clear_button_enabled() const {
return clear_button_enabled;
}
void LineEdit::_ime_text_callback(void *p_self, String p_text, Point2 p_selection) {
LineEdit *self = (LineEdit *)p_self;
self->ime_text = p_text;
@ -1481,6 +1547,8 @@ void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_menu"), &LineEdit::get_menu);
ClassDB::bind_method(D_METHOD("set_context_menu_enabled", "enable"), &LineEdit::set_context_menu_enabled);
ClassDB::bind_method(D_METHOD("is_context_menu_enabled"), &LineEdit::is_context_menu_enabled);
ClassDB::bind_method(D_METHOD("set_clear_button_enabled", "enable"), &LineEdit::set_clear_button_enabled);
ClassDB::bind_method(D_METHOD("is_clear_button_enabled"), &LineEdit::is_clear_button_enabled);
ADD_SIGNAL(MethodInfo("text_changed", PropertyInfo(Variant::STRING, "new_text")));
ADD_SIGNAL(MethodInfo("text_entered", PropertyInfo(Variant::STRING, "new_text")));
@ -1508,6 +1576,7 @@ void LineEdit::_bind_methods() {
ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "expand_to_text_length"), "set_expand_to_text_length", "get_expand_to_text_length");
ADD_PROPERTY(PropertyInfo(Variant::INT, "focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_focus_mode", "get_focus_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clear_button_enabled"), "set_clear_button_enabled", "is_clear_button_enabled");
ADD_GROUP("Placeholder", "placeholder_");
ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "placeholder_text"), "set_placeholder", "get_placeholder");
ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "placeholder_alpha", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_placeholder_alpha", "get_placeholder_alpha");
@ -1532,6 +1601,7 @@ LineEdit::LineEdit() {
secret_character = "*";
text_changed_dirty = false;
placeholder_alpha = 0.6;
clear_button_enabled = false;
deselect();
set_focus_mode(FOCUS_ALL);