summaryrefslogtreecommitdiff
path: root/scene/gui/line_edit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/line_edit.cpp')
-rw-r--r--scene/gui/line_edit.cpp137
1 files changed, 96 insertions, 41 deletions
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 299c304c5f..da6bff8ab8 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "line_edit.h"
+
#include "core/message_queue.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
@@ -43,7 +44,7 @@
static bool _is_text_char(CharType c) {
- return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
+ return !is_symbol(c);
}
void LineEdit::_gui_input(Ref<InputEvent> p_event) {
@@ -55,6 +56,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (b->is_pressed() && b->get_button_index() == BUTTON_RIGHT && context_menu_enabled) {
menu->set_position(get_global_transform().xform(get_local_mouse_position()));
menu->set_size(Vector2(1, 1));
+ menu->set_scale(get_global_transform().get_scale());
menu->popup();
grab_focus();
return;
@@ -66,6 +68,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
_reset_caret_blink_timer();
if (b->is_pressed()) {
+ accept_event(); //don't pass event further when clicked on text field
if (!text.empty() && is_editable() && _is_over_clear_button(b->get_position())) {
clear_button_status.press_attempt = true;
clear_button_status.pressing_inside = true;
@@ -157,6 +160,38 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (!k->is_pressed())
return;
+
+#ifdef APPLE_STYLE_KEYS
+ if (k->get_control() && !k->get_shift() && !k->get_alt() && !k->get_command()) {
+ uint32_t remap_key = KEY_UNKNOWN;
+ switch (k->get_scancode()) {
+ case KEY_F: {
+ remap_key = KEY_RIGHT;
+ } break;
+ case KEY_B: {
+ remap_key = KEY_LEFT;
+ } break;
+ case KEY_P: {
+ remap_key = KEY_UP;
+ } break;
+ case KEY_N: {
+ remap_key = KEY_DOWN;
+ } break;
+ case KEY_D: {
+ remap_key = KEY_DELETE;
+ } break;
+ case KEY_H: {
+ remap_key = KEY_BACKSPACE;
+ } break;
+ }
+
+ if (remap_key != KEY_UNKNOWN) {
+ k->set_scancode(remap_key);
+ k->set_control(false);
+ }
+ }
+#endif
+
unsigned int code = k->get_scancode();
if (k->get_command()) {
@@ -248,7 +283,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
set_cursor_position(text.length());
} break;
#endif
- default: { handled = false; }
+ default: {
+ handled = false;
+ }
}
if (handled) {
@@ -318,7 +355,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
handled = false;
break;
}
- // numlock disabled. fallthrough to key_left
+ FALLTHROUGH;
}
case KEY_LEFT: {
@@ -365,7 +402,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
handled = false;
break;
}
- // numlock disabled. fallthrough to key_right
+ FALLTHROUGH;
}
case KEY_RIGHT: {
@@ -472,7 +509,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
handled = false;
break;
}
- // numlock disabled. fallthrough to key_home
+ FALLTHROUGH;
}
case KEY_HOME: {
@@ -485,7 +522,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
handled = false;
break;
}
- // numlock disabled. fallthrough to key_end
+ FALLTHROUGH;
}
case KEY_END: {
@@ -502,7 +539,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (handled) {
accept_event();
- } else if (!k->get_alt() && !k->get_command()) {
+ } else if (!k->get_command()) {
if (k->get_unicode() >= 32 && k->get_scancode() != KEY_DELETE) {
if (editable) {
@@ -609,9 +646,7 @@ void LineEdit::_notification(int p_what) {
#endif
case NOTIFICATION_RESIZED: {
- if (expand_to_text_length) {
- window_pos = 0; //force scroll back since it's expanding to text length
- }
+ window_pos = 0;
set_cursor_position(get_cursor_position());
} break;
@@ -719,6 +754,8 @@ void LineEdit::_notification(int p_what) {
} else {
x_ofs = MAX(style->get_margin(MARGIN_LEFT), x_ofs - r_icon->get_width() - style->get_margin(MARGIN_RIGHT));
}
+
+ ofs_max -= r_icon->get_width();
}
int caret_height = font->get_height() > y_area ? y_area : font->get_height();
@@ -831,7 +868,6 @@ void LineEdit::_notification(int p_what) {
OS::get_singleton()->set_ime_active(true);
OS::get_singleton()->set_ime_position(get_global_position() + Point2(using_placeholder ? 0 : x_ofs, y_ofs + caret_height));
- OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this);
}
} break;
case NOTIFICATION_FOCUS_ENTER: {
@@ -843,7 +879,6 @@ void LineEdit::_notification(int p_what) {
OS::get_singleton()->set_ime_active(true);
Point2 cursor_pos = Point2(get_cursor_position(), 1) * get_minimum_size().height;
OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos);
- OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this);
if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->show_virtual_keyboard(text, get_global_rect());
@@ -852,7 +887,6 @@ void LineEdit::_notification(int p_what) {
case NOTIFICATION_FOCUS_EXIT: {
OS::get_singleton()->set_ime_position(Point2());
- OS::get_singleton()->set_ime_intermediate_text_callback(NULL, NULL);
OS::get_singleton()->set_ime_active(false);
ime_text = "";
ime_selection = Point2();
@@ -861,6 +895,14 @@ void LineEdit::_notification(int p_what) {
OS::get_singleton()->hide_virtual_keyboard();
} break;
+ case MainLoop::NOTIFICATION_OS_IME_UPDATE: {
+
+ if (has_focus()) {
+ ime_text = OS::get_singleton()->get_ime_text();
+ ime_selection = OS::get_singleton()->get_ime_selection();
+ update();
+ }
+ } break;
}
}
@@ -881,7 +923,8 @@ void LineEdit::cut_text() {
void LineEdit::paste_text() {
- String paste_buffer = OS::get_singleton()->get_clipboard();
+ // Strip escape characters like \n and \t as they can't be displayed on LineEdit.
+ String paste_buffer = OS::get_singleton()->get_clipboard().strip_escapes();
if (paste_buffer != "") {
@@ -910,6 +953,10 @@ void LineEdit::undo() {
TextOperation op = undo_stack_pos->get();
text = op.text;
set_cursor_position(op.cursor_pos);
+
+ if (expand_to_text_length)
+ minimum_size_changed();
+
_emit_text_change();
}
@@ -924,6 +971,10 @@ void LineEdit::redo() {
TextOperation op = undo_stack_pos->get();
text = op.text;
set_cursor_position(op.cursor_pos);
+
+ if (expand_to_text_length)
+ minimum_size_changed();
+
_emit_text_change();
}
@@ -1147,14 +1198,14 @@ void LineEdit::set_cursor_position(int p_pos) {
if (cursor_pos <= window_pos) {
/* Adjust window if cursor goes too much to the left */
- if (window_pos > 0)
- set_window_pos(window_pos - 1);
-
+ set_window_pos(MAX(0, cursor_pos - 1));
} else if (cursor_pos > window_pos) {
/* Adjust window if cursor goes too much to the right */
int window_width = get_size().width - style->get_minimum_size().width;
- if (right_icon.is_valid()) {
- window_width -= right_icon->get_width();
+ bool display_clear_icon = !text.empty() && is_editable() && clear_button_enabled;
+ if (right_icon.is_valid() || display_clear_icon) {
+ Ref<Texture> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon;
+ window_width -= r_icon->get_width();
}
if (window_width < 0)
@@ -1218,6 +1269,7 @@ void LineEdit::append_at_cursor(String p_text) {
void LineEdit::clear_internal() {
+ deselect();
_clear_undo_stack();
cached_width = 0;
cursor_pos = 0;
@@ -1283,13 +1335,11 @@ int LineEdit::get_max_length() const {
void LineEdit::selection_fill_at_cursor() {
- int aux;
-
selection.begin = cursor_pos;
selection.end = selection.cursor_start;
if (selection.end < selection.begin) {
- aux = selection.end;
+ int aux = selection.end;
selection.end = selection.begin;
selection.begin = aux;
}
@@ -1310,7 +1360,27 @@ void LineEdit::select_all() {
void LineEdit::set_editable(bool p_editable) {
+ if (editable == p_editable)
+ return;
+
editable = p_editable;
+
+ // Reorganize context menu.
+ menu->clear();
+ if (editable)
+ menu->add_item(RTR("Cut"), MENU_CUT, KEY_MASK_CMD | KEY_X);
+ menu->add_item(RTR("Copy"), MENU_COPY, KEY_MASK_CMD | KEY_C);
+ if (editable)
+ menu->add_item(RTR("Paste"), MENU_PASTE, KEY_MASK_CMD | KEY_V);
+ menu->add_separator();
+ menu->add_item(RTR("Select All"), MENU_SELECT_ALL, KEY_MASK_CMD | KEY_A);
+ if (editable) {
+ menu->add_item(RTR("Clear"), MENU_CLEAR);
+ menu->add_separator();
+ menu->add_item(RTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z);
+ menu->add_item(RTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z);
+ }
+
update();
}
@@ -1461,13 +1531,6 @@ void LineEdit::set_right_icon(const Ref<Texture> &p_icon) {
update();
}
-void LineEdit::_ime_text_callback(void *p_self, String p_text, Point2 p_selection) {
- LineEdit *self = (LineEdit *)p_self;
- self->ime_text = p_text;
- self->ime_selection = p_selection;
- self->update();
-}
-
void LineEdit::_text_changed() {
if (expand_to_text_length)
@@ -1613,7 +1676,6 @@ LineEdit::LineEdit() {
deselect();
set_focus_mode(FOCUS_ALL);
- editable = true;
set_default_cursor_shape(CURSOR_IBEAM);
set_mouse_filter(MOUSE_FILTER_STOP);
@@ -1628,15 +1690,8 @@ LineEdit::LineEdit() {
context_menu_enabled = true;
menu = memnew(PopupMenu);
add_child(menu);
- menu->add_item(RTR("Cut"), MENU_CUT, KEY_MASK_CMD | KEY_X);
- menu->add_item(RTR("Copy"), MENU_COPY, KEY_MASK_CMD | KEY_C);
- menu->add_item(RTR("Paste"), MENU_PASTE, KEY_MASK_CMD | KEY_V);
- menu->add_separator();
- menu->add_item(RTR("Select All"), MENU_SELECT_ALL, KEY_MASK_CMD | KEY_A);
- menu->add_item(RTR("Clear"), MENU_CLEAR);
- menu->add_separator();
- menu->add_item(RTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z);
- menu->add_item(RTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z);
+ editable = false; // initialise to opposite first, so we get past the early-out in set_editable
+ set_editable(true);
menu->connect("id_pressed", this, "menu_option");
expand_to_text_length = false;
}