mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 15:47:42 +00:00
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.
This commit is contained in:
parent
207319ecf1
commit
0583f75926
6 changed files with 42 additions and 4 deletions
|
@ -160,6 +160,9 @@ void AbstractView::begin_editing(const ModelIndex& index)
|
||||||
VERIFY(model());
|
VERIFY(model());
|
||||||
stop_editing();
|
stop_editing();
|
||||||
};
|
};
|
||||||
|
m_editing_delegate->on_change = [this, index] {
|
||||||
|
editing_widget_did_change(index);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractView::stop_editing()
|
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)
|
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;
|
Color text_color;
|
||||||
if (is_selected)
|
if (is_selected)
|
||||||
text_color = is_focused() ? palette().selection_text() : palette().inactive_selection_text();
|
text_color = is_focused() ? palette().selection_text() : palette().inactive_selection_text();
|
||||||
|
|
|
@ -152,6 +152,7 @@ protected:
|
||||||
virtual void toggle_selection(const ModelIndex&);
|
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_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 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);
|
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);
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,9 @@ void ColumnsView::paint_event(PaintEvent& event)
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::IntRect row_rect { column_x, row * item_height(), column.width, item_height() };
|
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);
|
auto icon = index.data(ModelRole::Icon);
|
||||||
Gfx::IntRect icon_rect = { column_x + icon_spacing(), 0, icon_size(), icon_size() };
|
Gfx::IntRect icon_rect = { column_x + icon_spacing(), 0, icon_size(), icon_size() };
|
||||||
|
|
|
@ -8,8 +8,10 @@
|
||||||
#include <LibCore/Timer.h>
|
#include <LibCore/Timer.h>
|
||||||
#include <LibGUI/IconView.h>
|
#include <LibGUI/IconView.h>
|
||||||
#include <LibGUI/Model.h>
|
#include <LibGUI/Model.h>
|
||||||
|
#include <LibGUI/ModelEditingDelegate.h>
|
||||||
#include <LibGUI/Painter.h>
|
#include <LibGUI/Painter.h>
|
||||||
#include <LibGUI/Scrollbar.h>
|
#include <LibGUI/Scrollbar.h>
|
||||||
|
|
||||||
#include <LibGfx/Palette.h>
|
#include <LibGfx/Palette.h>
|
||||||
|
|
||||||
REGISTER_WIDGET(GUI, IconView);
|
REGISTER_WIDGET(GUI, IconView);
|
||||||
|
@ -401,10 +403,24 @@ Gfx::IntRect IconView::editing_rect(ModelIndex const& index) const
|
||||||
if (!index.is_valid())
|
if (!index.is_valid())
|
||||||
return {};
|
return {};
|
||||||
auto& item_data = get_item_data(index.row());
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::IntRect IconView::paint_invalidation_rect(const ModelIndex& index) const
|
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
|
||||||
{
|
{
|
||||||
if (!index.is_valid())
|
if (!index.is_valid())
|
||||||
return {};
|
return {};
|
||||||
|
@ -548,7 +564,8 @@ void IconView::paint_event(PaintEvent& event)
|
||||||
|
|
||||||
const auto& text_rect = item_data.text_rect;
|
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()) {
|
if (is_focused() && item_data.index == cursor_index()) {
|
||||||
painter.draw_rect(text_rect, widget_background_color);
|
painter.draw_rect(text_rect, widget_background_color);
|
||||||
|
|
|
@ -57,6 +57,7 @@ private:
|
||||||
virtual void mouseup_event(MouseEvent&) override;
|
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_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 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;
|
virtual void move_cursor(CursorMovement, SelectionUpdate) override;
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ public:
|
||||||
|
|
||||||
Function<void()> on_commit;
|
Function<void()> on_commit;
|
||||||
Function<void()> on_rollback;
|
Function<void()> on_rollback;
|
||||||
|
Function<void()> on_change;
|
||||||
|
|
||||||
virtual Variant value() const = 0;
|
virtual Variant value() const = 0;
|
||||||
virtual void set_value(Variant const&, SelectionBehavior selection_behavior = SelectionBehavior::SelectAll) = 0;
|
virtual void set_value(Variant const&, SelectionBehavior selection_behavior = SelectionBehavior::SelectAll) = 0;
|
||||||
|
@ -55,6 +56,11 @@ protected:
|
||||||
if (on_rollback)
|
if (on_rollback)
|
||||||
on_rollback();
|
on_rollback();
|
||||||
}
|
}
|
||||||
|
void change()
|
||||||
|
{
|
||||||
|
if (on_change)
|
||||||
|
on_change();
|
||||||
|
}
|
||||||
|
|
||||||
const ModelIndex& index() const { return m_index; }
|
const ModelIndex& index() const { return m_index; }
|
||||||
|
|
||||||
|
@ -72,12 +78,17 @@ public:
|
||||||
virtual RefPtr<Widget> create_widget() override
|
virtual RefPtr<Widget> create_widget() override
|
||||||
{
|
{
|
||||||
auto textbox = TextBox::construct();
|
auto textbox = TextBox::construct();
|
||||||
|
textbox->set_frame_shape(Gfx::FrameShape::NoFrame);
|
||||||
|
|
||||||
textbox->on_return_pressed = [this] {
|
textbox->on_return_pressed = [this] {
|
||||||
commit();
|
commit();
|
||||||
};
|
};
|
||||||
textbox->on_escape_pressed = [this] {
|
textbox->on_escape_pressed = [this] {
|
||||||
rollback();
|
rollback();
|
||||||
};
|
};
|
||||||
|
textbox->on_change = [this] {
|
||||||
|
change();
|
||||||
|
};
|
||||||
return textbox;
|
return textbox;
|
||||||
}
|
}
|
||||||
virtual Variant value() const override { return static_cast<const TextBox*>(widget())->text(); }
|
virtual Variant value() const override { return static_cast<const TextBox*>(widget())->text(); }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue