indexing description: "[ Basic delegate of an EM_TEXTAREA. ]" date: "$Date$" revision: "$Revision$" class EM_BASIC_TEXTAREA_DELEGATE inherit EM_TEXTBOX_DELEGATE redefine install, optimal_width, optimal_height, draw_body end feature -- Initialisation install (textarea: EM_TEXTAREA) is -- Install style on `textarea'. -- Set up all default values for background, border, font and colors. do Precursor {EM_TEXTBOX_DELEGATE} (textarea) textarea.set_background_color (theme_colors.standard_background) textarea.set_border (create {EM_LINE_BORDER}.make (create {EM_COLOR}.make_black, 1)) end feature -- Measurement optimal_width (textarea: EM_TEXTAREA): INTEGER is -- Optimal width of `textarea' local lines: DS_LIST [STRING] do lines := line_splitter.split (textarea.text) from lines.start until lines.after loop Result := Result.max (textarea.font.string_width (lines.item_for_iteration)) lines.forth end Result := Result + textarea.border.left + textarea.border.right + 2 end optimal_height (textarea: EM_TEXTAREA): INTEGER is -- Optimal height of `textarea' local lines: DS_LIST [STRING] do lines := line_splitter.split (textarea.text) from lines.start until lines.after loop Result := Result + textarea.font.string_height (lines.item_for_iteration) lines.forth end Result := Result + textarea.border.top + textarea.border.bottom + 2 end feature -- Drawing draw_body (textarea: EM_TEXTAREA) is -- Draw body of `textarea'. local y, textarea_width, line_width: INTEGER lines, words: DS_LIST [STRING] line, partial_line: STRING do if textarea.text.count > 0 then y := textarea.border.top + 1 -- Split on line separators textarea_width := textarea.inner_width - 2 lines := line_splitter.split (textarea.text) from lines.start until lines.after loop line := lines.item_for_iteration line_width := textarea.font.string_width (line) -- Test if the line fits into the textarea if line_width <= textarea_width then draw_text_internal (line, textarea, y) y := y + textarea.font.string_height (line) else -- Split line into words words := word_splitter.split (line) words.start partial_line := words.item_for_iteration words.forth from until words.after loop line_width := textarea.font.string_width (partial_line+" "+words.item_for_iteration) if line_width > textarea_width then draw_text_internal (partial_line, textarea, y) y := y + textarea.font.string_height (partial_line) partial_line := words.item_for_iteration else partial_line.append_string (" ") partial_line.append_string (words.item_for_iteration) end words.forth end draw_text_internal (partial_line, textarea, y) y := y + textarea.font.string_height (partial_line) end lines.forth end end end feature -- Basic operations position_to_text_index (textarea: EM_TEXTAREA; a_x, a_y: INTEGER): INTEGER is -- Index in string at position `a_x' `a_y'. do Result := textarea.cursor_position end feature {NONE} -- Implementation draw_text_internal (text: STRING; textarea: EM_TEXTAREA; y: INTEGER) is -- Draw text at height `y'. local x: INTEGER do if text.count > 0 then x := textarea.border.left + 1 textarea.surface.set_drawing_color (textarea.foreground_color) textarea.font.draw_string (text, textarea.surface, x, y) end end line_splitter: ST_SPLITTER is -- Line splitter once create Result.make Result.set_separators ("%N%R") end word_splitter: ST_SPLITTER is -- Word splitter once create Result.make Result.set_separators (" ") end end