From 0583f75926b0842f582efdcc4870116bc3c79382 Mon Sep 17 00:00:00 2001 From: Marcus Nilsson Date: Sun, 5 Sep 2021 13:32:23 +0200 Subject: LibGUI: Dynamically resize editing content rect in IconView This makes IconView aware of the text width of the ModelEditingDelegate widget when editing an index and allows us to resize the content rect as needed. This also removes the border from the textbox since it could collide with the icon in ColumnsView. While editing we also skip painting the inactive selection rect since it would otherwise show when the content rect gets smaller. --- Userland/Libraries/LibGUI/AbstractView.cpp | 6 ++++++ Userland/Libraries/LibGUI/AbstractView.h | 1 + Userland/Libraries/LibGUI/ColumnsView.cpp | 4 +++- Userland/Libraries/LibGUI/IconView.cpp | 23 ++++++++++++++++++++--- Userland/Libraries/LibGUI/IconView.h | 1 + Userland/Libraries/LibGUI/ModelEditingDelegate.h | 11 +++++++++++ 6 files changed, 42 insertions(+), 4 deletions(-) (limited to 'Userland/Libraries/LibGUI') diff --git a/Userland/Libraries/LibGUI/AbstractView.cpp b/Userland/Libraries/LibGUI/AbstractView.cpp index dd426ec8be..e86826437b 100644 --- a/Userland/Libraries/LibGUI/AbstractView.cpp +++ b/Userland/Libraries/LibGUI/AbstractView.cpp @@ -160,6 +160,9 @@ void AbstractView::begin_editing(const ModelIndex& index) VERIFY(model()); stop_editing(); }; + m_editing_delegate->on_change = [this, index] { + editing_widget_did_change(index); + }; } void AbstractView::stop_editing() @@ -670,6 +673,9 @@ bool AbstractView::is_highlighting_searching(const ModelIndex& index) const void AbstractView::draw_item_text(Gfx::Painter& painter, const ModelIndex& index, bool is_selected, const Gfx::IntRect& text_rect, const StringView& item_text, const Gfx::Font& font, Gfx::TextAlignment alignment, Gfx::TextElision elision, size_t search_highlighting_offset) { + if (m_edit_index == index) + return; + Color text_color; if (is_selected) text_color = is_focused() ? palette().selection_text() : palette().inactive_selection_text(); diff --git a/Userland/Libraries/LibGUI/AbstractView.h b/Userland/Libraries/LibGUI/AbstractView.h index 2fbb86ae64..fce68e8bc7 100644 --- a/Userland/Libraries/LibGUI/AbstractView.h +++ b/Userland/Libraries/LibGUI/AbstractView.h @@ -152,6 +152,7 @@ protected: virtual void toggle_selection(const ModelIndex&); virtual void did_change_hovered_index([[maybe_unused]] const ModelIndex& old_index, [[maybe_unused]] const ModelIndex& new_index) { } virtual void did_change_cursor_index([[maybe_unused]] const ModelIndex& old_index, [[maybe_unused]] const ModelIndex& new_index) { } + virtual void editing_widget_did_change([[maybe_unused]] const ModelIndex& index) { } void draw_item_text(Gfx::Painter&, const ModelIndex&, bool, const Gfx::IntRect&, const StringView&, const Gfx::Font&, Gfx::TextAlignment, Gfx::TextElision, size_t search_highlighting_offset = 0); diff --git a/Userland/Libraries/LibGUI/ColumnsView.cpp b/Userland/Libraries/LibGUI/ColumnsView.cpp index c11857bd34..d02898b345 100644 --- a/Userland/Libraries/LibGUI/ColumnsView.cpp +++ b/Userland/Libraries/LibGUI/ColumnsView.cpp @@ -105,7 +105,9 @@ void ColumnsView::paint_event(PaintEvent& event) } Gfx::IntRect row_rect { column_x, row * item_height(), column.width, item_height() }; - painter.fill_rect(row_rect, background_color); + + if (m_edit_index.row() != row) + painter.fill_rect(row_rect, background_color); auto icon = index.data(ModelRole::Icon); Gfx::IntRect icon_rect = { column_x + icon_spacing(), 0, icon_size(), icon_size() }; diff --git a/Userland/Libraries/LibGUI/IconView.cpp b/Userland/Libraries/LibGUI/IconView.cpp index 0718515be4..b894c67ca1 100644 --- a/Userland/Libraries/LibGUI/IconView.cpp +++ b/Userland/Libraries/LibGUI/IconView.cpp @@ -8,8 +8,10 @@ #include #include #include +#include #include #include + #include REGISTER_WIDGET(GUI, IconView); @@ -401,10 +403,24 @@ Gfx::IntRect IconView::editing_rect(ModelIndex const& index) const if (!index.is_valid()) return {}; auto& item_data = get_item_data(index.row()); - return item_data.text_rect.inflated(4, 4); + auto editing_rect = item_data.text_rect; + editing_rect.set_height(font_for_index(index)->glyph_height() + 8); + editing_rect.set_y(item_data.text_rect.y() - 2); + return editing_rect; +} + +void IconView::editing_widget_did_change(const ModelIndex& index) +{ + if (m_editing_delegate->value().is_string()) { + auto text_width = font_for_index(index)->width(m_editing_delegate->value().as_string()); + m_edit_widget_content_rect.set_width(min(text_width + 8, effective_item_size().width())); + m_edit_widget_content_rect.center_horizontally_within(editing_rect(index).translated(frame_thickness(), frame_thickness())); + update_edit_widget_position(); + } } -Gfx::IntRect IconView::paint_invalidation_rect(const ModelIndex& index) const +Gfx::IntRect +IconView::paint_invalidation_rect(const ModelIndex& index) const { if (!index.is_valid()) return {}; @@ -548,7 +564,8 @@ void IconView::paint_event(PaintEvent& event) const auto& text_rect = item_data.text_rect; - painter.fill_rect(text_rect, background_color); + if (m_edit_index != item_data.index) + painter.fill_rect(text_rect, background_color); if (is_focused() && item_data.index == cursor_index()) { painter.draw_rect(text_rect, widget_background_color); diff --git a/Userland/Libraries/LibGUI/IconView.h b/Userland/Libraries/LibGUI/IconView.h index 8157a9da34..53da8f638b 100644 --- a/Userland/Libraries/LibGUI/IconView.h +++ b/Userland/Libraries/LibGUI/IconView.h @@ -57,6 +57,7 @@ private: virtual void mouseup_event(MouseEvent&) override; virtual void did_change_hovered_index(const ModelIndex& old_index, const ModelIndex& new_index) override; virtual void did_change_cursor_index(const ModelIndex& old_index, const ModelIndex& new_index) override; + virtual void editing_widget_did_change(const ModelIndex& index) override; virtual void move_cursor(CursorMovement, SelectionUpdate) override; diff --git a/Userland/Libraries/LibGUI/ModelEditingDelegate.h b/Userland/Libraries/LibGUI/ModelEditingDelegate.h index a910b67b05..faf11d276a 100644 --- a/Userland/Libraries/LibGUI/ModelEditingDelegate.h +++ b/Userland/Libraries/LibGUI/ModelEditingDelegate.h @@ -35,6 +35,7 @@ public: Function on_commit; Function on_rollback; + Function on_change; virtual Variant value() const = 0; virtual void set_value(Variant const&, SelectionBehavior selection_behavior = SelectionBehavior::SelectAll) = 0; @@ -55,6 +56,11 @@ protected: if (on_rollback) on_rollback(); } + void change() + { + if (on_change) + on_change(); + } const ModelIndex& index() const { return m_index; } @@ -72,12 +78,17 @@ public: virtual RefPtr create_widget() override { auto textbox = TextBox::construct(); + textbox->set_frame_shape(Gfx::FrameShape::NoFrame); + textbox->on_return_pressed = [this] { commit(); }; textbox->on_escape_pressed = [this] { rollback(); }; + textbox->on_change = [this] { + change(); + }; return textbox; } virtual Variant value() const override { return static_cast(widget())->text(); } -- cgit v1.2.3