Browse Source

Default editing popup for LineEdit and TextEdit

Juan Linietsky 9 years ago
parent
commit
f93aaa9b78
4 changed files with 205 additions and 24 deletions
  1. 97 20
      scene/gui/line_edit.cpp
  2. 24 4
      scene/gui/line_edit.h
  3. 66 0
      scene/gui/text_edit.cpp
  4. 18 0
      scene/gui/text_edit.h

+ 97 - 20
scene/gui/line_edit.cpp

@@ -41,7 +41,15 @@ void LineEdit::_input_event(InputEvent p_event) {
 
 
 			const InputEventMouseButton &b = p_event.mouse_button;
 			const InputEventMouseButton &b = p_event.mouse_button;
 
 
-			if (b.button_index!=1)
+			if (b.pressed && b.button_index==BUTTON_RIGHT) {
+				menu->set_pos(get_global_transform().xform(get_local_mouse_pos()));
+				menu->set_size(Vector2(1,1));
+				menu->popup();
+				grab_focus();
+				return;
+			}
+
+			if (b.button_index!=BUTTON_LEFT)
 				break;
 				break;
 
 
 			if (b.pressed) {
 			if (b.pressed) {
@@ -143,24 +151,10 @@ void LineEdit::_input_event(InputEvent p_event) {
 
 
 						if( k.mod.command && editable) {
 						if( k.mod.command && editable) {
 
 
-							int old_cursor_pos = cursor_pos;
-							text = undo_text;
-
-							Ref<Font> font = get_font("font");
-
-							cached_width = 0;
-							for (int i = 0; i<text.length(); i++)
-								cached_width += font->get_char_size(text[i]).width;
+							undo();
 
 
-							if(old_cursor_pos > text.length()) {
-								set_cursor_pos(text.length());
-							} else {
-								set_cursor_pos(old_cursor_pos);
-							}
 						}
 						}
 
 
-						emit_signal("text_changed",text);
-						_change_notify("text");
 
 
 					} break;
 					} break;
 
 
@@ -557,6 +551,28 @@ void LineEdit::paste_text() {
 
 
 
 
 
 
+}
+
+void LineEdit::undo() {
+
+	int old_cursor_pos = cursor_pos;
+	text = undo_text;
+
+	Ref<Font> font = get_font("font");
+
+	cached_width = 0;
+	for (int i = 0; i<text.length(); i++)
+		cached_width += font->get_char_size(text[i]).width;
+
+	if(old_cursor_pos > text.length()) {
+		set_cursor_pos(text.length());
+	} else {
+		set_cursor_pos(old_cursor_pos);
+	}
+
+	emit_signal("text_changed",text);
+	_change_notify("text");
+
 }
 }
 
 
 void LineEdit::shift_selection_check_pre(bool p_shift) {
 void LineEdit::shift_selection_check_pre(bool p_shift) {
@@ -669,6 +685,8 @@ void LineEdit::set_text(String p_text) {
 void LineEdit::clear() {
 void LineEdit::clear() {
 
 
 	clear_internal();
 	clear_internal();
+	emit_signal("text_changed",text);
+	_change_notify("text");
 }
 }
 
 
 String LineEdit::get_text() const {
 String LineEdit::get_text() const {
@@ -932,6 +950,39 @@ bool LineEdit::is_text_field() const {
     return true;
     return true;
 }
 }
 
 
+void LineEdit::menu_option(int p_option) {
+
+	switch(p_option) {
+		case MENU_CUT: {
+			cut_text();
+		} break;
+		case MENU_COPY: {
+
+			copy_text();
+		} break;
+		case MENU_PASTE: {
+
+			paste_text();
+		} break;
+		case MENU_CLEAR: {
+			clear();
+		} break;
+		case MENU_SELECT_ALL: {
+			select_all();
+		} break;
+		case MENU_UNDO: {
+
+			undo();
+		} break;
+
+	}
+
+}
+
+PopupMenu *LineEdit::get_menu() const {
+	return menu;
+}
+
 void LineEdit::_bind_methods() {
 void LineEdit::_bind_methods() {
 
 
 	ObjectTypeDB::bind_method(_MD("set_align", "align"), &LineEdit::set_align);
 	ObjectTypeDB::bind_method(_MD("set_align", "align"), &LineEdit::set_align);
@@ -952,6 +1003,8 @@ void LineEdit::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_secret","enabled"),&LineEdit::set_secret);
 	ObjectTypeDB::bind_method(_MD("set_secret","enabled"),&LineEdit::set_secret);
 	ObjectTypeDB::bind_method(_MD("is_secret"),&LineEdit::is_secret);
 	ObjectTypeDB::bind_method(_MD("is_secret"),&LineEdit::is_secret);
 	ObjectTypeDB::bind_method(_MD("select","from","to"),&LineEdit::select,DEFVAL(0),DEFVAL(-1));
 	ObjectTypeDB::bind_method(_MD("select","from","to"),&LineEdit::select,DEFVAL(0),DEFVAL(-1));
+	ObjectTypeDB::bind_method(_MD("menu_option","option"),&LineEdit::menu_option);
+	ObjectTypeDB::bind_method(_MD("get_menu:PopupMenu"),&LineEdit::get_menu);
 
 
 	ADD_SIGNAL( MethodInfo("text_changed", PropertyInfo( Variant::STRING, "text" )) );
 	ADD_SIGNAL( MethodInfo("text_changed", PropertyInfo( Variant::STRING, "text" )) );
 	ADD_SIGNAL( MethodInfo("text_entered", PropertyInfo( Variant::STRING, "text" )) );
 	ADD_SIGNAL( MethodInfo("text_entered", PropertyInfo( Variant::STRING, "text" )) );
@@ -961,11 +1014,21 @@ void LineEdit::_bind_methods() {
 	BIND_CONSTANT(ALIGN_RIGHT);
 	BIND_CONSTANT(ALIGN_RIGHT);
 	BIND_CONSTANT(ALIGN_FILL);
 	BIND_CONSTANT(ALIGN_FILL);
 
 
-	ADD_PROPERTY( PropertyInfo( Variant::STRING, "text" ), _SCS("set_text"),_SCS("get_text") );
+	BIND_CONSTANT( MENU_CUT );
+	BIND_CONSTANT( MENU_COPY );
+	BIND_CONSTANT( MENU_PASTE );
+	BIND_CONSTANT( MENU_CLEAR );
+	BIND_CONSTANT( MENU_SELECT_ALL );
+	BIND_CONSTANT( MENU_UNDO );
+	BIND_CONSTANT( MENU_MAX );
+
+	ADD_PROPERTYNZ( PropertyInfo( Variant::STRING, "text" ), _SCS("set_text"),_SCS("get_text") );
 	ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), _SCS("set_align"), _SCS("get_align"));
 	ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), _SCS("set_align"), _SCS("get_align"));
-	ADD_PROPERTY( PropertyInfo( Variant::INT, "max_length" ), _SCS("set_max_length"),_SCS("get_max_length") );
-	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "editable" ), _SCS("set_editable"),_SCS("is_editable") );
-	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "secret" ), _SCS("set_secret"),_SCS("is_secret") );
+	ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "max_length" ), _SCS("set_max_length"),_SCS("get_max_length") );
+	ADD_PROPERTYNO( PropertyInfo( Variant::BOOL, "editable" ), _SCS("set_editable"),_SCS("is_editable") );
+	ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "secret" ), _SCS("set_secret"),_SCS("is_secret") );
+
+
 }
 }
 
 
 LineEdit::LineEdit() {
 LineEdit::LineEdit() {
@@ -984,6 +1047,20 @@ LineEdit::LineEdit() {
 	set_stop_mouse(true);
 	set_stop_mouse(true);
 
 
 
 
+	menu = memnew( PopupMenu );
+	add_child(menu);
+	menu->add_item(TTR("Cut"),MENU_CUT,KEY_MASK_CMD|KEY_X);
+	menu->add_item(TTR("Copy"),MENU_COPY,KEY_MASK_CMD|KEY_C);
+	menu->add_item(TTR("Paste"),MENU_PASTE,KEY_MASK_CMD|KEY_V);
+	menu->add_separator();
+	menu->add_item(TTR("Select All"),MENU_SELECT_ALL,KEY_MASK_CMD|KEY_A);
+	menu->add_item(TTR("Clear"),MENU_CLEAR);
+	menu->add_separator();
+	menu->add_item(TTR("Undo"),MENU_UNDO,KEY_MASK_CMD|KEY_Z);
+	menu->connect("item_pressed",this,"menu_option");
+
+
+
 }
 }
 
 
 LineEdit::~LineEdit() {
 LineEdit::~LineEdit() {

+ 24 - 4
scene/gui/line_edit.h

@@ -30,6 +30,8 @@
 #define LINE_EDIT_H
 #define LINE_EDIT_H
 
 
 #include "scene/gui/control.h"
 #include "scene/gui/control.h"
+#include "scene/gui/popup_menu.h"
+
 /**
 /**
 	@author Juan Linietsky <[email protected]>
 	@author Juan Linietsky <[email protected]>
 */
 */
@@ -45,6 +47,18 @@ public:
 		ALIGN_RIGHT,
 		ALIGN_RIGHT,
 		ALIGN_FILL
 		ALIGN_FILL
 	};
 	};
+
+	enum MenuItems {
+		MENU_CUT,
+		MENU_COPY,
+		MENU_PASTE,
+		MENU_CLEAR,
+		MENU_SELECT_ALL,
+		MENU_UNDO,
+		MENU_MAX
+
+	};
+
 private:
 private:
 	Align align;
 	Align align;
 
 
@@ -54,6 +68,8 @@ private:
 	String undo_text;
 	String undo_text;
 	String text;
 	String text;
 
 
+	PopupMenu *menu;
+
 	int cursor_pos;
 	int cursor_pos;
 	int window_pos;
 	int window_pos;
 	int max_length; // 0 for no maximum
 	int max_length; // 0 for no maximum
@@ -85,14 +101,12 @@ private:
 	void clear_internal();
 	void clear_internal();
 	void changed_internal();
 	void changed_internal();
 
 
-	void copy_text();
-	void cut_text();
-	void paste_text();
 
 
 
 
 	void _input_event(InputEvent p_event);
 	void _input_event(InputEvent p_event);
 	void _notification(int p_what);
 	void _notification(int p_what);
 
 
+
 protected:
 protected:
 	static void _bind_methods();
 	static void _bind_methods();
 public:
 public:
@@ -103,6 +117,8 @@ public:
 	virtual bool can_drop_data(const Point2& p_point,const Variant& p_data) const;
 	virtual bool can_drop_data(const Point2& p_point,const Variant& p_data) const;
 	virtual void drop_data(const Point2& p_point,const Variant& p_data);
 	virtual void drop_data(const Point2& p_point,const Variant& p_data);
 
 
+	void menu_option(int p_option);
+	PopupMenu *get_menu() const;
 
 
 	void select_all();
 	void select_all();
 
 
@@ -116,6 +132,10 @@ public:
 	void append_at_cursor(String p_text);
 	void append_at_cursor(String p_text);
 	void clear();
 	void clear();
 
 
+	void copy_text();
+	void cut_text();
+	void paste_text();
+	void undo();
 
 
 	void set_editable(bool p_editable);
 	void set_editable(bool p_editable);
 	bool is_editable() const;
 	bool is_editable() const;
@@ -127,7 +147,7 @@ public:
 
 
 	virtual Size2 get_minimum_size() const;
 	virtual Size2 get_minimum_size() const;
 
 
-    virtual bool is_text_field() const;
+	virtual bool is_text_field() const;
 	LineEdit();
 	LineEdit();
 	~LineEdit();
 	~LineEdit();
 
 

+ 66 - 0
scene/gui/text_edit.cpp

@@ -1518,6 +1518,15 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
 
 
 					update();
 					update();
 				}
 				}
+
+				if (mb.button_index==BUTTON_RIGHT) {
+
+					menu->set_pos(get_global_transform().xform(get_local_mouse_pos()));
+					menu->set_size(Vector2(1,1));
+					menu->popup();
+					grab_focus();
+
+				}
 			} else {
 			} else {
 
 
 				if (mb.button_index==BUTTON_LEFT)
 				if (mb.button_index==BUTTON_LEFT)
@@ -4146,6 +4155,38 @@ bool TextEdit::is_text_field() const {
 
 
     return true;
     return true;
 }
 }
+
+void TextEdit::menu_option(int p_option) {
+
+	switch( p_option ) {
+		case MENU_CUT: {
+
+			cut();
+		} break;
+		case MENU_COPY: {
+			copy();
+		} break;
+		case MENU_PASTE: {
+
+			paste();
+		} break;
+		case MENU_CLEAR: {
+			clear();
+		} break;
+		case MENU_SELECT_ALL: {
+			select_all();
+		} break;
+		case MENU_UNDO: {
+			undo();
+		} break;
+
+	};
+}
+
+PopupMenu *TextEdit::get_menu() const {
+	return menu;
+}
+
 void TextEdit::_bind_methods() {
 void TextEdit::_bind_methods() {
 
 
 
 
@@ -4215,6 +4256,8 @@ void TextEdit::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_symbol_color","color"),&TextEdit::set_symbol_color);
 	ObjectTypeDB::bind_method(_MD("set_symbol_color","color"),&TextEdit::set_symbol_color);
 	ObjectTypeDB::bind_method(_MD("set_custom_bg_color","color"),&TextEdit::set_custom_bg_color);
 	ObjectTypeDB::bind_method(_MD("set_custom_bg_color","color"),&TextEdit::set_custom_bg_color);
 	ObjectTypeDB::bind_method(_MD("clear_colors"),&TextEdit::clear_colors);
 	ObjectTypeDB::bind_method(_MD("clear_colors"),&TextEdit::clear_colors);
+	ObjectTypeDB::bind_method(_MD("menu_option"),&TextEdit::menu_option);
+	ObjectTypeDB::bind_method(_MD("get_menu:PopupMenu"),&TextEdit::get_menu);
 
 
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret/caret_blink"), _SCS("cursor_set_blink_enabled"), _SCS("cursor_get_blink_enabled"));;
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret/caret_blink"), _SCS("cursor_set_blink_enabled"), _SCS("cursor_get_blink_enabled"));;
 	ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "caret/caret_blink_speed",PROPERTY_HINT_RANGE,"0.1,10,0.1"), _SCS("cursor_set_blink_speed"),_SCS("cursor_get_blink_speed") );
 	ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "caret/caret_blink_speed",PROPERTY_HINT_RANGE,"0.1,10,0.1"), _SCS("cursor_set_blink_speed"),_SCS("cursor_get_blink_speed") );
@@ -4223,6 +4266,15 @@ void TextEdit::_bind_methods() {
 	ADD_SIGNAL(MethodInfo("text_changed"));
 	ADD_SIGNAL(MethodInfo("text_changed"));
 	ADD_SIGNAL(MethodInfo("request_completion"));
 	ADD_SIGNAL(MethodInfo("request_completion"));
 
 
+	BIND_CONSTANT( MENU_CUT );
+	BIND_CONSTANT( MENU_COPY );
+	BIND_CONSTANT( MENU_PASTE );
+	BIND_CONSTANT( MENU_CLEAR );
+	BIND_CONSTANT( MENU_SELECT_ALL );
+	BIND_CONSTANT( MENU_UNDO );
+	BIND_CONSTANT( MENU_MAX );
+
+
 }
 }
 
 
 TextEdit::TextEdit()  {
 TextEdit::TextEdit()  {
@@ -4327,6 +4379,20 @@ TextEdit::TextEdit()  {
 	brace_matching_enabled=false;
 	brace_matching_enabled=false;
 	auto_indent=false;
 	auto_indent=false;
 	insert_mode = false;
 	insert_mode = false;
+
+	menu = memnew( PopupMenu );
+	add_child(menu);
+	menu->add_item(TTR("Cut"),MENU_CUT,KEY_MASK_CMD|KEY_X);
+	menu->add_item(TTR("Copy"),MENU_COPY,KEY_MASK_CMD|KEY_C);
+	menu->add_item(TTR("Paste"),MENU_PASTE,KEY_MASK_CMD|KEY_V);
+	menu->add_separator();
+	menu->add_item(TTR("Select All"),MENU_SELECT_ALL,KEY_MASK_CMD|KEY_A);
+	menu->add_item(TTR("Clear"),MENU_CLEAR);
+	menu->add_separator();
+	menu->add_item(TTR("Undo"),MENU_UNDO,KEY_MASK_CMD|KEY_Z);
+	menu->connect("item_pressed",this,"menu_option");
+
+
 }
 }
 
 
 TextEdit::~TextEdit()
 TextEdit::~TextEdit()

+ 18 - 0
scene/gui/text_edit.h

@@ -31,6 +31,7 @@
 
 
 #include "scene/gui/control.h"
 #include "scene/gui/control.h"
 #include "scene/gui/scroll_bar.h"
 #include "scene/gui/scroll_bar.h"
+#include "scene/gui/popup_menu.h"
 #include "scene/main/timer.h"
 #include "scene/main/timer.h"
 
 
 
 
@@ -290,6 +291,8 @@ class TextEdit : public Control  {
 
 
 	DVector<int> _search_bind(const String &p_key,uint32_t p_search_flags, int p_from_line,int p_from_column) const;
 	DVector<int> _search_bind(const String &p_key,uint32_t p_search_flags, int p_from_line,int p_from_column) const;
 
 
+	PopupMenu *menu;
+
 	void _clear();
 	void _clear();
 	void _cancel_completion();
 	void _cancel_completion();
 	void _cancel_code_hint();
 	void _cancel_code_hint();
@@ -317,6 +320,17 @@ protected:
 
 
 public:
 public:
 
 
+	enum MenuItems {
+		MENU_CUT,
+		MENU_COPY,
+		MENU_PASTE,
+		MENU_CLEAR,
+		MENU_SELECT_ALL,
+		MENU_UNDO,
+		MENU_MAX
+
+	};
+
 	enum SearchFlags {
 	enum SearchFlags {
 
 
 		SEARCH_MATCH_CASE=1,
 		SEARCH_MATCH_CASE=1,
@@ -433,6 +447,8 @@ public:
 	uint32_t get_saved_version() const;
 	uint32_t get_saved_version() const;
 	void tag_saved_version();
 	void tag_saved_version();
 
 
+	void menu_option(int p_option);
+
 	void set_show_line_numbers(bool p_show);
 	void set_show_line_numbers(bool p_show);
 
 
 	void set_tooltip_request_func(Object *p_obj, const StringName& p_function, const Variant& p_udata);
 	void set_tooltip_request_func(Object *p_obj, const StringName& p_function, const Variant& p_udata);
@@ -442,6 +458,8 @@ public:
 	void set_code_hint(const String& p_hint);
 	void set_code_hint(const String& p_hint);
 	void query_code_comple();
 	void query_code_comple();
 
 
+	PopupMenu *get_menu() const;
+
 	String get_text_for_completion();
 	String get_text_for_completion();
 
 
     virtual bool is_text_field() const;
     virtual bool is_text_field() const;