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

LibGUI: Add TextEditor::set_icon()

You can now set a 16x16 icon on a single-line TextEditor. If present,
the icon will be painted to the left of the text content.
Andreas Kling 5 лет назад
Родитель
Сommit
f50bc0f314
2 измененных файлов с 29 добавлено и 2 удалено
  1. 21 2
      Libraries/LibGUI/TextEditor.cpp
  2. 8 0
      Libraries/LibGUI/TextEditor.h

+ 21 - 2
Libraries/LibGUI/TextEditor.cpp

@@ -141,6 +141,9 @@ TextPosition TextEditor::text_position_at(const Gfx::IntPoint& a_position) const
     position.move_by(-(m_horizontal_content_padding + ruler_width()), 0);
     position.move_by(-frame_thickness(), -frame_thickness());
 
+    if (is_single_line() && icon())
+        position.move_by(-(icon_size() + icon_padding()), 0);
+
     size_t line_index = 0;
 
     if (is_line_wrapping_enabled()) {
@@ -515,6 +518,11 @@ void TextEditor::paint_event(PaintEvent& event)
         });
     }
 
+    if (!is_multi_line() && m_icon) {
+        Gfx::IntRect icon_rect { icon_padding(), 1, icon_size(), icon_size() };
+        painter.draw_scaled_bitmap(icon_rect, *m_icon, m_icon->rect());
+    }
+
     if (is_focused() && m_cursor_state)
         painter.fill_rect(cursor_content_rect(), palette().text_cursor());
 }
@@ -963,7 +971,7 @@ int TextEditor::content_x_for_position(const TextPosition& position) const
             }
             return IterationDecision::Continue;
         });
-        return m_horizontal_content_padding + x_offset;
+        return m_horizontal_content_padding + ((is_single_line() && icon()) ? (icon_size() + icon_padding()) : 0) + x_offset;
     case Gfx::TextAlignment::CenterRight:
         // FIXME
         ASSERT(!is_line_wrapping_enabled());
@@ -1481,8 +1489,11 @@ void TextEditor::for_each_visual_line(size_t line_index, Callback callback) cons
         };
         if (is_right_text_alignment(text_alignment()))
             visual_line_rect.set_right_without_resize(editor_visible_text_rect.right());
-        if (!is_multi_line())
+        if (is_single_line()) {
             visual_line_rect.center_vertically_within(editor_visible_text_rect);
+            if (m_icon)
+                visual_line_rect.move_by(icon_size() + icon_padding(), 0);
+        }
         if (callback(visual_line_rect, visual_line_view, start_of_line) == IterationDecision::Break)
             break;
         start_of_line = visual_line_break;
@@ -1620,4 +1631,12 @@ int TextEditor::fixed_glyph_width() const
     return font().glyph_width(' ');
 }
 
+void TextEditor::set_icon(const Gfx::Bitmap* icon)
+{
+    if (m_icon == icon)
+        return;
+    m_icon = icon;
+    update();
+}
+
 }

+ 8 - 0
Libraries/LibGUI/TextEditor.h

@@ -74,6 +74,9 @@ public:
     bool is_ruler_visible() const { return m_ruler_visible; }
     void set_ruler_visible(bool b) { m_ruler_visible = b; }
 
+    void set_icon(const Gfx::Bitmap*);
+    const Gfx::Bitmap* icon() const { return m_icon; }
+
     Function<void()> on_cursor_change;
     Function<void()> on_selection_change;
 
@@ -177,6 +180,9 @@ private:
     void defer_reflow();
     void undefer_reflow();
 
+    int icon_size() const { return 16; }
+    int icon_padding() const { return 2; }
+
     class ReflowDeferrer {
     public:
         ReflowDeferrer(TextEditor& editor)
@@ -279,6 +285,8 @@ private:
 
     RefPtr<Core::Timer> m_automatic_selection_scroll_timer;
     Gfx::IntPoint m_last_mousemove_position;
+
+    RefPtr<Gfx::Bitmap> m_icon;
 };
 
 }