From 0006f035ebb020227ad5b67faf4e04b723b1e0ec Mon Sep 17 00:00:00 2001 From: Saracen Date: Sat, 15 Aug 2015 07:47:22 +0100 Subject: [PATCH] Added alignment to LineEdit GUI control. --- scene/gui/line_edit.cpp | 119 +++++++++++++++++++++++++++++++++++----- scene/gui/line_edit.h | 21 ++++++- 2 files changed, 124 insertions(+), 16 deletions(-) diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 2b4d7db01e..310e2fee8b 100644 --- a/scene/gui/line_edit.cpp +++ b/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 = get_font("font"); + + cached_width = 0; + for (int i = 0; iget_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 = get_font("font"); + + cached_width = 0; + for (int i = 0; iget_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 = get_font("font"); + for (int i = selection.begin; iget_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_ofscanvas_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=get_font("font"); + Ref font = get_font("font"); + int ofs = window_pos; + Ref 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 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 = get_font("font"); + + for (int i = 0; iget_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 = get_font("font"); + + for (int i = selection.begin; iget_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; diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index b1c4c8f616..f28136d66e 100644 --- a/scene/gui/line_edit.h +++ b/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