Просмотр исходного кода

Added alignment to LineEdit GUI control.

Saracen 10 лет назад
Родитель
Сommit
0006f035eb
2 измененных файлов с 124 добавлено и 16 удалено
  1. 105 14
      scene/gui/line_edit.cpp
  2. 19 2
      scene/gui/line_edit.h

+ 105 - 14
scene/gui/line_edit.cpp

@@ -145,6 +145,13 @@ void LineEdit::_input_event(InputEvent p_event) {
 
 							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 {
@@ -164,6 +171,13 @@ void LineEdit::_input_event(InputEvent p_event) {
 							selection_clear();
 							undo_text = text;
 							text = text.substr(cursor_pos,text.length()-cursor_pos);
+
+							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;
+
 							set_cursor_pos(0);
 							emit_signal("text_changed",text);
 							_change_notify("text");
@@ -303,6 +317,18 @@ void LineEdit::_input_event(InputEvent p_event) {
 	}
 }
 
+void LineEdit::set_align(Align p_align) {
+
+	ERR_FAIL_INDEX(p_align, 4);
+	align = p_align;
+	update();
+}
+
+LineEdit::Align LineEdit::get_align() const{
+
+	return align;
+}
+
 Variant LineEdit::get_drag_data(const Point2& p_point) {
 
 	if (selection.drag_attempt && selection.enabled) {
@@ -325,7 +351,13 @@ void LineEdit::drop_data(const Point2& p_point,const Variant& p_data){
 	if (p_data.get_type()==Variant::STRING) {
 		set_cursor_at_pixel_pos(p_point.x);
 		int selected = selection.end - selection.begin;
+
+		Ref<Font> font = get_font("font");
+		for (int i = selection.begin; i<selection.end; i++)
+			cached_width -= font->get_char_size(text[i]).width;
+
 		text.erase(selection.begin, selected);
+
 		append_at_cursor(p_data);
 		selection.begin = cursor_pos-selected;
 		selection.end = cursor_pos;
@@ -365,8 +397,25 @@ void LineEdit::_notification(int p_what) {
 				get_stylebox("focus")->draw( ci, Rect2( Point2(), size ) );
 			}
 
-						
-			int ofs=style->get_offset().x;
+			int x_ofs=0;
+
+			switch (align) {
+				
+				case ALIGN_FILL:
+				case ALIGN_LEFT: {
+
+					x_ofs=style->get_offset().x;
+				} break;
+				case ALIGN_CENTER: {
+
+					x_ofs=x_ofs=int(size.width-(cached_width))/2;
+				} break;
+				case ALIGN_RIGHT: {
+
+					x_ofs=x_ofs=int(size.width-style->get_offset().x-(cached_width));
+				} break;
+			}
+
 			int ofs_max=width-style->get_minimum_size().width;
 			int char_ofs=window_pos;
 			
@@ -391,29 +440,29 @@ void LineEdit::_notification(int p_what) {
 				int char_width=font->get_char_size( cchar,next ).width;
 								
 		// end of widget, break!
-				if ( (ofs+char_width) > ofs_max )
+				if ((x_ofs + char_width) > ofs_max)
 					break;
 				
 				
 				bool selected=selection.enabled && char_ofs>=selection.begin && char_ofs<selection.end;
 				
 				if (selected)
-					VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2( Point2( ofs , y_ofs ),Size2( char_width, y_area )),selection_color);
+					VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(char_width, y_area)), selection_color);
 				
 
-				font->draw_char(ci,Point2( ofs , y_ofs+font_ascent ), cchar, next,selected?font_color_selected:font_color );
+				font->draw_char(ci, Point2(x_ofs, y_ofs + font_ascent), cchar, next, selected ? font_color_selected : font_color);
 				
 				if (char_ofs==cursor_pos && has_focus())
 					VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(
-						Point2( ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color );
+						Point2( x_ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color );
 				
-				ofs+=char_width;
+				x_ofs+=char_width;
 				char_ofs++;
 			}
 
 			if (char_ofs==cursor_pos && has_focus()) //may be at the end
 				VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(
-					Point2( ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color );		
+					Point2( x_ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color );		
 			
 		} break;
 		case NOTIFICATION_FOCUS_ENTER: {
@@ -484,9 +533,29 @@ void LineEdit::shift_selection_check_post(bool p_shift) {
 
 void LineEdit::set_cursor_at_pixel_pos(int p_x) {
 	
-	int ofs=window_pos;
-	int pixel_ofs=get_stylebox("normal")->get_offset().x;
-	Ref<Font> font=get_font("font");
+	Ref<Font> font = get_font("font");
+	int ofs = window_pos;
+	Ref<StyleBox> style = get_stylebox("normal");
+	int pixel_ofs = 0;
+	Size2 size = get_size();
+
+	switch (align) {
+				
+		case ALIGN_FILL:
+		case ALIGN_LEFT: {
+			
+			pixel_ofs = int(style->get_offset().x);
+		} break;
+		case ALIGN_CENTER: {
+
+			pixel_ofs=int(size.width-(cached_width))/2;
+		} break;
+		case ALIGN_RIGHT: {
+
+			pixel_ofs=int(size.width-style->get_offset().x-(cached_width));
+		} break;
+	}
+
 
 	while (ofs<text.length()) {
 		
@@ -523,6 +592,8 @@ void LineEdit::delete_char() {
 	
 	if ((text.length()<=0) || (cursor_pos==0)) return;
 	
+	Ref<Font> font = get_font("font");
+	cached_width -= font->get_char_size(text[cursor_pos - 1]).width;
 	
 	text.erase( cursor_pos-1, 1 );
 	
@@ -626,17 +697,22 @@ void LineEdit::append_at_cursor(String p_text) {
 	if ( ( max_length <= 0 ) || (text.length()+p_text.length() <= max_length)) {
 		
 		undo_text = text;
+
+		Ref<Font> font = get_font("font");
+
+		for (int i = 0; i<p_text.length(); i++)
+			cached_width += font->get_char_size(p_text[i]).width;
+
 		String pre = text.substr( 0, cursor_pos );
 		String post = text.substr( cursor_pos, text.length()-cursor_pos );
 		text=pre+p_text+post;
 		set_cursor_pos(cursor_pos+p_text.length());
-		
 	}
-	
 }
 
 void LineEdit::clear_internal() {
 	
+	cached_width = 0;
 	cursor_pos=0;
 	window_pos=0;
 	undo_text="";
@@ -676,6 +752,12 @@ void LineEdit::selection_delete() {
 	if (selection.enabled) {
 		
 		undo_text = text;
+
+		Ref<Font> font = get_font("font");
+
+		for (int i = selection.begin; i<selection.end; i++)
+			cached_width -= font->get_char_size(text[i]).width;
+
 		text.erase(selection.begin,selection.end-selection.begin);
 		cursor_pos-=CLAMP( cursor_pos-selection.begin, 0, selection.end-selection.begin);
 		
@@ -789,6 +871,8 @@ bool LineEdit::is_text_field() const {
 
 void LineEdit::_bind_methods() {
 	
+	ObjectTypeDB::bind_method(_MD("set_align", "align"), &LineEdit::set_align);
+	ObjectTypeDB::bind_method(_MD("get_align"), &LineEdit::get_align);
 
 	ObjectTypeDB::bind_method(_MD("_input_event"),&LineEdit::_input_event);
 	ObjectTypeDB::bind_method(_MD("clear"),&LineEdit::clear);	
@@ -809,15 +893,22 @@ void LineEdit::_bind_methods() {
 	ADD_SIGNAL( MethodInfo("text_changed", PropertyInfo( Variant::STRING, "text" )) );
 	ADD_SIGNAL( MethodInfo("text_entered", PropertyInfo( Variant::STRING, "text" )) );
 
+	BIND_CONSTANT(ALIGN_LEFT);
+	BIND_CONSTANT(ALIGN_CENTER);
+	BIND_CONSTANT(ALIGN_RIGHT);
+	BIND_CONSTANT(ALIGN_FILL);
+
 	ADD_PROPERTY( 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_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") );
-
 }
 
 LineEdit::LineEdit() {
 	
+	align = ALIGN_LEFT;
+	cached_width = 0;
 	cursor_pos=0;
 	window_pos=0;
 	max_length = 0;

+ 19 - 2
scene/gui/line_edit.h

@@ -36,7 +36,18 @@
 class LineEdit : public Control {
 	
 	OBJ_TYPE( LineEdit, Control );
-	
+
+public:
+	enum Align {
+
+		ALIGN_LEFT,
+		ALIGN_CENTER,
+		ALIGN_RIGHT,
+		ALIGN_FILL
+	};
+private:
+	Align align;
+
 	bool editable;
 	bool pass;
 	
@@ -46,6 +57,8 @@ class LineEdit : public Control {
 	int cursor_pos;
 	int window_pos;
 	int max_length; // 0 for no maximum
+
+	int cached_width;
 	
 	struct Selection {
 		
@@ -83,7 +96,8 @@ class LineEdit : public Control {
 protected:	
 	static void _bind_methods();	
 public:
-	
+	void set_align(Align p_align);
+	Align get_align() const;
 		
 	virtual Variant get_drag_data(const Point2& p_point);
 	virtual bool can_drop_data(const Point2& p_point,const Variant& p_data) const;
@@ -119,4 +133,7 @@ public:
 	
 };
 
+
+VARIANT_ENUM_CAST(LineEdit::Align);
+
 #endif