Blender  V3.3
interface_view.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
18 #include <memory>
19 #include <type_traits>
20 #include <variant>
21 
22 #include "DNA_screen_types.h"
23 
24 #include "BKE_screen.h"
25 
26 #include "BLI_listbase.h"
27 
28 #include "ED_screen.h"
29 
30 #include "interface_intern.h"
31 
32 #include "UI_interface.hh"
33 
34 #include "UI_abstract_view.hh"
35 #include "UI_grid_view.hh"
36 #include "UI_tree_view.hh"
37 
38 using namespace blender;
39 using namespace blender::ui;
40 
44 struct ViewLink : public Link {
45  std::string idname;
46  std::unique_ptr<AbstractView> view;
47 };
48 
49 template<class T>
51  StringRef idname,
52  std::unique_ptr<AbstractView> view)
53 {
54  ViewLink *view_link = MEM_new<ViewLink>(__func__);
55  BLI_addtail(&block.views, view_link);
56 
57  view_link->view = std::move(view);
58  view_link->idname = idname;
59 
60  return dynamic_cast<T *>(view_link->view.get());
61 }
62 
64  StringRef idname,
65  std::unique_ptr<AbstractGridView> grid_view)
66 {
67  return ui_block_add_view_impl<AbstractGridView>(block, idname, std::move(grid_view));
68 }
69 
71  StringRef idname,
72  std::unique_ptr<AbstractTreeView> tree_view)
73 {
74  return ui_block_add_view_impl<AbstractTreeView>(block, idname, std::move(tree_view));
75 }
76 
78 {
79  LISTBASE_FOREACH_MUTABLE (ViewLink *, link, &block->views) {
80  MEM_delete(link);
81  }
82 }
83 
84 void UI_block_views_listen(const uiBlock *block, const wmRegionListenerParams *listener_params)
85 {
86  ARegion *region = listener_params->region;
87 
88  LISTBASE_FOREACH (ViewLink *, view_link, &block->views) {
89  if (view_link->view->listen(*listener_params->notifier)) {
90  ED_region_tag_redraw(region);
91  }
92  }
93 }
94 
96 {
98  if (!item_but) {
99  return nullptr;
100  }
101 
102  return item_but->view_item;
103 }
104 
106 {
108  if (!item_but) {
109  return nullptr;
110  }
111 
112  return item_but->view_item;
113 }
114 
116 {
117  /* First get the idname the of the view we're looking for. */
118  LISTBASE_FOREACH (ViewLink *, view_link, &block.views) {
119  if (view_link->view.get() == &view) {
120  return view_link->idname;
121  }
122  }
123 
124  return {};
125 }
126 
127 template<class T>
129  const T &new_view)
130 {
131  uiBlock *old_block = new_block.oldblock;
132  if (!old_block) {
133  return nullptr;
134  }
135 
136  StringRef idname = ui_block_view_find_idname(new_block, new_view);
137  if (idname.is_empty()) {
138  return nullptr;
139  }
140 
141  LISTBASE_FOREACH (ViewLink *, old_view_link, &old_block->views) {
142  if (old_view_link->idname == idname) {
143  return dynamic_cast<T *>(old_view_link->view.get());
144  }
145  }
146 
147  return nullptr;
148 }
149 
151  const uiViewHandle *new_view_handle)
152 {
153  BLI_assert(new_block && new_view_handle);
154  const AbstractView &new_view = reinterpret_cast<const AbstractView &>(*new_view_handle);
155 
156  AbstractView *old_view = ui_block_view_find_matching_in_old_block_impl(*new_block, new_view);
157  return reinterpret_cast<uiViewHandle *>(old_view);
158 }
159 
161  const uiBlock *new_block, const uiViewItemHandle *new_item_handle)
162 {
163  uiBlock *old_block = new_block->oldblock;
164  if (!old_block) {
165  return nullptr;
166  }
167 
168  const AbstractViewItem &new_item = *reinterpret_cast<const AbstractViewItem *>(new_item_handle);
170  *new_block, new_item.get_view());
171  if (!old_view) {
172  return nullptr;
173  }
174 
175  LISTBASE_FOREACH (uiBut *, old_but, &old_block->buttons) {
176  if (old_but->type != UI_BTYPE_VIEW_ITEM) {
177  continue;
178  }
179  uiButViewItem *old_item_but = (uiButViewItem *)old_but;
180  if (!old_item_but->view_item) {
181  continue;
182  }
183  AbstractViewItem &old_item = *reinterpret_cast<AbstractViewItem *>(old_item_but->view_item);
184  /* Check if the item is from the expected view. */
185  if (&old_item.get_view() != old_view) {
186  continue;
187  }
188 
189  if (UI_view_item_matches(reinterpret_cast<const uiViewItemHandle *>(&new_item),
190  reinterpret_cast<const uiViewItemHandle *>(&old_item))) {
191  return old_item_but;
192  }
193  }
194 
195  return nullptr;
196 }
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:354
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:655
static AppView * view
struct uiViewHandle uiViewHandle
Definition: UI_interface.h:76
bool UI_view_item_matches(const uiViewItemHandle *a_handle, const uiViewItemHandle *b_handle)
struct uiViewItemHandle uiViewItemHandle
Definition: UI_interface.h:78
@ UI_BTYPE_VIEW_ITEM
Definition: UI_interface.h:393
constexpr bool is_empty() const
AbstractView & get_view() const
uiBut uiBut * ui_view_item_find_active(const struct ARegion *region)
uiBut * ui_view_item_find_mouse_over(const struct ARegion *region, const int xy[2]) ATTR_NONNULL(1
uiButViewItem * ui_block_view_find_matching_view_item_but_in_old_block(const uiBlock *new_block, const uiViewItemHandle *new_item_handle)
uiViewItemHandle * UI_region_views_find_active_item(const ARegion *region)
void ui_block_free_views(uiBlock *block)
static StringRef ui_block_view_find_idname(const uiBlock &block, const AbstractView &view)
uiViewItemHandle * UI_region_views_find_item_at(const ARegion *region, const int xy[2])
AbstractGridView * UI_block_add_view(uiBlock &block, StringRef idname, std::unique_ptr< AbstractGridView > grid_view)
static T * ui_block_add_view_impl(uiBlock &block, StringRef idname, std::unique_ptr< AbstractView > view)
uiViewHandle * ui_block_view_find_matching_in_old_block(const uiBlock *new_block, const uiViewHandle *new_view_handle)
void UI_block_views_listen(const uiBlock *block, const wmRegionListenerParams *listener_params)
static T * ui_block_view_find_matching_in_old_block_impl(const uiBlock &new_block, const T &new_view)
#define T
uiBlock * oldblock
ListBase buttons
ListBase views
uiViewItemHandle * view_item
struct wmNotifier * notifier
Definition: BKE_screen.h:127
struct ARegion * region
Definition: BKE_screen.h:126
int xy[2]
Definition: wm_draw.c:135