diff options
Diffstat (limited to 'LibGUI')
-rw-r--r-- | LibGUI/GTreeView.cpp | 51 | ||||
-rw-r--r-- | LibGUI/GTreeView.h | 2 |
2 files changed, 43 insertions, 10 deletions
diff --git a/LibGUI/GTreeView.cpp b/LibGUI/GTreeView.cpp index ee99c46491..10638ef8e6 100644 --- a/LibGUI/GTreeView.cpp +++ b/LibGUI/GTreeView.cpp @@ -75,6 +75,7 @@ void GTreeView::mousedown_event(GMouseEvent& event) if (is_toggle && model.row_count(index)) { auto& metadata = ensure_metadata_for_index(index); metadata.open = !metadata.open; + update_content_size(); update(); } } @@ -86,7 +87,6 @@ void GTreeView::traverse_in_paint_order(Callback callback) const auto& model = *this->model(); int indent_level = 0; int y_offset = 0; - auto visible_content_rect = this->visible_content_rect(); Function<IterationDecision(const GModelIndex&)> traverse_index = [&] (const GModelIndex& index) { int row_count_at_index = model.row_count(index); @@ -104,10 +104,8 @@ void GTreeView::traverse_in_paint_order(Callback callback) const toggle_rect = { toggle_x, rect.y(), toggle_size(), toggle_size() }; toggle_rect.center_vertically_within(rect); } - if (rect.intersects(visible_content_rect)) { - if (callback(index, rect, toggle_rect, indent_level) == IterationDecision::Abort) - return IterationDecision::Abort; - } + if (callback(index, rect, toggle_rect, indent_level) == IterationDecision::Abort) + return IterationDecision::Abort; y_offset += item_height(); // NOTE: Skip traversing children if this index is closed! if (!metadata.open) @@ -134,12 +132,16 @@ void GTreeView::paint_event(GPaintEvent& event) painter.add_clip_rect(event.rect()); painter.fill_rect(event.rect(), Color::White); painter.translate(frame_inner_rect().location()); + painter.translate(-horizontal_scrollbar().value(), -vertical_scrollbar().value()); if (!model()) return; auto& model = *this->model(); + auto visible_content_rect = this->visible_content_rect(); traverse_in_paint_order([&] (const GModelIndex& index, const Rect& rect, const Rect& toggle_rect, int indent_level) { + if (!rect.intersects(visible_content_rect)) + return IterationDecision::Continue; #ifdef DEBUG_ITEM_RECTS painter.fill_rect(rect, Color::LightGray); #endif @@ -210,6 +212,12 @@ void GTreeView::scroll_into_view(const GModelIndex& a_index, Orientation orienta GScrollableWidget::scroll_into_view(found_rect, orientation); } +void GTreeView::did_update_model() +{ + GAbstractView::did_update_model(); + update_content_size(); +} + void GTreeView::did_update_selection() { ASSERT(model()); @@ -217,10 +225,33 @@ void GTreeView::did_update_selection() auto index = model.selected_index(); if (!index.is_valid()) return; - ensure_metadata_for_index(index).open = true; - auto parent = index.parent(); - while (parent.is_valid()) { - ensure_metadata_for_index(parent).open = true; - parent = parent.parent(); + bool opened_any = false; + auto& metadata_for_index = ensure_metadata_for_index(index); + if (!metadata_for_index.open) { + opened_any = true; + metadata_for_index.open = true; } + auto ancestor = index.parent(); + while (ancestor.is_valid()) { + auto& metadata_for_ancestor = ensure_metadata_for_index(ancestor); + if (!metadata_for_ancestor.open) { + metadata_for_ancestor.open = true; + opened_any = true; + } + ancestor = ancestor.parent(); + } + if (opened_any) + update_content_size(); +} + +void GTreeView::update_content_size() +{ + int height = 0; + int width = 0; + traverse_in_paint_order([&] (const GModelIndex&, const Rect& rect, const Rect&, int) { + width = max(width, rect.right()); + height += rect.height(); + return IterationDecision::Continue; + }); + set_content_size({ width, height }); } diff --git a/LibGUI/GTreeView.h b/LibGUI/GTreeView.h index 1dab5cb1bd..04462839f0 100644 --- a/LibGUI/GTreeView.h +++ b/LibGUI/GTreeView.h @@ -14,6 +14,7 @@ protected: virtual void paint_event(GPaintEvent&) override; virtual void mousedown_event(GMouseEvent&) override; virtual void did_update_selection() override; + virtual void did_update_model() override; private: GModelIndex index_at_content_position(const Point&, bool& is_toggle) const; @@ -24,6 +25,7 @@ private: int icon_spacing() const { return 2; } int toggle_size() const { return 9; } int text_padding() const { return 2; } + void update_content_size(); template<typename Callback> void traverse_in_paint_order(Callback) const; |