indexing description: "[ Basic delegate of an EM_LABEL. ]" date: "$Date$" revision: "$Revision$" class EM_BASIC_LABEL_DELEGATE inherit EM_WIDGET_DELEGATE redefine install, optimal_width, optimal_height, draw_body end feature -- Initialisation install (label: EM_LABEL) is -- Install style on `label'. -- Set up all default values for background, border, font and colors. do Precursor {EM_WIDGET_DELEGATE} (label) label.set_transparent end feature -- Measurement optimal_width (label: EM_LABEL): INTEGER is -- Optimal width of `label' local lines: DS_LIST [STRING] do if label.is_multilined then lines := line_splitter.split (label.text) from lines.start until lines.after loop Result := Result.max (label.font.string_width (lines.item_for_iteration)) lines.forth end Result := Result + label.border.left + label.border.right + 2 else Result := label.font.string_width (label.text) + label.border.left + label.border.right + 2 end end optimal_height (label: EM_LABEL): INTEGER is -- Optimal height of `label' local lines: DS_LIST [STRING] do if label.is_multilined then lines := line_splitter.split (label.text) from lines.start until lines.after loop Result := Result + label.font.string_height (lines.item_for_iteration) lines.forth end Result := Result + label.border.top + label.border.bottom + 2 else Result := label.font.string_height (label.text) + label.border.top + label.border.bottom + 2 end end feature -- Drawing draw_body (label: EM_LABEL) is -- Draw body of `label'. local y: INTEGER label_width, line_width: INTEGER lines, words: DS_LIST [STRING] line, partial_line: STRING do if label.text.count > 0 then -- Find y value -- TODO: this will not work in vertical_centered mode if label.is_top_aligned then y := label.border.top + 1 elseif label.is_bottom_aligned then y := label.height - label.optimal_height + label.border.top + 1 else y := (label.height - label.optimal_height + label.border.top + label.border.bottom + 2) // 2 end if not label.is_multilined then -- Draw one line draw_text_internal (label.text, label, y) else -- Split on line separators label_width := label.inner_width - 2 lines := line_splitter.split (label.text) from lines.start until lines.after loop line := lines.item_for_iteration line_width := label.font.string_width (line) -- Test if the line fits into the label if line_width <= label_width then draw_text_internal (line, label, y) y := y + label.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 := label.font.string_width (partial_line+" "+words.item_for_iteration) if line_width > label_width then draw_text_internal (partial_line, label, y) y := y + label.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, label, y) y := y + label.font.string_height (partial_line) end lines.forth end end end end feature {NONE} -- Implementation draw_text_internal (text: STRING; label: EM_LABEL; y: INTEGER) is -- draw text at height `y'. local x: INTEGER shadow_color: EM_COLOR do if text.count > 0 then if label.is_left_aligned then x := label.border.left + 1 elseif label.is_right_aligned then x := label.width-label.border.right-label.font.string_width (text) - 1 else x := (label.width-label.font.string_width (text)) // 2 end if label.is_shadow_enabled then if label.shadow_color = Void then create shadow_color.make_with_rgb ((255-label.foreground_color.red)//2, (255-label.foreground_color.green)//2, (255-label.foreground_color.blue)//2) label.surface.set_drawing_color (shadow_color) else label.surface.set_drawing_color (label.shadow_color) end label.font.draw_string (text, label.surface, x+1, y+1) end label.surface.set_drawing_color (label.foreground_color) label.font.draw_string (text, label.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