+
+ if(!style)
+ {
+ text_part = 0;
+ return;
+ }
+
+ text_part = style->get_part("text");
+
+ if(multiline)
+ check_view_range();
+
+ check_cursor_blink();
+}
+
+void Entry::move_edit_position(Navigation nav, bool select)
+{
+ if(nav==NAV_LEFT)
+ {
+ if(edit_pos>0)
+ set_edit_position(edit_pos-1, select);
+ }
+ else if(nav==NAV_RIGHT)
+ {
+ if(edit_pos<text.size())
+ set_edit_position(edit_pos+1, select);
+ }
+ else if(nav==NAV_DOWN)
+ {
+ unsigned row, col;
+ text.offset_to_coords(edit_pos, row, col);
+ set_edit_position(text.coords_to_offset(row+1, col), select);
+ }
+ else if(nav==NAV_UP)
+ {
+ unsigned row, col;
+ text.offset_to_coords(edit_pos, row, col);
+ set_edit_position((row>0 ? text.coords_to_offset(row-1, col) : 0), select);
+ }
+}
+
+void Entry::set_edit_position(unsigned ep, bool select)
+{
+ if(select && !selection_active)
+ selection_pos = edit_pos;
+ selection_active = select;
+
+ unsigned old_edit_pos = edit_pos;
+ edit_pos = min(ep, text.size());
+
+ if(edit_pos!=old_edit_pos)
+ signal_edit_position_changed.emit(edit_pos);
+
+ if(multiline)
+ check_view_range();
+ rebuild();
+}
+
+void Entry::erase_selection(bool emit_change)
+{
+ unsigned start, end;
+ if(!get_selection(start, end))
+ return;
+
+ text.erase(start, end-start);
+ if(emit_change)
+ signal_text_changed.emit(text.get());
+ set_edit_position(start, false);
+}
+
+void Entry::check_cursor_blink()
+{
+ cursor_blink = (state&FOCUS);
+ if((state&FOCUS) && style)
+ {
+ const Part *cursor_part = style->get_part("cursor");
+ if(cursor_part && cursor_part->get_graphic(ACTIVE|FOCUS)!=cursor_part->get_graphic(NORMAL|FOCUS))
+ {
+ set_animation_interval(Time::sec/2);
+ return;
+ }
+ }
+
+ stop_animation();
+}
+
+void Entry::check_view_range()
+{
+ if(!multiline || !text_part)
+ return;
+
+ visible_rows = text.get_visible_lines(*text_part, geom, 0);
+
+ unsigned row, col;
+ text.offset_to_coords(edit_pos, row, col);
+
+ unsigned old_first_row = first_row;
+ if(first_row>row)
+ first_row = row;
+ else if(row>=first_row+visible_rows)
+ first_row = row+1-visible_rows;
+
+ unsigned scroll = max(text.get_n_lines(), visible_rows)-visible_rows;
+ if(first_row>scroll)
+ first_row = scroll;
+
+ if(first_row!=old_first_row)
+ signal_scroll_position_changed.emit(first_row);
+
+ slider->set_range(0, scroll);
+ slider->set_value(scroll-first_row);
+}
+
+void Entry::slider_value_changed(double value)
+{
+ if(text.get_n_lines()>visible_rows)
+ {
+ unsigned old_first_row = first_row;
+ first_row = text.get_n_lines()-visible_rows-static_cast<unsigned>(value);
+ if(first_row!=old_first_row)
+ signal_scroll_position_changed.emit(first_row);
+ }