Blender V4.3
UI_tree_view.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12#pragma once
13
14#include <functional>
15#include <memory>
16#include <string>
17
18#include "BLI_function_ref.hh"
20#include "BLI_vector.hh"
21
22#include "UI_abstract_view.hh"
23#include "UI_resources.hh"
24
25struct bContext;
26struct uiBlock;
27struct uiLayout;
28
29namespace blender::ui {
30
31class AbstractTreeView;
32class AbstractTreeViewItem;
33class TreeViewItemDropTarget;
34
35/* ---------------------------------------------------------------------- */
50 friend class AbstractTreeView;
52
53 /* Private constructor, so only the friends above can create this! */
54 TreeViewItemContainer() = default;
55
56 protected:
62
63 public:
64 enum class IterOptions {
65 None = 0,
66 SkipCollapsed = 1 << 0,
67 SkipFiltered = 1 << 1,
68
69 /* Keep ENUM_OPERATORS() below updated! */
70 };
72
86 template<class ItemT, typename... Args> inline ItemT &add_tree_item(Args &&...args);
91 AbstractTreeViewItem &add_tree_item(std::unique_ptr<AbstractTreeViewItem> item);
92
93 protected:
95 void foreach_parent(ItemIterFn iter_fn) const;
96};
97
100
107
110/* ---------------------------------------------------------------------- */
115 /* Shared pointer so the pointer can be kept persistent over redraws. The grip button gets a
116 * pointer to modify the value on resizing, and it uses it to identify the button over redraws.*/
117 /* TODO support region zoom. */
118 std::shared_ptr<int> custom_height_ = nullptr;
119 std::shared_ptr<int> scroll_value_ = nullptr;
120
122 friend class TreeViewBuilder;
125
126 public:
127 /* virtual */ ~AbstractTreeView() override = default;
128
129 void draw_overlays(const ARegion &region, const uiBlock &block) const override;
130
132
133 void scroll(ViewScrollDirection direction) override;
134
138 AbstractTreeViewItem *find_hovered(const ARegion &region, const int2 &xy);
139
144 void set_default_rows(int default_rows);
145
146 protected:
147 virtual void build_tree() = 0;
148
149 private:
150 void foreach_view_item(FunctionRef<void(AbstractViewItem &)> iter_fn) const final;
151 void update_children_from_old(const AbstractView &old_view) override;
152 static void update_children_from_old_recursive(const TreeViewOrItem &new_items,
153 const TreeViewOrItem &old_items);
154 static AbstractTreeViewItem *find_matching_child(
155 const AbstractTreeViewItem &lookup_item, const Span<AbstractTreeViewItem *> possible_items);
156 std::optional<int> tot_visible_row_count() const;
157
158 bool supports_scrolling() const override;
159
160 void draw_hierarchy_lines(const ARegion &region, const uiBlock &block) const;
161 void get_hierarchy_lines(const ARegion &region,
162 const TreeViewOrItem &parent,
163 const float aspect,
164 Vector<std::pair<int2, int2>> &lines,
165 int &visible_item_index) const;
166
167 int count_visible_descendants(const AbstractTreeViewItem &parent) const;
168};
169
172/* ---------------------------------------------------------------------- */
184 friend class AbstractTreeView;
186 /* Higher-level API. */
188
189 private:
190 bool is_open_ = false;
191
192 protected:
194 std::string label_;
195
196 public:
197 /* virtual */ ~AbstractTreeViewItem() override = default;
198
199 virtual void build_row(uiLayout &row) = 0;
200
201 /* virtual */ std::optional<std::string> debug_name() const override;
202
203 std::unique_ptr<DropTargetInterface> create_item_drop_target() final;
204 virtual std::unique_ptr<TreeViewItemDropTarget> create_drop_target();
205
211 std::optional<rctf> get_win_rect(const ARegion &region) const;
212
214
221 bool toggle_collapsed();
228 virtual bool set_collapsed(bool collapsed);
236
241 bool is_collapsed() const;
242 bool is_collapsible() const;
243
244 int count_parents() const;
245
252 virtual void on_collapse_change(bContext &C, bool is_collapsed);
257 virtual std::optional<bool> should_be_collapsed() const;
258
259 protected:
261 /* virtual */ StringRef get_rename_string() const override;
263 /* virtual */ bool rename(const bContext &C, StringRefNull new_name) override;
264
269 virtual bool supports_collapsing() const;
270
275
277
279 /* virtual */ bool matches(const AbstractViewItem &other) const override;
280
282 /* virtual */ void update_from_old(const AbstractViewItem &old) override;
283
294 virtual bool matches_single(const AbstractTreeViewItem &other) const;
295
301 bool is_hovered() const;
302
304
305 private:
306 static void tree_row_click_fn(bContext *, void *, void *);
307 static void collapse_chevron_click_fn(bContext *, void *but_arg1, void *);
308
313 bool set_state_active() final;
314
315 void add_treerow_button(uiBlock &block);
316 int indent_width() const;
317 void add_indent(uiLayout &row) const;
318 void add_collapse_chevron(uiBlock &block) const;
319 void add_rename_button(uiLayout &row);
320
321 bool has_active_child() const;
322};
323
326/* ---------------------------------------------------------------------- */
336 public:
337 using IsActiveFn = std::function<bool()>;
338 using ActivateFn = std::function<void(bContext &C, BasicTreeViewItem &new_active)>;
340
341 explicit BasicTreeViewItem(StringRef label, BIFIconID icon = ICON_NONE);
342
343 void build_row(uiLayout &row) override;
344 void add_label(uiLayout &layout, StringRefNull label_override = "");
345 void set_on_activate_fn(ActivateFn fn);
349 void set_is_active_fn(IsActiveFn is_active_fn);
350
351 protected:
357
359
360 private:
361 static void tree_row_click_fn(bContext *C, void *arg1, void *arg2);
362
363 std::optional<bool> should_be_active() const override;
364 void on_activate(bContext &C) override;
365};
366
369/* ---------------------------------------------------------------------- */
383 protected:
386
387 public:
389 DropBehavior behavior = DropBehavior::Insert);
390
391 std::optional<DropLocation> choose_drop_location(const ARegion &region,
392 const wmEvent &event) const override;
393
396 template<class ViewType> inline ViewType &get_view() const;
397};
398
401/* ---------------------------------------------------------------------- */
406 public:
407 static void build_tree_view(AbstractTreeView &tree_view,
408 uiLayout &layout,
409 std::optional<StringRef> search_string = {},
410 bool add_box = true);
411
412 private:
413 static void ensure_min_rows_items(AbstractTreeView &tree_view);
414};
415
418/* ---------------------------------------------------------------------- */
419
420template<class ItemT, typename... Args>
421inline ItemT &TreeViewItemContainer::add_tree_item(Args &&...args)
422{
423 static_assert(std::is_base_of<AbstractTreeViewItem, ItemT>::value,
424 "Type must derive from and implement the AbstractTreeViewItem interface");
425
426 return dynamic_cast<ItemT &>(
427 add_tree_item(std::make_unique<ItemT>(std::forward<Args>(args)...)));
428}
429
430template<class ViewType> ViewType &TreeViewItemDropTarget::get_view() const
431{
432 static_assert(std::is_base_of<AbstractTreeView, ViewType>::value,
433 "Type must derive from and implement the ui::AbstractTreeView interface");
434 return dynamic_cast<ViewType &>(view_item_.get_tree_view());
435}
436
437} // namespace blender::ui
#define ENUM_OPERATORS(_type, _max)
int BIFIconID
Abstract base class for defining a customizable tree-view item.
std::optional< rctf > get_win_rect(const ARegion &region) const
Definition tree_view.cc:570
void update_from_old(const AbstractViewItem &old) override
Definition tree_view.cc:537
AbstractTreeView & get_tree_view() const
Definition tree_view.cc:565
std::unique_ptr< DropTargetInterface > create_item_drop_target() final
Definition tree_view.cc:550
StringRef get_rename_string() const override
Definition tree_view.cc:524
virtual void build_row(uiLayout &row)=0
bool matches(const AbstractViewItem &other) const override
Definition tree_view.cc:697
void toggle_collapsed_from_view(bContext &C)
Definition tree_view.cc:671
virtual std::unique_ptr< TreeViewItemDropTarget > create_drop_target()
Definition tree_view.cc:555
virtual void on_collapse_change(bContext &C, bool is_collapsed)
Definition tree_view.cc:661
~AbstractTreeViewItem() override=default
virtual std::optional< bool > should_be_collapsed() const
Definition tree_view.cc:666
virtual bool set_collapsed(bool collapsed)
Definition tree_view.cc:629
virtual bool matches_single(const AbstractTreeViewItem &other) const
Definition tree_view.cc:545
std::optional< std::string > debug_name() const override
Definition tree_view.cc:560
virtual bool supports_collapsing() const
Definition tree_view.cc:519
bool rename(const bContext &C, StringRefNull new_name) override
Definition tree_view.cc:529
AbstractTreeViewItem * find_hovered(const ARegion &region, const int2 &xy)
Definition tree_view.cc:110
void scroll(ViewScrollDirection direction) override
Definition tree_view.cc:332
void draw_overlays(const ARegion &region, const uiBlock &block) const override
Definition tree_view.cc:263
~AbstractTreeView() override=default
void foreach_item(ItemIterFn iter_fn, IterOptions options=IterOptions::None) const
Definition tree_view.cc:105
void set_default_rows(int default_rows)
Definition tree_view.cc:129
virtual void on_activate(bContext &C)
virtual std::optional< bool > should_be_active() const
std::function< bool()> IsActiveFn
std::function< void(bContext &C, BasicTreeViewItem &new_active)> ActivateFn
ItemT & add_tree_item(Args &&...args)
AbstractTreeViewItem * parent_
TreeViewItemContainer * root_
void foreach_item_recursive(ItemIterFn iter_fn, IterOptions options=IterOptions::None) const
Definition tree_view.cc:69
Vector< std::unique_ptr< AbstractTreeViewItem > > children_
void foreach_parent(ItemIterFn iter_fn) const
Definition tree_view.cc:89
AbstractTreeViewItem & view_item_
CCL_NAMESPACE_BEGIN struct Options options
const char * label
int xy[2]
Definition wm_draw.cc:170
bool override
Definition wm_files.cc:1167