diff options
Diffstat (limited to 'source')
19 files changed, 807 insertions, 862 deletions
diff --git a/source/blender/editors/include/UI_abstract_view.hh b/source/blender/editors/include/UI_abstract_view.hh index fdb7069e7c4..dfddace8899 100644 --- a/source/blender/editors/include/UI_abstract_view.hh +++ b/source/blender/editors/include/UI_abstract_view.hh @@ -3,11 +3,16 @@ /** \file * \ingroup editorui * - * Base for all views (UIs to display data sets), supporting common features. + * Base class for all views (UIs to display data sets) and view items, supporting common features. * https://wiki.blender.org/wiki/Source/Interface/Views * * One of the most important responsibilities of the base class is managing reconstruction, - * enabling state that is persistent over reconstructions/redraws. + * enabling state that is persistent over reconstructions/redraws. Other features: + * - Renaming + * - Custom context menus + * - Notifier listening + * - Drag controllers (dragging view items) + * - Drop controllers (dropping onto/into view items) */ #pragma once @@ -18,15 +23,25 @@ #include "DNA_defs.h" #include "BLI_span.hh" +#include "BLI_string_ref.hh" -struct wmNotifier; +struct bContext; struct uiBlock; +struct uiBut; +struct uiLayout; +struct uiViewItemHandle; +struct wmDrag; +struct wmNotifier; namespace blender::ui { class AbstractViewItem; +class AbstractViewItemDropController; +class AbstractViewItemDragController; class AbstractView { + friend class AbstractViewItem; + bool is_reconstructed_ = false; /** * Only one item can be renamed at a time. So rather than giving each item an own rename buffer @@ -43,6 +58,12 @@ class AbstractView { /** Listen to a notifier, returning true if a redraw is needed. */ virtual bool listen(const wmNotifier &) const; + /** + * Makes \a item valid for display in this view. Behavior is undefined for items not registered + * with this. + */ + void register_item(AbstractViewItem &item); + /** Only one item can be renamed at a time. */ bool is_renaming() const; /** \return If renaming was started successfully. */ @@ -63,7 +84,6 @@ class AbstractView { * After this, reconstruction is complete (see #is_reconstructed()). */ void update_from_old(uiBlock &new_block); - /** * Check if the view is fully (re-)constructed. That means, both the build function and * #update_from_old() have finished. @@ -72,16 +92,86 @@ class AbstractView { }; class AbstractViewItem { + friend class AbstractView; + friend class ViewItemAPIWrapper; + protected: + /** + * The view this item is a part of, and was registered for using #AbstractView::register_item(). + * If this wasn't done, the behavior of items is undefined. + */ + AbstractView *view_ = nullptr; bool is_active_ = false; + bool is_renaming_ = false; public: virtual ~AbstractViewItem() = default; + virtual void build_context_menu(bContext &C, uiLayout &column) const; + + /** + * Queries if the view item supports renaming in principle. Renaming may still fail, e.g. if + * another item is already being renamed. + */ + virtual bool supports_renaming() const; + /** + * Try renaming the item, or the data it represents. Can assume + * #AbstractViewItem::supports_renaming() returned true. Sub-classes that override this should + * usually call this, unless they have a custom #AbstractViewItem.matches() implementation. + * + * \return True if the renaming was successful. + */ + virtual bool rename(StringRefNull new_name); + /** + * Get the string that should be used for renaming, typically the item's label. This string will + * not be modified, but if the renaming is canceled, the value will be reset to this. + */ + virtual StringRef get_rename_string() const; + + /** + * If an item wants to support being dragged, it has to return a drag controller here. + * That is an object implementing #AbstractViewItemDragController. + */ + virtual std::unique_ptr<AbstractViewItemDragController> create_drag_controller() const; + /** + * If an item wants to support dropping data into it, it has to return a drop controller here. + * That is an object implementing #AbstractViewItemDropController. + * + * \note This drop controller may be requested for each event. The view doesn't keep a drop + * controller around currently. So it can not contain persistent state. + */ + virtual std::unique_ptr<AbstractViewItemDropController> create_drop_controller() const; + + /** Get the view this item is registered for using #AbstractView::register_item(). */ + AbstractView &get_view() const; + + /** + * Requires the view to have completed reconstruction, see #is_reconstructed(). Otherwise we + * can't be sure about the item state. + */ + bool is_active() const; + + bool is_renaming() const; + void begin_renaming(); + void end_renaming(); + void rename_apply(); + + template<typename ToType = AbstractViewItem> + static ToType *from_item_handle(uiViewItemHandle *handle); + protected: AbstractViewItem() = default; /** + * Compare this item's identity to \a other to check if they represent the same data. + * Implementations can assume that the types match already (caller must check). + * + * Used to recognize an item from a previous redraw, to be able to keep its state (e.g. active, + * renaming, etc.). + */ + virtual bool matches(const AbstractViewItem &other) const = 0; + + /** * Copy persistent state (e.g. active, selection, etc.) from a matching item of * the last redraw to this item. If sub-classes introduce more advanced state they should * override this and make it update their state accordingly. @@ -90,7 +180,101 @@ class AbstractViewItem { */ virtual void update_from_old(const AbstractViewItem &old); - void set_view(AbstractView &view); + /** + * Add a text button for renaming the item to \a block. This must be used for the built-in + * renaming to work. This button is meant to appear temporarily. It is removed when renaming is + * done. + */ + void add_rename_button(uiBlock &block); }; +template<typename ToType> ToType *AbstractViewItem::from_item_handle(uiViewItemHandle *handle) +{ + static_assert(std::is_base_of<AbstractViewItem, ToType>::value, + "Type must derive from and implement the AbstractViewItem interface"); + + return dynamic_cast<ToType *>(reinterpret_cast<AbstractViewItem *>(handle)); +} + +/* ---------------------------------------------------------------------- */ +/** \name Drag 'n Drop + * \{ */ + +/** + * Class to enable dragging a view item. An item can return a drop controller for itself by + * implementing #AbstractViewItem::create_drag_controller(). + */ +class AbstractViewItemDragController { + protected: + AbstractView &view_; + + public: + AbstractViewItemDragController(AbstractView &view); + virtual ~AbstractViewItemDragController() = default; + + virtual int get_drag_type() const = 0; + virtual void *create_drag_data() const = 0; + virtual void on_drag_start(); + + /** Request the view the item is registered for as type #ViewType. Throws a `std::bad_cast` + * exception if the view is not of the requested type. */ + template<class ViewType> inline ViewType &get_view() const; +}; + +/** + * Class to define the behavior when dropping something onto/into a view item, plus the behavior + * when dragging over this item. An item can return a drop controller for itself via a custom + * implementation of #AbstractViewItem::create_drop_controller(). + */ +class AbstractViewItemDropController { + protected: + AbstractView &view_; + + public: + AbstractViewItemDropController(AbstractView &view); + virtual ~AbstractViewItemDropController() = default; + + /** + * Check if the data dragged with \a drag can be dropped on the item this controller is for. + * \param r_disabled_hint: Return a static string to display to the user, explaining why dropping + * isn't possible on this item. Shouldn't be done too aggressively, e.g. + * don't set this if the drag-type can't be dropped here; only if it can + * but there's another reason it can't be dropped. + * Can assume this is a non-null pointer. + */ + virtual bool can_drop(const wmDrag &drag, const char **r_disabled_hint) const = 0; + /** + * Custom text to display when dragging over a view item. Should explain what happens when + * dropping the data onto this item. Will only be used if #AbstractViewItem::can_drop() + * returns true, so the implementing override doesn't have to check that again. + * The returned value must be a translated string. + */ + virtual std::string drop_tooltip(const wmDrag &drag) const = 0; + /** + * Execute the logic to apply a drop of the data dragged with \a drag onto/into the item this + * controller is for. + */ + virtual bool on_drop(struct bContext *C, const wmDrag &drag) = 0; + + /** Request the view the item is registered for as type #ViewType. Throws a `std::bad_cast` + * exception if the view is not of the requested type. */ + template<class ViewType> inline ViewType &get_view() const; +}; + +template<class ViewType> ViewType &AbstractViewItemDragController::get_view() const +{ + static_assert(std::is_base_of<AbstractView, ViewType>::value, + "Type must derive from and implement the ui::AbstractView interface"); + return dynamic_cast<ViewType &>(view_); +} + +template<class ViewType> ViewType &AbstractViewItemDropController::get_view() const +{ + static_assert(std::is_base_of<AbstractView, ViewType>::value, + "Type must derive from and implement the ui::AbstractView interface"); + return dynamic_cast<ViewType &>(view_); +} + +/** \} */ + } // namespace blender::ui diff --git a/source/blender/editors/include/UI_grid_view.hh b/source/blender/editors/include/UI_grid_view.hh index 74ce16ccd85..805198f38ef 100644 --- a/source/blender/editors/include/UI_grid_view.hh +++ b/source/blender/editors/include/UI_grid_view.hh @@ -19,7 +19,7 @@ struct bContext; struct PreviewImage; struct uiBlock; -struct uiButGridTile; +struct uiButViewItem; struct uiLayout; struct View2D; struct wmNotifier; @@ -41,32 +41,22 @@ class AbstractGridViewItem : public AbstractViewItem { protected: /** Reference to a string that uniquely identifies this item in the view. */ StringRef identifier_{}; - /** Every visible item gets a button of type #UI_BTYPE_GRID_TILE during the layout building. */ - uiButGridTile *grid_tile_but_ = nullptr; + /** Every visible item gets a button of type #UI_BTYPE_VIEW_ITEM during the layout building. */ + uiButViewItem *view_item_but_ = nullptr; public: virtual ~AbstractGridViewItem() = default; virtual void build_grid_tile(uiLayout &layout) const = 0; - /** - * Compare this item's identifier to \a other to check if they represent the same data. - * Used to recognize an item from a previous redraw, to be able to keep its state (e.g. active, - * renaming, etc.). - */ - bool matches(const AbstractGridViewItem &other) const; - const AbstractGridView &get_view() const; - /** - * Requires the tree to have completed reconstruction, see #is_reconstructed(). Otherwise we - * can't be sure about the item state. - */ - bool is_active() const; - protected: AbstractGridViewItem(StringRef identifier); + /** See AbstractViewItem::matches(). */ + virtual bool matches(const AbstractViewItem &other) const override; + /** Called when the item's state changes from inactive to active. */ virtual void on_activate(); /** diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index f39c62d8e2b..99a1d038cca 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -74,10 +74,8 @@ typedef struct uiLayout uiLayout; typedef struct uiPopupBlockHandle uiPopupBlockHandle; /* C handle for C++ #ui::AbstractView type. */ typedef struct uiViewHandle uiViewHandle; -/* C handle for C++ #ui::AbstractTreeViewItem type. */ -typedef struct uiTreeViewItemHandle uiTreeViewItemHandle; -/* C handle for C++ #ui::AbstractGridViewItem type. */ -typedef struct uiGridViewItemHandle uiGridViewItemHandle; +/* C handle for C++ #ui::AbstractViewItem type. */ +typedef struct uiViewItemHandle uiViewItemHandle; /* Defines */ @@ -391,10 +389,8 @@ typedef enum { /** Resize handle (resize uilist). */ UI_BTYPE_GRIP = 57 << 9, UI_BTYPE_DECORATOR = 58 << 9, - /* An item in a tree view. Parent items may be collapsible. */ - UI_BTYPE_TREEROW = 59 << 9, - /* An item in a grid view. */ - UI_BTYPE_GRID_TILE = 60 << 9, + /* An item a view (see #ui::AbstractViewItem). */ + UI_BTYPE_VIEW_ITEM = 59 << 9, } eButType; #define BUTTYPE (63 << 9) @@ -1685,8 +1681,6 @@ int UI_search_items_find_index(uiSearchItems *items, const char *name); */ void UI_but_hint_drawstr_set(uiBut *but, const char *string); -void UI_but_treerow_indentation_set(uiBut *but, int indentation); - void UI_but_node_link_set(uiBut *but, struct bNodeSocket *socket, const float draw_color[4]); void UI_but_number_step_size_set(uiBut *but, float step_size); @@ -3201,45 +3195,44 @@ void UI_interface_tag_script_reload(void); void UI_block_views_listen(const uiBlock *block, const struct wmRegionListenerParams *listener_params); -bool UI_grid_view_item_is_active(const uiGridViewItemHandle *item_handle); -bool UI_tree_view_item_is_active(const uiTreeViewItemHandle *item); -bool UI_grid_view_item_matches(const uiGridViewItemHandle *a, const uiGridViewItemHandle *b); -bool UI_tree_view_item_matches(const uiTreeViewItemHandle *a, const uiTreeViewItemHandle *b); +bool UI_view_item_is_active(const uiViewItemHandle *item_handle); +bool UI_view_item_matches(const uiViewItemHandle *a_handle, const uiViewItemHandle *b_handle); /** - * Attempt to start dragging the tree-item \a item_. This will not work if the tree item doesn't - * support dragging, i.e. it won't create a drag-controller upon request. - * \return True if dragging started successfully, otherwise false. + * Can \a item_handle be renamed right now? Note that this isn't just a mere wrapper around + * #AbstractViewItem::supports_renaming(). This also checks if there is another item being renamed, + * and returns false if so. */ -bool UI_tree_view_item_drag_start(struct bContext *C, uiTreeViewItemHandle *item_); -bool UI_tree_view_item_can_drop(const uiTreeViewItemHandle *item_, - const struct wmDrag *drag, - const char **r_disabled_hint); -char *UI_tree_view_item_drop_tooltip(const uiTreeViewItemHandle *item, const struct wmDrag *drag); +bool UI_view_item_can_rename(const uiViewItemHandle *item_handle); +void UI_view_item_begin_rename(uiViewItemHandle *item_handle); + +void UI_view_item_context_menu_build(struct bContext *C, + const uiViewItemHandle *item_handle, + uiLayout *column); + /** - * Let a tree-view item handle a drop event. - * \return True if the drop was handled by the tree-view item. + * Attempt to start dragging \a item_. This will not work if the view item doesn't + * support dragging, i.e. if it won't create a drag-controller upon request. + * \return True if dragging started successfully, otherwise false. */ -bool UI_tree_view_item_drop_handle(struct bContext *C, - const uiTreeViewItemHandle *item_, - const struct ListBase *drags); +bool UI_view_item_drag_start(struct bContext *C, const uiViewItemHandle *item_); +bool UI_view_item_can_drop(const uiViewItemHandle *item_, + const struct wmDrag *drag, + const char **r_disabled_hint); +char *UI_view_item_drop_tooltip(const uiViewItemHandle *item, const struct wmDrag *drag); /** - * Can \a item_handle be renamed right now? Not that this isn't just a mere wrapper around - * #AbstractTreeViewItem::can_rename(). This also checks if there is another item being renamed, - * and returns false if so. + * Let a view item handle a drop event. + * \return True if the drop was handled by the view item. */ -bool UI_tree_view_item_can_rename(const uiTreeViewItemHandle *item_handle); -void UI_tree_view_item_begin_rename(uiTreeViewItemHandle *item_handle); - -void UI_tree_view_item_context_menu_build(struct bContext *C, - const uiTreeViewItemHandle *item, - uiLayout *column); +bool UI_view_item_drop_handle(struct bContext *C, + const uiViewItemHandle *item_, + const struct ListBase *drags); /** - * \param xy: Coordinate to find a tree-row item at, in window space. + * \param xy: Coordinate to find a view item at, in window space. */ -uiTreeViewItemHandle *UI_block_tree_view_find_item_at(const struct ARegion *region, - const int xy[2]) ATTR_NONNULL(1, 2); -uiTreeViewItemHandle *UI_block_tree_view_find_active_item(const struct ARegion *region); +uiViewItemHandle *UI_block_view_find_item_at(const struct ARegion *region, const int xy[2]) + ATTR_NONNULL(); +uiViewItemHandle *UI_block_view_find_active_item(const struct ARegion *region); #ifdef __cplusplus } diff --git a/source/blender/editors/include/UI_tree_view.hh b/source/blender/editors/include/UI_tree_view.hh index fa427d96dd8..872a6085060 100644 --- a/source/blender/editors/include/UI_tree_view.hh +++ b/source/blender/editors/include/UI_tree_view.hh @@ -9,7 +9,6 @@ #pragma once -#include <array> #include <functional> #include <memory> #include <string> @@ -25,18 +24,13 @@ struct bContext; struct uiBlock; struct uiBut; -struct uiButTreeRow; +struct uiButViewItem; struct uiLayout; -struct wmDrag; -struct wmEvent; -struct wmNotifier; namespace blender::ui { class AbstractTreeView; class AbstractTreeViewItem; -class AbstractTreeViewItemDropController; -class AbstractTreeViewItemDragController; /* ---------------------------------------------------------------------- */ /** \name Tree-View Item Container @@ -161,19 +155,17 @@ class AbstractTreeViewItem : public AbstractViewItem, public TreeViewItemContain private: bool is_open_ = false; - bool is_renaming_ = false; protected: /** This label is used as the default way to identifying an item within its parent. */ std::string label_{}; - /** Every visible item gets a button of type #UI_BTYPE_TREEROW during the layout building. */ - uiButTreeRow *tree_row_but_ = nullptr; + /** Every visible item gets a button of type #UI_BTYPE_VIEW_ITEM during the layout building. */ + uiButViewItem *view_item_but_ = nullptr; public: virtual ~AbstractTreeViewItem() = default; virtual void build_row(uiLayout &row) = 0; - virtual void build_context_menu(bContext &C, uiLayout &column) const; AbstractTreeView &get_tree_view() const; @@ -185,11 +177,6 @@ class AbstractTreeViewItem : public AbstractViewItem, public TreeViewItemContain * can't be sure about the item state. */ bool is_collapsed() const; - /** - * Requires the tree to have completed reconstruction, see #is_reconstructed(). Otherwise we - * can't be sure about the item state. - */ - bool is_active() const; protected: /** @@ -202,25 +189,19 @@ class AbstractTreeViewItem : public AbstractViewItem, public TreeViewItemContain */ virtual std::optional<bool> should_be_active() const; - /** - * Queries if the tree-view item supports renaming in principle. Renaming may still fail, e.g. if - * another item is already being renamed. - */ - virtual bool supports_renaming() const; - /** - * Try renaming the item, or the data it represents. Can assume - * #AbstractTreeViewItem::supports_renaming() returned true. Sub-classes that override this - * should usually call this, unless they have a custom #AbstractTreeViewItem.matches(). - * - * \return True if the renaming was successful. - */ - virtual bool rename(StringRefNull new_name); + /** See AbstractViewItem::get_rename_string(). */ + virtual StringRef get_rename_string() const override; + /** See AbstractViewItem::rename(). */ + virtual bool rename(StringRefNull new_name) override; /** * Return whether the item can be collapsed. Used to disable collapsing for items with children. */ virtual bool supports_collapsing() const; + /** See #AbstractViewItem::matches(). */ + virtual bool matches(const AbstractViewItem &other) const override; + /** See #AbstractViewItem::update_from_old(). */ virtual void update_from_old(const AbstractViewItem &old) override; @@ -230,22 +211,11 @@ class AbstractTreeViewItem : public AbstractViewItem, public TreeViewItemContain * open/closed, active, etc.). Items are only matched if their parents also match. * By default this just matches the item's label (if the parents match!). If that isn't * good enough for a sub-class, that can override it. - */ - virtual bool matches(const AbstractTreeViewItem &other) const; - - /** - * If an item wants to support being dragged, it has to return a drag controller here. - * That is an object implementing #AbstractTreeViewItemDragController. - */ - virtual std::unique_ptr<AbstractTreeViewItemDragController> create_drag_controller() const; - /** - * If an item wants to support dropping data into it, it has to return a drop controller here. - * That is an object implementing #AbstractTreeViewItemDropController. * - * \note This drop controller may be requested for each event. The tree-view doesn't keep a drop - * controller around currently. So it can not contain persistent state. + * TODO #matches_single() is a rather temporary name, used to indicate that this only compares + * the item itself, not the parents. Item matching is expected to change quite a bit anyway. */ - virtual std::unique_ptr<AbstractTreeViewItemDropController> create_drop_controller() const; + virtual bool matches_single(const AbstractTreeViewItem &other) const; /** * Activates this item, deactivates other items, calls the #AbstractTreeViewItem::on_activate() @@ -263,29 +233,24 @@ class AbstractTreeViewItem : public AbstractViewItem, public TreeViewItemContain */ bool is_hovered() const; bool is_collapsible() const; - bool is_renaming() const; void ensure_parents_uncollapsed(); - uiButTreeRow *tree_row_button(); + uiButViewItem *view_item_button(); private: - static void rename_button_fn(bContext *, void *, char *); - static AbstractTreeViewItem *find_tree_item_from_rename_button(const uiBut &but); static void tree_row_click_fn(struct bContext *, void *, void *); static void collapse_chevron_click_fn(bContext *, void *but_arg1, void *); static bool is_collapse_chevron_but(const uiBut *but); /** See #AbstractTreeView::change_state_delayed() */ void change_state_delayed(); - void end_renaming(); void add_treerow_button(uiBlock &block); void add_indent(uiLayout &row) const; void add_collapse_chevron(uiBlock &block) const; void add_rename_button(uiLayout &row); - bool matches_including_parents(const AbstractTreeViewItem &other) const; bool has_active_child() const; int count_parents() const; }; @@ -293,69 +258,6 @@ class AbstractTreeViewItem : public AbstractViewItem, public TreeViewItemContain /** \} */ /* ---------------------------------------------------------------------- */ -/** \name Drag 'n Drop - * \{ */ - -/** - * Class to enable dragging a tree-item. An item can return a drop controller for itself via a - * custom implementation of #AbstractTreeViewItem::create_drag_controller(). - */ -class AbstractTreeViewItemDragController { - protected: - AbstractTreeView &tree_view_; - - public: - AbstractTreeViewItemDragController(AbstractTreeView &tree_view); - virtual ~AbstractTreeViewItemDragController() = default; - - virtual int get_drag_type() const = 0; - virtual void *create_drag_data() const = 0; - virtual void on_drag_start(); - - template<class TreeViewType> inline TreeViewType &tree_view() const; -}; - -/** - * Class to customize the drop behavior of a tree-item, plus the behavior when dragging over this - * item. An item can return a drop controller for itself via a custom implementation of - * #AbstractTreeViewItem::create_drop_controller(). - */ -class AbstractTreeViewItemDropController { - protected: - AbstractTreeView &tree_view_; - - public: - AbstractTreeViewItemDropController(AbstractTreeView &tree_view); - virtual ~AbstractTreeViewItemDropController() = default; - - /** - * Check if the data dragged with \a drag can be dropped on the item this controller is for. - * \param r_disabled_hint: Return a static string to display to the user, explaining why dropping - * isn't possible on this item. Shouldn't be done too aggressively, e.g. - * don't set this if the drag-type can't be dropped here; only if it can - * but there's another reason it can't be dropped. - * Can assume this is a non-null pointer. - */ - virtual bool can_drop(const wmDrag &drag, const char **r_disabled_hint) const = 0; - /** - * Custom text to display when dragging over a tree item. Should explain what happens when - * dropping the data onto this item. Will only be used if #AbstractTreeViewItem::can_drop() - * returns true, so the implementing override doesn't have to check that again. - * The returned value must be a translated string. - */ - virtual std::string drop_tooltip(const wmDrag &drag) const = 0; - /** - * Execute the logic to apply a drop of the data dragged with \a drag onto/into the item this - * controller is for. - */ - virtual bool on_drop(struct bContext *C, const wmDrag &drag) = 0; - - template<class TreeViewType> inline TreeViewType &tree_view() const; -}; - -/** \} */ - -/* ---------------------------------------------------------------------- */ /** \name Predefined Tree-View Item Types * * Common, Basic Tree-View Item Types. @@ -426,18 +328,4 @@ inline ItemT &TreeViewItemContainer::add_tree_item(Args &&...args) add_tree_item(std::make_unique<ItemT>(std::forward<Args>(args)...))); } -template<class TreeViewType> TreeViewType &AbstractTreeViewItemDragController::tree_view() const -{ - static_assert(std::is_base_of<AbstractTreeView, TreeViewType>::value, - "Type must derive from and implement the AbstractTreeView interface"); - return static_cast<TreeViewType &>(tree_view_); -} - -template<class TreeViewType> TreeViewType &AbstractTreeViewItemDropController::tree_view() const -{ - static_assert(std::is_base_of<AbstractTreeView, TreeViewType>::value, - "Type must derive from and implement the AbstractTreeView interface"); - return static_cast<TreeViewType &>(tree_view_); -} - } // namespace blender::ui diff --git a/source/blender/editors/interface/abstract_view.cc b/source/blender/editors/interface/abstract_view.cc index dea9600fde4..077c76a08f1 100644 --- a/source/blender/editors/interface/abstract_view.cc +++ b/source/blender/editors/interface/abstract_view.cc @@ -10,6 +10,13 @@ namespace blender::ui { +void AbstractView::register_item(AbstractViewItem &item) +{ + /* Actually modifies the item, not the view. But for the public API it "feels" a bit nicer to + * have the view base class register the items, rather than setting the view on the item. */ + item.view_ = this; +} + /* ---------------------------------------------------------------------- */ /** \name View Reconstruction * \{ */ diff --git a/source/blender/editors/interface/abstract_view_item.cc b/source/blender/editors/interface/abstract_view_item.cc index fc71dbe8b95..f73183d07e9 100644 --- a/source/blender/editors/interface/abstract_view_item.cc +++ b/source/blender/editors/interface/abstract_view_item.cc @@ -4,6 +4,16 @@ * \ingroup edinterface */ +#include "BKE_context.h" + +#include "BLI_listbase.h" +#include "BLI_string.h" + +#include "WM_api.h" + +#include "UI_interface.h" +#include "interface_intern.h" + #include "UI_abstract_view.hh" namespace blender::ui { @@ -15,8 +25,349 @@ namespace blender::ui { void AbstractViewItem::update_from_old(const AbstractViewItem &old) { is_active_ = old.is_active_; + is_renaming_ = old.is_renaming_; +} + +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Renaming + * \{ */ + +bool AbstractViewItem::supports_renaming() const +{ + /* No renaming by default. */ + return false; +} +bool AbstractViewItem::rename(StringRefNull /*new_name*/) +{ + /* No renaming by default. */ + return false; +} + +StringRef AbstractViewItem::get_rename_string() const +{ + /* No rename string by default. */ + return {}; +} + +bool AbstractViewItem::is_renaming() const +{ + return is_renaming_; +} + +void AbstractViewItem::begin_renaming() +{ + AbstractView &view = get_view(); + if (view.is_renaming() || !supports_renaming()) { + return; + } + + if (view.begin_renaming()) { + is_renaming_ = true; + } + + StringRef initial_str = get_rename_string(); + std::copy(std::begin(initial_str), std::end(initial_str), std::begin(view.get_rename_buffer())); +} + +void AbstractViewItem::rename_apply() +{ + const AbstractView &view = get_view(); + rename(view.get_rename_buffer().data()); + end_renaming(); +} + +void AbstractViewItem::end_renaming() +{ + if (!is_renaming()) { + return; + } + + is_renaming_ = false; + + AbstractView &view = get_view(); + view.end_renaming(); +} + +static AbstractViewItem *find_item_from_rename_button(const uiBut &rename_but) +{ + /* A minimal sanity check, can't do much more here. */ + BLI_assert(rename_but.type == UI_BTYPE_TEXT && rename_but.poin); + + LISTBASE_FOREACH (uiBut *, but, &rename_but.block->buttons) { + if (but->type != UI_BTYPE_VIEW_ITEM) { + continue; + } + + uiButViewItem *view_item_but = (uiButViewItem *)but; + AbstractViewItem *item = reinterpret_cast<AbstractViewItem *>(view_item_but->view_item); + const AbstractView &view = item->get_view(); + + if (item->is_renaming() && (view.get_rename_buffer().data() == rename_but.poin)) { + return item; + } + } + + return nullptr; +} + +static void rename_button_fn(bContext *UNUSED(C), void *arg, char *UNUSED(origstr)) +{ + const uiBut *rename_but = static_cast<uiBut *>(arg); + AbstractViewItem *item = find_item_from_rename_button(*rename_but); + BLI_assert(item); + item->rename_apply(); +} + +void AbstractViewItem::add_rename_button(uiBlock &block) +{ + AbstractView &view = get_view(); + uiBut *rename_but = uiDefBut(&block, + UI_BTYPE_TEXT, + 1, + "", + 0, + 0, + UI_UNIT_X * 10, + UI_UNIT_Y, + view.get_rename_buffer().data(), + 1.0f, + view.get_rename_buffer().size(), + 0, + 0, + ""); + + /* Gotta be careful with what's passed to the `arg1` here. Any view data will be freed once the + * callback is executed. */ + UI_but_func_rename_set(rename_but, rename_button_fn, rename_but); + UI_but_flag_disable(rename_but, UI_BUT_UNDO); + + const bContext *evil_C = reinterpret_cast<bContext *>(block.evil_C); + ARegion *region = CTX_wm_region(evil_C); + /* Returns false if the button was removed. */ + if (UI_but_active_only(evil_C, region, &block, rename_but) == false) { + end_renaming(); + } +} + +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Context Menu + * \{ */ + +void AbstractViewItem::build_context_menu(bContext & /*C*/, uiLayout & /*column*/) const +{ + /* No context menu by default. */ +} + +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Drag 'n Drop + * \{ */ + +std::unique_ptr<AbstractViewItemDragController> AbstractViewItem::create_drag_controller() const +{ + /* There's no drag controller (and hence no drag support) by default. */ + return nullptr; +} + +std::unique_ptr<AbstractViewItemDropController> AbstractViewItem::create_drop_controller() const +{ + /* There's no drop controller (and hence no drop support) by default. */ + return nullptr; +} + +AbstractViewItemDragController::AbstractViewItemDragController(AbstractView &view) : view_(view) +{ +} + +void AbstractViewItemDragController::on_drag_start() +{ + /* Do nothing by default. */ +} + +AbstractViewItemDropController::AbstractViewItemDropController(AbstractView &view) : view_(view) +{ +} + +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name General Getters & Setters + * \{ */ + +AbstractView &AbstractViewItem::get_view() const +{ + if (UNLIKELY(!view_)) { + throw std::runtime_error( + "Invalid state, item must be registered through AbstractView::register_item()"); + } + return *view_; +} + +bool AbstractViewItem::is_active() const +{ + BLI_assert_msg(get_view().is_reconstructed(), + "State can't be queried until reconstruction is completed"); + return is_active_; } /** \} */ } // namespace blender::ui + +/* ---------------------------------------------------------------------- */ +/** \name C-API + * \{ */ + +namespace blender::ui { + +/** + * Helper class to provide a higher level public (C-)API. Has access to private/protected view item + * members and ensures some invariants that way. + */ +class ViewItemAPIWrapper { + public: + static bool matches(const AbstractViewItem &a, const AbstractViewItem &b) + { + if (typeid(a) != typeid(b)) { + return false; + } + /* TODO should match the view as well. */ + return a.matches(b); + } + + static bool can_rename(const AbstractViewItem &item) + { + const AbstractView &view = item.get_view(); + return !view.is_renaming() && item.supports_renaming(); + } + + static bool drag_start(bContext &C, const AbstractViewItem &item) + { + const std::unique_ptr<AbstractViewItemDragController> drag_controller = + item.create_drag_controller(); + if (!drag_controller) { + return false; + } + + WM_event_start_drag(&C, + ICON_NONE, + drag_controller->get_drag_type(), + drag_controller->create_drag_data(), + 0, + WM_DRAG_FREE_DATA); + drag_controller->on_drag_start(); + + return true; + } + + static bool can_drop(const AbstractViewItem &item, + const wmDrag &drag, + const char **r_disabled_hint) + { + const std::unique_ptr<AbstractViewItemDropController> drop_controller = + item.create_drop_controller(); + if (!drop_controller) { + return false; + } + + return drop_controller->can_drop(drag, r_disabled_hint); + } + + static std::string drop_tooltip(const AbstractViewItem &item, const wmDrag &drag) + { + const std::unique_ptr<AbstractViewItemDropController> drop_controller = + item.create_drop_controller(); + if (!drop_controller) { + return {}; + } + + return drop_controller->drop_tooltip(drag); + } + + static bool drop_handle(bContext &C, const AbstractViewItem &item, const ListBase &drags) + { + std::unique_ptr<AbstractViewItemDropController> drop_controller = + item.create_drop_controller(); + + const char *disabled_hint_dummy = nullptr; + LISTBASE_FOREACH (const wmDrag *, drag, &drags) { + if (drop_controller->can_drop(*drag, &disabled_hint_dummy)) { + return drop_controller->on_drop(&C, *drag); + } + } + + return false; + } +}; + +} // namespace blender::ui + +using namespace blender::ui; + +bool UI_view_item_is_active(const uiViewItemHandle *item_handle) +{ + const AbstractViewItem &item = reinterpret_cast<const AbstractViewItem &>(*item_handle); + return item.is_active(); +} + +bool UI_view_item_matches(const uiViewItemHandle *a_handle, const uiViewItemHandle *b_handle) +{ + const AbstractViewItem &a = reinterpret_cast<const AbstractViewItem &>(*a_handle); + const AbstractViewItem &b = reinterpret_cast<const AbstractViewItem &>(*b_handle); + return ViewItemAPIWrapper::matches(a, b); +} + +bool UI_view_item_can_rename(const uiViewItemHandle *item_handle) +{ + const AbstractViewItem &item = reinterpret_cast<const AbstractViewItem &>(*item_handle); + return ViewItemAPIWrapper::can_rename(item); +} + +void UI_view_item_begin_rename(uiViewItemHandle *item_handle) +{ + AbstractViewItem &item = reinterpret_cast<AbstractViewItem &>(*item_handle); + item.begin_renaming(); +} + +void UI_view_item_context_menu_build(bContext *C, + const uiViewItemHandle *item_handle, + uiLayout *column) +{ + const AbstractViewItem &item = reinterpret_cast<const AbstractViewItem &>(*item_handle); + item.build_context_menu(*C, *column); +} + +bool UI_view_item_drag_start(bContext *C, const uiViewItemHandle *item_) +{ + const AbstractViewItem &item = reinterpret_cast<const AbstractViewItem &>(*item_); + return ViewItemAPIWrapper::drag_start(*C, item); +} + +bool UI_view_item_can_drop(const uiViewItemHandle *item_, + const wmDrag *drag, + const char **r_disabled_hint) +{ + const AbstractViewItem &item = reinterpret_cast<const AbstractViewItem &>(*item_); + return ViewItemAPIWrapper::can_drop(item, *drag, r_disabled_hint); +} + +char *UI_view_item_drop_tooltip(const uiViewItemHandle *item_, const wmDrag *drag) +{ + const AbstractViewItem &item = reinterpret_cast<const AbstractViewItem &>(*item_); + + const std::string tooltip = ViewItemAPIWrapper::drop_tooltip(item, *drag); + return tooltip.empty() ? nullptr : BLI_strdup(tooltip.c_str()); +} + +bool UI_view_item_drop_handle(bContext *C, const uiViewItemHandle *item_, const ListBase *drags) +{ + const AbstractViewItem &item = reinterpret_cast<const AbstractViewItem &>(*item_); + return ViewItemAPIWrapper::drop_handle(*C, item, *drags); +} + +/** \} */ diff --git a/source/blender/editors/interface/grid_view.cc b/source/blender/editors/interface/grid_view.cc index 362642b0846..37fbb33f83b 100644 --- a/source/blender/editors/interface/grid_view.cc +++ b/source/blender/editors/interface/grid_view.cc @@ -95,18 +95,19 @@ AbstractGridViewItem::AbstractGridViewItem(StringRef identifier) : identifier_(i { } -bool AbstractGridViewItem::matches(const AbstractGridViewItem &other) const +bool AbstractGridViewItem::matches(const AbstractViewItem &other) const { - return identifier_ == other.identifier_; + const AbstractGridViewItem &other_grid_item = dynamic_cast<const AbstractGridViewItem &>(other); + return identifier_ == other_grid_item.identifier_; } void AbstractGridViewItem::grid_tile_click_fn(struct bContext * /*C*/, void *but_arg1, void * /*arg2*/) { - uiButGridTile *grid_tile_but = (uiButGridTile *)but_arg1; + uiButViewItem *view_item_but = (uiButViewItem *)but_arg1; AbstractGridViewItem &grid_item = reinterpret_cast<AbstractGridViewItem &>( - *grid_tile_but->view_item); + *view_item_but->view_item); grid_item.activate(); } @@ -114,8 +115,8 @@ void AbstractGridViewItem::grid_tile_click_fn(struct bContext * /*C*/, void AbstractGridViewItem::add_grid_tile_button(uiBlock &block) { const GridViewStyle &style = get_view().get_style(); - grid_tile_but_ = (uiButGridTile *)uiDefBut(&block, - UI_BTYPE_GRID_TILE, + view_item_but_ = (uiButViewItem *)uiDefBut(&block, + UI_BTYPE_VIEW_ITEM, 0, "", 0, @@ -129,15 +130,8 @@ void AbstractGridViewItem::add_grid_tile_button(uiBlock &block) 0, ""); - grid_tile_but_->view_item = reinterpret_cast<uiGridViewItemHandle *>(this); - UI_but_func_set(&grid_tile_but_->but, grid_tile_click_fn, grid_tile_but_, nullptr); -} - -bool AbstractGridViewItem::is_active() const -{ - BLI_assert_msg(get_view().is_reconstructed(), - "State can't be queried until reconstruction is completed"); - return is_active_; + view_item_but_->view_item = reinterpret_cast<uiViewItemHandle *>(this); + UI_but_func_set(&view_item_but_->but, grid_tile_click_fn, view_item_but_, nullptr); } void AbstractGridViewItem::on_activate() @@ -468,24 +462,3 @@ std::optional<bool> PreviewGridItem::should_be_active() const } } // namespace blender::ui - -using namespace blender::ui; - -/* ---------------------------------------------------------------------- */ -/* C-API */ - -using namespace blender::ui; - -bool UI_grid_view_item_is_active(const uiGridViewItemHandle *item_handle) -{ - const AbstractGridViewItem &item = reinterpret_cast<const AbstractGridViewItem &>(*item_handle); - return item.is_active(); -} - -bool UI_grid_view_item_matches(const uiGridViewItemHandle *a_handle, - const uiGridViewItemHandle *b_handle) -{ - const AbstractGridViewItem &a = reinterpret_cast<const AbstractGridViewItem &>(*a_handle); - const AbstractGridViewItem &b = reinterpret_cast<const AbstractGridViewItem &>(*b_handle); - return a.matches(b); -} diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index c0df193de87..2f9e69137ed 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -769,20 +769,11 @@ static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut) return false; } - if ((but->type == UI_BTYPE_TREEROW) && (oldbut->type == UI_BTYPE_TREEROW)) { - uiButTreeRow *but_treerow = (uiButTreeRow *)but; - uiButTreeRow *oldbut_treerow = (uiButTreeRow *)oldbut; - if (!but_treerow->tree_item || !oldbut_treerow->tree_item || - !UI_tree_view_item_matches(but_treerow->tree_item, oldbut_treerow->tree_item)) { - return false; - } - } - - if ((but->type == UI_BTYPE_GRID_TILE) && (oldbut->type == UI_BTYPE_GRID_TILE)) { - uiButGridTile *but_gridtile = (uiButGridTile *)but; - uiButGridTile *oldbut_gridtile = (uiButGridTile *)oldbut; - if (!but_gridtile->view_item || !oldbut_gridtile->view_item || - !UI_grid_view_item_matches(but_gridtile->view_item, oldbut_gridtile->view_item)) { + if ((but->type == UI_BTYPE_VIEW_ITEM) && (oldbut->type == UI_BTYPE_VIEW_ITEM)) { + uiButViewItem *but_item = (uiButViewItem *)but; + uiButViewItem *oldbut_item = (uiButViewItem *)oldbut; + if (!but_item->view_item || !oldbut_item->view_item || + !UI_view_item_matches(but_item->view_item, oldbut_item->view_item)) { return false; } } @@ -907,16 +898,10 @@ static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but) progress_oldbut->progress = progress_but->progress; break; } - case UI_BTYPE_TREEROW: { - uiButTreeRow *treerow_oldbut = (uiButTreeRow *)oldbut; - uiButTreeRow *treerow_newbut = (uiButTreeRow *)but; - SWAP(uiTreeViewItemHandle *, treerow_newbut->tree_item, treerow_oldbut->tree_item); - break; - } - case UI_BTYPE_GRID_TILE: { - uiButGridTile *gridtile_oldbut = (uiButGridTile *)oldbut; - uiButGridTile *gridtile_newbut = (uiButGridTile *)but; - SWAP(uiGridViewItemHandle *, gridtile_newbut->view_item, gridtile_oldbut->view_item); + case UI_BTYPE_VIEW_ITEM: { + uiButViewItem *view_item_oldbut = (uiButViewItem *)oldbut; + uiButViewItem *view_item_newbut = (uiButViewItem *)but; + SWAP(uiViewItemHandle *, view_item_newbut->view_item, view_item_oldbut->view_item); break; } default: @@ -1013,7 +998,7 @@ static bool ui_but_update_from_old_block(const bContext *C, /* Stupid special case: The active button may be inside (as in, overlapped on top) a view-item * button which we also want to keep highlighted then. */ - if (ui_but_is_view_item(but)) { + if (but->type == UI_BTYPE_VIEW_ITEM) { flag_copy |= UI_ACTIVE; } @@ -2245,21 +2230,12 @@ int ui_but_is_pushed_ex(uiBut *but, double *value) } } break; - case UI_BTYPE_TREEROW: { - uiButTreeRow *tree_row_but = (uiButTreeRow *)but; - - is_push = -1; - if (tree_row_but->tree_item) { - is_push = UI_tree_view_item_is_active(tree_row_but->tree_item); - } - break; - } - case UI_BTYPE_GRID_TILE: { - uiButGridTile *grid_tile_but = (uiButGridTile *)but; + case UI_BTYPE_VIEW_ITEM: { + const uiButViewItem *view_item_but = (const uiButViewItem *)but; is_push = -1; - if (grid_tile_but->view_item) { - is_push = UI_grid_view_item_is_active(grid_tile_but->view_item); + if (view_item_but->view_item) { + is_push = UI_view_item_is_active(view_item_but->view_item); } break; } @@ -4011,17 +3987,13 @@ static void ui_but_alloc_info(const eButType type, alloc_size = sizeof(uiButCurveProfile); alloc_str = "uiButCurveProfile"; break; - case UI_BTYPE_TREEROW: - alloc_size = sizeof(uiButTreeRow); - alloc_str = "uiButTreeRow"; - break; case UI_BTYPE_HOTKEY_EVENT: alloc_size = sizeof(uiButHotkeyEvent); alloc_str = "uiButHotkeyEvent"; break; - case UI_BTYPE_GRID_TILE: - alloc_size = sizeof(uiButGridTile); - alloc_str = "uiButGridTile"; + case UI_BTYPE_VIEW_ITEM: + alloc_size = sizeof(uiButViewItem); + alloc_str = "uiButViewItem"; break; default: alloc_size = sizeof(uiBut); @@ -4214,7 +4186,6 @@ static uiBut *ui_def_but(uiBlock *block, UI_BTYPE_BLOCK, UI_BTYPE_BUT_MENU, UI_BTYPE_SEARCH_MENU, - UI_BTYPE_TREEROW, UI_BTYPE_POPOVER)) { but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT); } @@ -6469,15 +6440,6 @@ uiBut *uiDefSearchButO_ptr(uiBlock *block, return but; } -void UI_but_treerow_indentation_set(uiBut *but, int indentation) -{ - uiButTreeRow *but_row = (uiButTreeRow *)but; - BLI_assert(but->type == UI_BTYPE_TREEROW); - - but_row->indentation = indentation; - BLI_assert(indentation >= 0); -} - void UI_but_hint_drawstr_set(uiBut *but, const char *string) { ui_but_add_shortcut(but, string, false); diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c index e58298cdaee..518fe65ee09 100644 --- a/source/blender/editors/interface/interface_context_menu.c +++ b/source/blender/editors/interface/interface_context_menu.c @@ -927,11 +927,11 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev { const ARegion *region = CTX_wm_menu(C) ? CTX_wm_menu(C) : CTX_wm_region(C); - uiButTreeRow *treerow_but = (uiButTreeRow *)ui_tree_row_find_mouse_over(region, event->xy); - if (treerow_but) { - BLI_assert(treerow_but->but.type == UI_BTYPE_TREEROW); - UI_tree_view_item_context_menu_build( - C, treerow_but->tree_item, uiLayoutColumn(layout, false)); + uiButViewItem *view_item_but = (uiButViewItem *)ui_view_item_find_mouse_over(region, + event->xy); + if (view_item_but) { + BLI_assert(view_item_but->but.type == UI_BTYPE_VIEW_ITEM); + UI_view_item_context_menu_build(C, view_item_but->view_item, uiLayoutColumn(layout, false)); uiItemS(layout); } } diff --git a/source/blender/editors/interface/interface_dropboxes.cc b/source/blender/editors/interface/interface_dropboxes.cc index 9d3c1372b15..df488fb9127 100644 --- a/source/blender/editors/interface/interface_dropboxes.cc +++ b/source/blender/editors/interface/interface_dropboxes.cc @@ -22,15 +22,14 @@ #include "UI_interface.h" /* -------------------------------------------------------------------- */ -/** \name Tree View Drag/Drop Callbacks +/** \name View Drag/Drop Callbacks * \{ */ -static bool ui_tree_view_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +static bool ui_view_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { const ARegion *region = CTX_wm_region(C); - const uiTreeViewItemHandle *hovered_tree_item = UI_block_tree_view_find_item_at(region, - event->xy); - if (!hovered_tree_item) { + const uiViewItemHandle *hovered_item = UI_block_view_find_item_at(region, event->xy); + if (!hovered_item) { return false; } @@ -39,21 +38,21 @@ static bool ui_tree_view_drop_poll(bContext *C, wmDrag *drag, const wmEvent *eve } drag->drop_state.free_disabled_info = false; - return UI_tree_view_item_can_drop(hovered_tree_item, drag, &drag->drop_state.disabled_info); + return UI_view_item_can_drop(hovered_item, drag, &drag->drop_state.disabled_info); } -static char *ui_tree_view_drop_tooltip(bContext *C, - wmDrag *drag, - const int xy[2], - wmDropBox *UNUSED(drop)) +static char *ui_view_drop_tooltip(bContext *C, + wmDrag *drag, + const int xy[2], + wmDropBox *UNUSED(drop)) { const ARegion *region = CTX_wm_region(C); - const uiTreeViewItemHandle *hovered_tree_item = UI_block_tree_view_find_item_at(region, xy); - if (!hovered_tree_item) { + const uiViewItemHandle *hovered_item = UI_block_view_find_item_at(region, xy); + if (!hovered_item) { return nullptr; } - return UI_tree_view_item_drop_tooltip(hovered_tree_item, drag); + return UI_view_item_drop_tooltip(hovered_item, drag); } /** \} */ @@ -140,12 +139,7 @@ void ED_dropboxes_ui() { ListBase *lb = WM_dropboxmap_find("User Interface", SPACE_EMPTY, 0); - WM_dropbox_add(lb, - "UI_OT_tree_view_drop", - ui_tree_view_drop_poll, - nullptr, - nullptr, - ui_tree_view_drop_tooltip); + WM_dropbox_add(lb, "UI_OT_view_drop", ui_view_drop_poll, nullptr, nullptr, ui_view_drop_tooltip); WM_dropbox_add(lb, "UI_OT_drop_name", ui_drop_name_poll, diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 2496136883d..0a50522a141 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1151,7 +1151,10 @@ static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleBu data->applied = true; } -static void ui_apply_but_TREEROW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data) +static void ui_apply_but_VIEW_ITEM(bContext *C, + uiBlock *block, + uiBut *but, + uiHandleButtonData *data) { if (data->apply_through_extra_icon) { /* Don't apply this, it would cause unintended tree-row toggling when clicking on extra icons. @@ -2128,10 +2131,10 @@ static bool ui_but_drag_init(bContext *C, return false; } } - else if (but->type == UI_BTYPE_TREEROW) { - uiButTreeRow *tree_row_but = (uiButTreeRow *)but; - if (tree_row_but->tree_item) { - UI_tree_view_item_drag_start(C, tree_row_but->tree_item); + else if (but->type == UI_BTYPE_VIEW_ITEM) { + const uiButViewItem *view_item_but = (uiButViewItem *)but; + if (view_item_but->view_item) { + UI_view_item_drag_start(C, view_item_but->view_item); } } else { @@ -2289,11 +2292,8 @@ static void ui_apply_but( case UI_BTYPE_ROW: ui_apply_but_ROW(C, block, but, data); break; - case UI_BTYPE_GRID_TILE: - ui_apply_but_ROW(C, block, but, data); - break; - case UI_BTYPE_TREEROW: - ui_apply_but_TREEROW(C, block, but, data); + case UI_BTYPE_VIEW_ITEM: + ui_apply_but_VIEW_ITEM(C, block, but, data); break; case UI_BTYPE_LISTROW: ui_apply_but_LISTROW(C, block, but, data); @@ -4764,53 +4764,13 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, cons return WM_UI_HANDLER_CONTINUE; } -static int ui_do_but_TREEROW(bContext *C, - uiBut *but, - uiHandleButtonData *data, - const wmEvent *event) -{ - uiButTreeRow *tree_row_but = (uiButTreeRow *)but; - BLI_assert(tree_row_but->but.type == UI_BTYPE_TREEROW); - - if (data->state == BUTTON_STATE_HIGHLIGHT) { - if (event->type == LEFTMOUSE) { - switch (event->val) { - case KM_PRESS: - /* Extra icons have priority, don't mess with them. */ - if (ui_but_extra_operator_icon_mouse_over_get(but, data->region, event)) { - return WM_UI_HANDLER_BREAK; - } - button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG); - data->dragstartx = event->xy[0]; - data->dragstarty = event->xy[1]; - return WM_UI_HANDLER_CONTINUE; - - case KM_CLICK: - button_activate_state(C, but, BUTTON_STATE_EXIT); - return WM_UI_HANDLER_BREAK; - - case KM_DBL_CLICK: - data->cancel = true; - UI_tree_view_item_begin_rename(tree_row_but->tree_item); - ED_region_tag_redraw(CTX_wm_region(C)); - return WM_UI_HANDLER_BREAK; - } - } - } - else if (data->state == BUTTON_STATE_WAIT_DRAG) { - /* Let "default" button handling take care of the drag logic. */ - return ui_do_but_EXIT(C, but, data, event); - } - - return WM_UI_HANDLER_CONTINUE; -} - -static int ui_do_but_GRIDTILE(bContext *C, - uiBut *but, - uiHandleButtonData *data, - const wmEvent *event) +static int ui_do_but_VIEW_ITEM(bContext *C, + uiBut *but, + uiHandleButtonData *data, + const wmEvent *event) { - BLI_assert(but->type == UI_BTYPE_GRID_TILE); + uiButViewItem *view_item_but = (uiButViewItem *)but; + BLI_assert(view_item_but->but.type == UI_BTYPE_VIEW_ITEM); if (data->state == BUTTON_STATE_HIGHLIGHT) { if (event->type == LEFTMOUSE) { @@ -4831,8 +4791,7 @@ static int ui_do_but_GRIDTILE(bContext *C, case KM_DBL_CLICK: data->cancel = true; - // uiButGridTile *grid_tile_but = (uiButGridTile *)but; - // UI_tree_view_item_begin_rename(grid_tile_but->tree_item); + UI_view_item_begin_rename(view_item_but->view_item); ED_region_tag_redraw(CTX_wm_region(C)); return WM_UI_HANDLER_BREAK; } @@ -7980,7 +7939,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * * to spawn the context menu should also activate the item. This makes it clear which item * will be operated on. * Apply the button immediately, so context menu polls get the right active item. */ - if (ELEM(but->type, UI_BTYPE_TREEROW)) { + if (ELEM(but->type, UI_BTYPE_VIEW_ITEM)) { ui_apply_but(C, but->block, but, but->active, true); } @@ -8045,11 +8004,8 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * case UI_BTYPE_ROW: retval = ui_do_but_TOG(C, but, data, event); break; - case UI_BTYPE_GRID_TILE: - retval = ui_do_but_GRIDTILE(C, but, data, event); - break; - case UI_BTYPE_TREEROW: - retval = ui_do_but_TREEROW(C, but, data, event); + case UI_BTYPE_VIEW_ITEM: + retval = ui_do_but_VIEW_ITEM(C, but, data, event); break; case UI_BTYPE_SCROLL: retval = ui_do_but_SCROLL(C, block, but, data, event); @@ -9725,7 +9681,7 @@ static int ui_handle_view_items_hover(const wmEvent *event, const ARegion *regio } LISTBASE_FOREACH (uiBut *, but, &block->buttons) { - if (ui_but_is_view_item(but)) { + if (but->type == UI_BTYPE_VIEW_ITEM) { but->flag &= ~UI_ACTIVE; has_view_item = true; } @@ -9752,7 +9708,7 @@ static int ui_handle_view_item_event(bContext *C, ARegion *region, uiBut *view_but) { - BLI_assert(ui_but_is_view_item(view_but)); + BLI_assert(view_but->type == UI_BTYPE_VIEW_ITEM); if (event->type == LEFTMOUSE) { /* Will free active button if there already is one. */ ui_handle_button_activate(C, region, view_but, BUTTON_ACTIVATE_OVER); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 5e0382f73a9..03b9d03a6e3 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -343,20 +343,12 @@ typedef struct uiButProgressbar { float progress; } uiButProgressbar; -/** Derived struct for #UI_BTYPE_TREEROW. */ -typedef struct uiButTreeRow { +typedef struct uiButViewItem { uiBut but; - uiTreeViewItemHandle *tree_item; - int indentation; -} uiButTreeRow; - -/** Derived struct for #UI_BTYPE_GRID_TILE. */ -typedef struct uiButGridTile { - uiBut but; - - uiGridViewItemHandle *view_item; -} uiButGridTile; + /* C-Handle to the view item this button was created for. */ + uiViewItemHandle *view_item; +} uiButViewItem; /** Derived struct for #UI_BTYPE_HSVCUBE. */ typedef struct uiButHSVCube { @@ -1372,7 +1364,6 @@ void ui_but_anim_decorate_update_from_flag(uiButDecorator *but); bool ui_but_is_editable(const uiBut *but) ATTR_WARN_UNUSED_RESULT; bool ui_but_is_editable_as_text(const uiBut *but) ATTR_WARN_UNUSED_RESULT; bool ui_but_is_toggle(const uiBut *but) ATTR_WARN_UNUSED_RESULT; -bool ui_but_is_view_item(const uiBut *but) ATTR_WARN_UNUSED_RESULT; /** * Can we mouse over the button or is it hidden/disabled/layout. * \note ctrl is kind of a hack currently, @@ -1406,9 +1397,7 @@ uiBut *ui_list_row_find_from_index(const struct ARegion *region, uiBut *listbox) ATTR_WARN_UNUSED_RESULT; uiBut *ui_view_item_find_mouse_over(const struct ARegion *region, const int xy[2]) ATTR_NONNULL(1, 2); -uiBut *ui_tree_row_find_mouse_over(const struct ARegion *region, const int xy[2]) - ATTR_NONNULL(1, 2); -uiBut *ui_tree_row_find_active(const struct ARegion *region); +uiBut *ui_view_item_find_active(const struct ARegion *region); typedef bool (*uiButFindPollFn)(const uiBut *but, const void *customdata); /** @@ -1546,8 +1535,8 @@ void ui_block_free_views(struct uiBlock *block); uiViewHandle *ui_block_view_find_matching_in_old_block(const uiBlock *new_block, const uiViewHandle *new_view); -uiButTreeRow *ui_block_view_find_treerow_in_old_block(const uiBlock *new_block, - const uiTreeViewItemHandle *new_item_handle); +uiButViewItem *ui_block_view_find_matching_view_item_but_in_old_block( + const uiBlock *new_block, const uiViewItemHandle *new_item_handle); /* interface_templates.c */ diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index aafb56119ae..7a51ed23677 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -2054,40 +2054,39 @@ static void UI_OT_list_start_filter(wmOperatorType *ot) /** \name UI Tree-View Drop Operator * \{ */ -static bool ui_tree_view_drop_poll(bContext *C) +static bool ui_view_drop_poll(bContext *C) { const wmWindow *win = CTX_wm_window(C); const ARegion *region = CTX_wm_region(C); - const uiTreeViewItemHandle *hovered_tree_item = UI_block_tree_view_find_item_at( - region, win->eventstate->xy); + const uiViewItemHandle *hovered_item = UI_block_view_find_item_at(region, win->eventstate->xy); - return hovered_tree_item != NULL; + return hovered_item != NULL; } -static int ui_tree_view_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) +static int ui_view_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { if (event->custom != EVT_DATA_DRAGDROP) { return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } const ARegion *region = CTX_wm_region(C); - uiTreeViewItemHandle *hovered_tree_item = UI_block_tree_view_find_item_at(region, event->xy); + uiViewItemHandle *hovered_item = UI_block_view_find_item_at(region, event->xy); - if (!UI_tree_view_item_drop_handle(C, hovered_tree_item, event->customdata)) { + if (!UI_view_item_drop_handle(C, hovered_item, event->customdata)) { return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } return OPERATOR_FINISHED; } -static void UI_OT_tree_view_drop(wmOperatorType *ot) +static void UI_OT_view_drop(wmOperatorType *ot) { - ot->name = "Tree View drop"; - ot->idname = "UI_OT_tree_view_drop"; - ot->description = "Drag and drop items onto a tree item"; + ot->name = "View drop"; + ot->idname = "UI_OT_view_drop"; + ot->description = "Drag and drop items onto a data-set item"; - ot->invoke = ui_tree_view_drop_invoke; - ot->poll = ui_tree_view_drop_poll; + ot->invoke = ui_view_drop_invoke; + ot->poll = ui_view_drop_poll; ot->flag = OPTYPE_INTERNAL; } @@ -2095,43 +2094,42 @@ static void UI_OT_tree_view_drop(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ -/** \name UI Tree-View Item Rename Operator +/** \name UI View Item Rename Operator * - * General purpose renaming operator for tree-views. Thanks to this, to add a rename button to - * context menus for example, tree-view API users don't have to implement their own renaming - * operators with the same logic as they already have for their #ui::AbstractTreeViewItem::rename() - * override. + * General purpose renaming operator for views. Thanks to this, to add a rename button to context + * menus for example, view API users don't have to implement their own renaming operators with the + * same logic as they already have for their #ui::AbstractViewItem::rename() override. * * \{ */ -static bool ui_tree_view_item_rename_poll(bContext *C) +static bool ui_view_item_rename_poll(bContext *C) { const ARegion *region = CTX_wm_region(C); - const uiTreeViewItemHandle *active_item = UI_block_tree_view_find_active_item(region); - return active_item != NULL && UI_tree_view_item_can_rename(active_item); + const uiViewItemHandle *active_item = UI_block_view_find_active_item(region); + return active_item != NULL && UI_view_item_can_rename(active_item); } -static int ui_tree_view_item_rename_exec(bContext *C, wmOperator *UNUSED(op)) +static int ui_view_item_rename_exec(bContext *C, wmOperator *UNUSED(op)) { ARegion *region = CTX_wm_region(C); - uiTreeViewItemHandle *active_item = UI_block_tree_view_find_active_item(region); + uiViewItemHandle *active_item = UI_block_view_find_active_item(region); - UI_tree_view_item_begin_rename(active_item); + UI_view_item_begin_rename(active_item); ED_region_tag_redraw(region); return OPERATOR_FINISHED; } -static void UI_OT_tree_view_item_rename(wmOperatorType *ot) +static void UI_OT_view_item_rename(wmOperatorType *ot) { - ot->name = "Rename Tree-View Item"; - ot->idname = "UI_OT_tree_view_item_rename"; - ot->description = "Rename the active item in the tree"; + ot->name = "Rename View Item"; + ot->idname = "UI_OT_view_item_rename"; + ot->description = "Rename the active item in the data-set view"; - ot->exec = ui_tree_view_item_rename_exec; - ot->poll = ui_tree_view_item_rename_poll; + ot->exec = ui_view_item_rename_exec; + ot->poll = ui_view_item_rename_poll; /* Could get a custom tooltip via the `get_description()` callback and another overridable - * function of the tree-view. */ + * function of the view. */ ot->flag = OPTYPE_INTERNAL; } @@ -2235,8 +2233,8 @@ void ED_operatortypes_ui(void) WM_operatortype_append(UI_OT_list_start_filter); - WM_operatortype_append(UI_OT_tree_view_drop); - WM_operatortype_append(UI_OT_tree_view_item_rename); + WM_operatortype_append(UI_OT_view_drop); + WM_operatortype_append(UI_OT_view_item_rename); /* external */ WM_operatortype_append(UI_OT_eyedropper_color); diff --git a/source/blender/editors/interface/interface_query.cc b/source/blender/editors/interface/interface_query.cc index 71cf60985df..f084f3e06cb 100644 --- a/source/blender/editors/interface/interface_query.cc +++ b/source/blender/editors/interface/interface_query.cc @@ -54,13 +54,7 @@ bool ui_but_is_toggle(const uiBut *but) UI_BTYPE_TOGGLE_N, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N, - UI_BTYPE_ROW, - UI_BTYPE_TREEROW); -} - -bool ui_but_is_view_item(const uiBut *but) -{ - return ELEM(but->type, UI_BTYPE_TREEROW, UI_BTYPE_GRID_TILE); + UI_BTYPE_ROW); } bool ui_but_is_interactive_ex(const uiBut *but, const bool labeledit, const bool for_tooltip) @@ -462,14 +456,9 @@ uiBut *ui_list_row_find_from_index(const ARegion *region, const int index, uiBut return ui_but_find(region, ui_but_is_listrow_at_index, &data); } -static bool ui_but_is_treerow(const uiBut *but, const void *UNUSED(customdata)) -{ - return but->type == UI_BTYPE_TREEROW; -} - static bool ui_but_is_view_item_fn(const uiBut *but, const void *UNUSED(customdata)) { - return ui_but_is_view_item(but); + return but->type == UI_BTYPE_VIEW_ITEM; } uiBut *ui_view_item_find_mouse_over(const ARegion *region, const int xy[2]) @@ -477,24 +466,19 @@ uiBut *ui_view_item_find_mouse_over(const ARegion *region, const int xy[2]) return ui_but_find_mouse_over_ex(region, xy, false, false, ui_but_is_view_item_fn, nullptr); } -uiBut *ui_tree_row_find_mouse_over(const ARegion *region, const int xy[2]) -{ - return ui_but_find_mouse_over_ex(region, xy, false, false, ui_but_is_treerow, nullptr); -} - -static bool ui_but_is_active_treerow(const uiBut *but, const void *customdata) +static bool ui_but_is_active_view_item(const uiBut *but, const void *UNUSED(customdata)) { - if (!ui_but_is_treerow(but, customdata)) { + if (but->type != UI_BTYPE_VIEW_ITEM) { return false; } - const uiButTreeRow *treerow_but = (const uiButTreeRow *)but; - return UI_tree_view_item_is_active(treerow_but->tree_item); + const uiButViewItem *view_item_but = (const uiButViewItem *)but; + return UI_view_item_is_active(view_item_but->view_item); } -uiBut *ui_tree_row_find_active(const ARegion *region) +uiBut *ui_view_item_find_active(const ARegion *region) { - return ui_but_find(region, ui_but_is_active_treerow, nullptr); + return ui_but_find(region, ui_but_is_active_view_item, nullptr); } /** \} */ diff --git a/source/blender/editors/interface/interface_view.cc b/source/blender/editors/interface/interface_view.cc index 70728565263..b35f6d2c969 100644 --- a/source/blender/editors/interface/interface_view.cc +++ b/source/blender/editors/interface/interface_view.cc @@ -86,24 +86,24 @@ void UI_block_views_listen(const uiBlock *block, const wmRegionListenerParams *l } } -uiTreeViewItemHandle *UI_block_tree_view_find_item_at(const ARegion *region, const int xy[2]) +uiViewItemHandle *UI_block_view_find_item_at(const ARegion *region, const int xy[2]) { - uiButTreeRow *tree_row_but = (uiButTreeRow *)ui_tree_row_find_mouse_over(region, xy); - if (!tree_row_but) { + uiButViewItem *item_but = (uiButViewItem *)ui_view_item_find_mouse_over(region, xy); + if (!item_but) { return nullptr; } - return tree_row_but->tree_item; + return item_but->view_item; } -uiTreeViewItemHandle *UI_block_tree_view_find_active_item(const ARegion *region) +uiViewItemHandle *UI_block_view_find_active_item(const ARegion *region) { - uiButTreeRow *tree_row_but = (uiButTreeRow *)ui_tree_row_find_active(region); - if (!tree_row_but) { + uiButViewItem *item_but = (uiButViewItem *)ui_view_item_find_active(region); + if (!item_but) { return nullptr; } - return tree_row_but->tree_item; + return item_but->view_item; } static StringRef ui_block_view_find_idname(const uiBlock &block, const AbstractView &view) @@ -151,39 +151,38 @@ uiViewHandle *ui_block_view_find_matching_in_old_block(const uiBlock *new_block, return reinterpret_cast<uiViewHandle *>(old_view); } -uiButTreeRow *ui_block_view_find_treerow_in_old_block(const uiBlock *new_block, - const uiTreeViewItemHandle *new_item_handle) +uiButViewItem *ui_block_view_find_matching_view_item_but_in_old_block( + const uiBlock *new_block, const uiViewItemHandle *new_item_handle) { uiBlock *old_block = new_block->oldblock; if (!old_block) { return nullptr; } - const AbstractTreeViewItem &new_item = *reinterpret_cast<const AbstractTreeViewItem *>( - new_item_handle); + const AbstractViewItem &new_item = *reinterpret_cast<const AbstractViewItem *>(new_item_handle); const AbstractView *old_view = ui_block_view_find_matching_in_old_block_impl( - *new_block, new_item.get_tree_view()); + *new_block, new_item.get_view()); if (!old_view) { return nullptr; } LISTBASE_FOREACH (uiBut *, old_but, &old_block->buttons) { - if (old_but->type != UI_BTYPE_TREEROW) { + if (old_but->type != UI_BTYPE_VIEW_ITEM) { continue; } - uiButTreeRow *old_treerow_but = (uiButTreeRow *)old_but; - if (!old_treerow_but->tree_item) { + uiButViewItem *old_item_but = (uiButViewItem *)old_but; + if (!old_item_but->view_item) { continue; } - AbstractTreeViewItem &old_item = *reinterpret_cast<AbstractTreeViewItem *>( - old_treerow_but->tree_item); - /* Check if the row is from the expected tree-view. */ - if (&old_item.get_tree_view() != old_view) { + AbstractViewItem &old_item = *reinterpret_cast<AbstractViewItem *>(old_item_but->view_item); + /* Check if the item is from the expected view. */ + if (&old_item.get_view() != old_view) { continue; } - if (UI_tree_view_item_matches(new_item_handle, old_treerow_but->tree_item)) { - return old_treerow_but; + if (UI_view_item_matches(reinterpret_cast<const uiViewItemHandle *>(&new_item), + reinterpret_cast<const uiViewItemHandle *>(&old_item))) { + return old_item_but; } } diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index e2df2d77817..855e72788d2 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -104,8 +104,7 @@ typedef enum { UI_WTYPE_LISTITEM, UI_WTYPE_PROGRESSBAR, UI_WTYPE_NODESOCKET, - UI_WTYPE_TREEROW, - UI_WTYPE_GRID_TILE, + UI_WTYPE_VIEW_ITEM, } uiWidgetTypeEnum; /** @@ -3672,12 +3671,11 @@ static void widget_progressbar(uiBut *but, widgetbase_draw(&wtb_bar, wcol); } -static void widget_treerow_exec(uiWidgetColors *wcol, - rcti *rect, - const uiWidgetStateInfo *state, - int UNUSED(roundboxalign), - int indentation, - const float zoom) +static void widget_view_item(uiWidgetColors *wcol, + rcti *rect, + const uiWidgetStateInfo *state, + int UNUSED(roundboxalign), + const float zoom) { uiWidgetBase wtb; widget_init(&wtb); @@ -3690,31 +3688,6 @@ static void widget_treerow_exec(uiWidgetColors *wcol, if ((state->but_flag & UI_ACTIVE) || (state->but_flag & UI_SELECT)) { widgetbase_draw(&wtb, wcol); } - - BLI_rcti_resize(rect, BLI_rcti_size_x(rect) - UI_UNIT_X * indentation, BLI_rcti_size_y(rect)); - BLI_rcti_translate(rect, 0.5f * UI_UNIT_X * indentation, 0); -} - -static void widget_treerow(uiBut *but, - uiWidgetColors *wcol, - rcti *rect, - const uiWidgetStateInfo *state, - int roundboxalign, - const float zoom) -{ - uiButTreeRow *tree_row = (uiButTreeRow *)but; - BLI_assert(but->type == UI_BTYPE_TREEROW); - widget_treerow_exec(wcol, rect, state, roundboxalign, tree_row->indentation, zoom); -} - -static void widget_gridtile(uiWidgetColors *wcol, - rcti *rect, - const uiWidgetStateInfo *state, - int roundboxalign, - const float zoom) -{ - /* TODO Reuse tree-row drawing. */ - widget_treerow_exec(wcol, rect, state, roundboxalign, 0, zoom); } static void widget_nodesocket(uiBut *but, @@ -4608,14 +4581,9 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type) wt.custom = widget_progressbar; break; - case UI_WTYPE_TREEROW: - wt.wcol_theme = &btheme->tui.wcol_view_item; - wt.custom = widget_treerow; - break; - - case UI_WTYPE_GRID_TILE: + case UI_WTYPE_VIEW_ITEM: wt.wcol_theme = &btheme->tui.wcol_view_item; - wt.draw = widget_gridtile; + wt.draw = widget_view_item; break; case UI_WTYPE_NODESOCKET: @@ -4949,13 +4917,8 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu fstyle = &style->widgetlabel; break; - case UI_BTYPE_TREEROW: - wt = widget_type(UI_WTYPE_TREEROW); - fstyle = &style->widgetlabel; - break; - - case UI_BTYPE_GRID_TILE: - wt = widget_type(UI_WTYPE_GRID_TILE); + case UI_BTYPE_VIEW_ITEM: + wt = widget_type(UI_WTYPE_VIEW_ITEM); fstyle = &style->widgetlabel; break; diff --git a/source/blender/editors/interface/tree_view.cc b/source/blender/editors/interface/tree_view.cc index ec1140e8efb..c224226ba17 100644 --- a/source/blender/editors/interface/tree_view.cc +++ b/source/blender/editors/interface/tree_view.cc @@ -37,9 +37,11 @@ AbstractTreeViewItem &TreeViewItemContainer::add_tree_item( if (root_ == nullptr) { root_ = this; } - + AbstractTreeView &tree_view = static_cast<AbstractTreeView &>(*root_); AbstractTreeViewItem &added_item = *children_.last(); added_item.root_ = root_; + tree_view.register_item(added_item); + if (root_ != this) { /* Any item that isn't the root can be assumed to the a #AbstractTreeViewItem. Not entirely * nice to static_cast this, but well... */ @@ -95,7 +97,7 @@ AbstractTreeViewItem *AbstractTreeView::find_matching_child( const AbstractTreeViewItem &lookup_item, const TreeViewOrItem &items) { for (const auto &iter_item : items.children_) { - if (lookup_item.matches(*iter_item)) { + if (lookup_item.matches_single(*iter_item)) { /* We have a matching item! */ return iter_item.get(); } @@ -118,9 +120,8 @@ void AbstractTreeViewItem::tree_row_click_fn(struct bContext * /*C*/, void *but_arg1, void * /*arg2*/) { - uiButTreeRow *tree_row_but = (uiButTreeRow *)but_arg1; - AbstractTreeViewItem &tree_item = reinterpret_cast<AbstractTreeViewItem &>( - *tree_row_but->tree_item); + uiButViewItem *item_but = (uiButViewItem *)but_arg1; + AbstractTreeViewItem &tree_item = reinterpret_cast<AbstractTreeViewItem &>(*item_but->view_item); tree_item.activate(); /* Not only activate the item, also show its children. Maybe this should be optional, or @@ -131,11 +132,11 @@ void AbstractTreeViewItem::tree_row_click_fn(struct bContext * /*C*/, void AbstractTreeViewItem::add_treerow_button(uiBlock &block) { /* For some reason a width > (UI_UNIT_X * 2) make the layout system use all available width. */ - tree_row_but_ = (uiButTreeRow *)uiDefBut( - &block, UI_BTYPE_TREEROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, nullptr, 0, 0, 0, 0, ""); + view_item_but_ = (uiButViewItem *)uiDefBut( + &block, UI_BTYPE_VIEW_ITEM, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, nullptr, 0, 0, 0, 0, ""); - tree_row_but_->tree_item = reinterpret_cast<uiTreeViewItemHandle *>(this); - UI_but_func_set(&tree_row_but_->but, tree_row_click_fn, tree_row_but_, nullptr); + view_item_but_->view_item = reinterpret_cast<uiViewItemHandle *>(this); + UI_but_func_set(&view_item_but_->but, tree_row_click_fn, view_item_but_, nullptr); } void AbstractTreeViewItem::add_indent(uiLayout &row) const @@ -167,10 +168,9 @@ void AbstractTreeViewItem::collapse_chevron_click_fn(struct bContext *C, const wmWindow *win = CTX_wm_window(C); const ARegion *region = CTX_wm_region(C); - uiTreeViewItemHandle *hovered_item_handle = UI_block_tree_view_find_item_at(region, - win->eventstate->xy); - AbstractTreeViewItem *hovered_item = reinterpret_cast<AbstractTreeViewItem *>( - hovered_item_handle); + uiViewItemHandle *hovered_item_handle = UI_block_view_find_item_at(region, win->eventstate->xy); + + AbstractTreeViewItem *hovered_item = from_item_handle<AbstractTreeViewItem>(hovered_item_handle); BLI_assert(hovered_item != nullptr); hovered_item->toggle_collapsed(); @@ -204,40 +204,6 @@ void AbstractTreeViewItem::add_collapse_chevron(uiBlock &block) const BLI_assert(is_collapse_chevron_but(but)); } -AbstractTreeViewItem *AbstractTreeViewItem::find_tree_item_from_rename_button( - const uiBut &rename_but) -{ - /* A minimal sanity check, can't do much more here. */ - BLI_assert(rename_but.type == UI_BTYPE_TEXT && rename_but.poin); - - LISTBASE_FOREACH (uiBut *, but, &rename_but.block->buttons) { - if (but->type != UI_BTYPE_TREEROW) { - continue; - } - - uiButTreeRow *tree_row_but = (uiButTreeRow *)but; - AbstractTreeViewItem *item = reinterpret_cast<AbstractTreeViewItem *>(tree_row_but->tree_item); - const AbstractTreeView &tree_view = item->get_tree_view(); - - if (item->is_renaming() && (tree_view.get_rename_buffer().data() == rename_but.poin)) { - return item; - } - } - - return nullptr; -} - -void AbstractTreeViewItem::rename_button_fn(bContext *UNUSED(C), void *arg, char *UNUSED(origstr)) -{ - const uiBut *rename_but = static_cast<uiBut *>(arg); - AbstractTreeViewItem *item = find_tree_item_from_rename_button(*rename_but); - BLI_assert(item); - - const AbstractTreeView &tree_view = item->get_tree_view(); - item->rename(tree_view.get_rename_buffer().data()); - item->end_renaming(); -} - void AbstractTreeViewItem::add_rename_button(uiLayout &row) { uiBlock *block = uiLayoutGetBlock(&row); @@ -247,33 +213,7 @@ void AbstractTreeViewItem::add_rename_button(uiLayout &row) /* Enable emboss for the text button. */ UI_block_emboss_set(block, UI_EMBOSS); - AbstractTreeView &tree_view = get_tree_view(); - uiBut *rename_but = uiDefBut(block, - UI_BTYPE_TEXT, - 1, - "", - 0, - 0, - UI_UNIT_X * 10, - UI_UNIT_Y, - tree_view.get_rename_buffer().data(), - 1.0f, - tree_view.get_rename_buffer().size(), - 0, - 0, - ""); - - /* Gotta be careful with what's passed to the `arg1` here. Any tree data will be freed once the - * callback is executed. */ - UI_but_func_rename_set(rename_but, AbstractTreeViewItem::rename_button_fn, rename_but); - UI_but_flag_disable(rename_but, UI_BUT_UNDO); - - const bContext *evil_C = static_cast<bContext *>(block->evil_C); - ARegion *region = CTX_wm_region(evil_C); - /* Returns false if the button was removed. */ - if (UI_but_active_only(evil_C, region, block, rename_but) == false) { - end_renaming(); - } + AbstractViewItem::add_rename_button(*block); UI_block_emboss_set(block, previous_emboss); UI_block_layout_set_current(block, &row); @@ -306,82 +246,35 @@ bool AbstractTreeViewItem::supports_collapsing() const return true; } -std::unique_ptr<AbstractTreeViewItemDragController> AbstractTreeViewItem::create_drag_controller() - const -{ - /* There's no drag controller (and hence no drag support) by default. */ - return nullptr; -} - -std::unique_ptr<AbstractTreeViewItemDropController> AbstractTreeViewItem::create_drop_controller() - const -{ - /* There's no drop controller (and hence no drop support) by default. */ - return nullptr; -} - -bool AbstractTreeViewItem::supports_renaming() const +StringRef AbstractTreeViewItem::get_rename_string() const { - /* No renaming by default. */ - return false; + return label_; } bool AbstractTreeViewItem::rename(StringRefNull new_name) { - /* It is important to update the label after renaming, so #AbstractTreeViewItem::matches() + /* It is important to update the label after renaming, so #AbstractTreeViewItem::matches_single() * recognizes the item. (It only compares labels by default.) */ label_ = new_name; return true; } -void AbstractTreeViewItem::build_context_menu(bContext & /*C*/, uiLayout & /*column*/) const -{ - /* No context menu by default. */ -} - void AbstractTreeViewItem::update_from_old(const AbstractViewItem &old) { AbstractViewItem::update_from_old(old); const AbstractTreeViewItem &old_tree_item = dynamic_cast<const AbstractTreeViewItem &>(old); is_open_ = old_tree_item.is_open_; - is_renaming_ = old_tree_item.is_renaming_; } -bool AbstractTreeViewItem::matches(const AbstractTreeViewItem &other) const +bool AbstractTreeViewItem::matches_single(const AbstractTreeViewItem &other) const { return label_ == other.label_; } -void AbstractTreeViewItem::begin_renaming() -{ - AbstractTreeView &tree_view = get_tree_view(); - if (tree_view.is_renaming() || !supports_renaming()) { - return; - } - - if (tree_view.begin_renaming()) { - is_renaming_ = true; - } - - std::copy(std::begin(label_), std::end(label_), std::begin(tree_view.get_rename_buffer())); -} - -void AbstractTreeViewItem::end_renaming() -{ - if (!is_renaming()) { - return; - } - - is_renaming_ = false; - - AbstractTreeView &tree_view = get_tree_view(); - tree_view.end_renaming(); -} - AbstractTreeView &AbstractTreeViewItem::get_tree_view() const { - return static_cast<AbstractTreeView &>(*root_); + return dynamic_cast<AbstractTreeView &>(get_view()); } int AbstractTreeViewItem::count_parents() const @@ -417,26 +310,19 @@ void AbstractTreeViewItem::deactivate() is_active_ = false; } -bool AbstractTreeViewItem::is_active() const -{ - BLI_assert_msg(get_tree_view().is_reconstructed(), - "State can't be queried until reconstruction is completed"); - return is_active_; -} - bool AbstractTreeViewItem::is_hovered() const { BLI_assert_msg(get_tree_view().is_reconstructed(), "State can't be queried until reconstruction is completed"); - BLI_assert_msg(tree_row_but_ != nullptr, + BLI_assert_msg(view_item_but_ != nullptr, "Hovered state can't be queried before the tree row is being built"); - const uiTreeViewItemHandle *this_handle = reinterpret_cast<const uiTreeViewItemHandle *>(this); + const uiViewItemHandle *this_item_handle = reinterpret_cast<const uiViewItemHandle *>(this); /* The new layout hasn't finished construction yet, so the final state of the button is unknown. * Get the matching button from the previous redraw instead. */ - uiButTreeRow *old_treerow_but = ui_block_view_find_treerow_in_old_block(tree_row_but_->but.block, - this_handle); - return old_treerow_but && (old_treerow_but->but.flag & UI_ACTIVE); + uiButViewItem *old_item_but = ui_block_view_find_matching_view_item_but_in_old_block( + view_item_but_->but.block, this_item_handle); + return old_item_but && (old_item_but->but.flag & UI_ACTIVE); } bool AbstractTreeViewItem::is_collapsed() const @@ -464,11 +350,6 @@ bool AbstractTreeViewItem::is_collapsible() const return this->supports_collapsing(); } -bool AbstractTreeViewItem::is_renaming() const -{ - return is_renaming_; -} - void AbstractTreeViewItem::ensure_parents_uncollapsed() { for (AbstractTreeViewItem *parent = parent_; parent; parent = parent->parent_) { @@ -476,19 +357,21 @@ void AbstractTreeViewItem::ensure_parents_uncollapsed() } } -bool AbstractTreeViewItem::matches_including_parents(const AbstractTreeViewItem &other) const +bool AbstractTreeViewItem::matches(const AbstractViewItem &other) const { - if (!matches(other)) { + const AbstractTreeViewItem &other_tree_item = dynamic_cast<const AbstractTreeViewItem &>(other); + + if (!matches_single(other_tree_item)) { return false; } - if (count_parents() != other.count_parents()) { + if (count_parents() != other_tree_item.count_parents()) { return false; } - for (AbstractTreeViewItem *parent = parent_, *other_parent = other.parent_; + for (AbstractTreeViewItem *parent = parent_, *other_parent = other_tree_item.parent_; parent && other_parent; parent = parent->parent_, other_parent = other_parent->parent_) { - if (!parent->matches(*other_parent)) { + if (!parent->matches_single(*other_parent)) { return false; } } @@ -496,9 +379,9 @@ bool AbstractTreeViewItem::matches_including_parents(const AbstractTreeViewItem return true; } -uiButTreeRow *AbstractTreeViewItem::tree_row_button() +uiButViewItem *AbstractTreeViewItem::view_item_button() { - return tree_row_but_; + return view_item_but_; } void AbstractTreeViewItem::change_state_delayed() @@ -511,25 +394,6 @@ void AbstractTreeViewItem::change_state_delayed() /* ---------------------------------------------------------------------- */ -AbstractTreeViewItemDragController::AbstractTreeViewItemDragController(AbstractTreeView &tree_view) - : tree_view_(tree_view) -{ -} - -void AbstractTreeViewItemDragController::on_drag_start() -{ - /* Do nothing by default. */ -} - -/* ---------------------------------------------------------------------- */ - -AbstractTreeViewItemDropController::AbstractTreeViewItemDropController(AbstractTreeView &tree_view) - : tree_view_(tree_view) -{ -} - -/* ---------------------------------------------------------------------- */ - class TreeViewLayoutBuilder { uiBlock &block_; @@ -575,7 +439,7 @@ void TreeViewLayoutBuilder::polish_layout(const uiBlock &block) UI_but_drawflag_enable(static_cast<uiBut *>(but->next), UI_BUT_NO_TEXT_PADDING); } - if (but->type == UI_BTYPE_TREEROW) { + if (but->type == UI_BTYPE_VIEW_ITEM) { break; } } @@ -687,154 +551,4 @@ std::optional<bool> BasicTreeViewItem::should_be_active() const return std::nullopt; } -/* ---------------------------------------------------------------------- */ - -/** - * Helper for a public (C-)API, presenting higher level functionality. Has access to internal - * data/functionality (friend of #AbstractTreeViewItem), which is sometimes needed when - * functionality of the API needs to be constructed from multiple internal conditions and/or - * functions that on their own shouldn't be part of the API. - */ -class TreeViewItemAPIWrapper { - public: - static bool matches(const AbstractTreeViewItem &a, const AbstractTreeViewItem &b) - { - /* TODO should match the tree-view as well. */ - return a.matches_including_parents(b); - } - - static bool drag_start(bContext &C, const AbstractTreeViewItem &item) - { - const std::unique_ptr<AbstractTreeViewItemDragController> drag_controller = - item.create_drag_controller(); - if (!drag_controller) { - return false; - } - - WM_event_start_drag(&C, - ICON_NONE, - drag_controller->get_drag_type(), - drag_controller->create_drag_data(), - 0, - WM_DRAG_FREE_DATA); - drag_controller->on_drag_start(); - - return true; - } - - static bool can_drop(const AbstractTreeViewItem &item, - const wmDrag &drag, - const char **r_disabled_hint) - { - const std::unique_ptr<AbstractTreeViewItemDropController> drop_controller = - item.create_drop_controller(); - if (!drop_controller) { - return false; - } - - return drop_controller->can_drop(drag, r_disabled_hint); - } - - static std::string drop_tooltip(const AbstractTreeViewItem &item, const wmDrag &drag) - { - const std::unique_ptr<AbstractTreeViewItemDropController> drop_controller = - item.create_drop_controller(); - if (!drop_controller) { - return {}; - } - - return drop_controller->drop_tooltip(drag); - } - - static bool drop_handle(bContext &C, const AbstractTreeViewItem &item, const ListBase &drags) - { - std::unique_ptr<AbstractTreeViewItemDropController> drop_controller = - item.create_drop_controller(); - - const char *disabled_hint_dummy = nullptr; - LISTBASE_FOREACH (const wmDrag *, drag, &drags) { - if (drop_controller->can_drop(*drag, &disabled_hint_dummy)) { - return drop_controller->on_drop(&C, *drag); - } - } - - return false; - } - - static bool can_rename(const AbstractTreeViewItem &item) - { - const AbstractTreeView &tree_view = item.get_tree_view(); - return !tree_view.is_renaming() && item.supports_renaming(); - } -}; - } // namespace blender::ui - -/* ---------------------------------------------------------------------- */ -/* C-API */ - -using namespace blender::ui; - -bool UI_tree_view_item_is_active(const uiTreeViewItemHandle *item_handle) -{ - const AbstractTreeViewItem &item = reinterpret_cast<const AbstractTreeViewItem &>(*item_handle); - return item.is_active(); -} - -bool UI_tree_view_item_matches(const uiTreeViewItemHandle *a_handle, - const uiTreeViewItemHandle *b_handle) -{ - const AbstractTreeViewItem &a = reinterpret_cast<const AbstractTreeViewItem &>(*a_handle); - const AbstractTreeViewItem &b = reinterpret_cast<const AbstractTreeViewItem &>(*b_handle); - return TreeViewItemAPIWrapper::matches(a, b); -} - -bool UI_tree_view_item_drag_start(bContext *C, uiTreeViewItemHandle *item_) -{ - const AbstractTreeViewItem &item = reinterpret_cast<const AbstractTreeViewItem &>(*item_); - return TreeViewItemAPIWrapper::drag_start(*C, item); -} - -bool UI_tree_view_item_can_drop(const uiTreeViewItemHandle *item_, - const wmDrag *drag, - const char **r_disabled_hint) -{ - const AbstractTreeViewItem &item = reinterpret_cast<const AbstractTreeViewItem &>(*item_); - return TreeViewItemAPIWrapper::can_drop(item, *drag, r_disabled_hint); -} - -char *UI_tree_view_item_drop_tooltip(const uiTreeViewItemHandle *item_, const wmDrag *drag) -{ - const AbstractTreeViewItem &item = reinterpret_cast<const AbstractTreeViewItem &>(*item_); - - const std::string tooltip = TreeViewItemAPIWrapper::drop_tooltip(item, *drag); - return tooltip.empty() ? nullptr : BLI_strdup(tooltip.c_str()); -} - -bool UI_tree_view_item_drop_handle(bContext *C, - const uiTreeViewItemHandle *item_, - const ListBase *drags) -{ - const AbstractTreeViewItem &item = reinterpret_cast<const AbstractTreeViewItem &>(*item_); - return TreeViewItemAPIWrapper::drop_handle(*C, item, *drags); -} - -bool UI_tree_view_item_can_rename(const uiTreeViewItemHandle *item_handle) -{ - const AbstractTreeViewItem &item = reinterpret_cast<const AbstractTreeViewItem &>(*item_handle); - return TreeViewItemAPIWrapper::can_rename(item); -} - -void UI_tree_view_item_begin_rename(uiTreeViewItemHandle *item_handle) -{ - AbstractTreeViewItem &item = reinterpret_cast<AbstractTreeViewItem &>(*item_handle); - item.begin_renaming(); -} - -void UI_tree_view_item_context_menu_build(bContext *C, - const uiTreeViewItemHandle *item_handle, - uiLayout *column) -{ - const AbstractTreeViewItem &item = reinterpret_cast<const AbstractTreeViewItem &>(*item_handle); - item.build_context_menu(*C, *column); -} diff --git a/source/blender/editors/space_file/asset_catalog_tree_view.cc b/source/blender/editors/space_file/asset_catalog_tree_view.cc index 87595ecdb88..1829f19bfd6 100644 --- a/source/blender/editors/space_file/asset_catalog_tree_view.cc +++ b/source/blender/editors/space_file/asset_catalog_tree_view.cc @@ -86,12 +86,12 @@ class AssetCatalogTreeViewItem : public ui::BasicTreeViewItem { bool rename(StringRefNull new_name) override; /** Add drag support for catalog items. */ - std::unique_ptr<ui::AbstractTreeViewItemDragController> create_drag_controller() const override; + std::unique_ptr<ui::AbstractViewItemDragController> create_drag_controller() const override; /** Add dropping support for catalog items. */ - std::unique_ptr<ui::AbstractTreeViewItemDropController> create_drop_controller() const override; + std::unique_ptr<ui::AbstractViewItemDropController> create_drop_controller() const override; }; -class AssetCatalogDragController : public ui::AbstractTreeViewItemDragController { +class AssetCatalogDragController : public ui::AbstractViewItemDragController { AssetCatalogTreeItem &catalog_item_; public: @@ -103,7 +103,7 @@ class AssetCatalogDragController : public ui::AbstractTreeViewItemDragController void on_drag_start() override; }; -class AssetCatalogDropController : public ui::AbstractTreeViewItemDropController { +class AssetCatalogDropController : public ui::AbstractViewItemDropController { AssetCatalogTreeItem &catalog_item_; public: @@ -142,7 +142,7 @@ class AssetCatalogTreeViewAllItem : public ui::BasicTreeViewItem { void build_row(uiLayout &row) override; - struct DropController : public ui::AbstractTreeViewItemDropController { + struct DropController : public ui::AbstractViewItemDropController { DropController(AssetCatalogTreeView &tree_view); bool can_drop(const wmDrag &drag, const char **r_disabled_hint) const override; @@ -150,13 +150,13 @@ class AssetCatalogTreeViewAllItem : public ui::BasicTreeViewItem { bool on_drop(struct bContext *C, const wmDrag &drag) override; }; - std::unique_ptr<ui::AbstractTreeViewItemDropController> create_drop_controller() const override; + std::unique_ptr<ui::AbstractViewItemDropController> create_drop_controller() const override; }; class AssetCatalogTreeViewUnassignedItem : public ui::BasicTreeViewItem { using BasicTreeViewItem::BasicTreeViewItem; - struct DropController : public ui::AbstractTreeViewItemDropController { + struct DropController : public ui::AbstractViewItemDropController { DropController(AssetCatalogTreeView &tree_view); bool can_drop(const wmDrag &drag, const char **r_disabled_hint) const override; @@ -164,7 +164,7 @@ class AssetCatalogTreeViewUnassignedItem : public ui::BasicTreeViewItem { bool on_drop(struct bContext *C, const wmDrag &drag) override; }; - std::unique_ptr<ui::AbstractTreeViewItemDropController> create_drop_controller() const override; + std::unique_ptr<ui::AbstractViewItemDropController> create_drop_controller() const override; }; /* ---------------------------------------------------------------------- */ @@ -272,11 +272,11 @@ void AssetCatalogTreeViewItem::build_row(uiLayout &row) return; } - uiButTreeRow *tree_row_but = tree_row_button(); + uiButViewItem *view_item_but = view_item_button(); PointerRNA *props; props = UI_but_extra_operator_icon_add( - (uiBut *)tree_row_but, "ASSET_OT_catalog_new", WM_OP_INVOKE_DEFAULT, ICON_ADD); + (uiBut *)view_item_but, "ASSET_OT_catalog_new", WM_OP_INVOKE_DEFAULT, ICON_ADD); RNA_string_set(props, "parent_path", catalog_item_.catalog_path().c_str()); } @@ -305,7 +305,7 @@ void AssetCatalogTreeViewItem::build_context_menu(bContext &C, uiLayout &column) 0, &props); RNA_string_set(&props, "catalog_id", catalog_id_str_buffer); - uiItemO(&column, "Rename", ICON_NONE, "UI_OT_tree_view_item_rename"); + uiItemO(&column, "Rename", ICON_NONE, "UI_OT_view_item_rename"); /* Doesn't actually exist right now, but could be defined in Python. Reason that this isn't done * in Python yet is that catalogs are not exposed in BPY, and we'd somehow pass the clicked on @@ -333,14 +333,14 @@ bool AssetCatalogTreeViewItem::rename(StringRefNull new_name) return true; } -std::unique_ptr<ui::AbstractTreeViewItemDropController> AssetCatalogTreeViewItem:: +std::unique_ptr<ui::AbstractViewItemDropController> AssetCatalogTreeViewItem:: create_drop_controller() const { return std::make_unique<AssetCatalogDropController>( static_cast<AssetCatalogTreeView &>(get_tree_view()), catalog_item_); } -std::unique_ptr<ui::AbstractTreeViewItemDragController> AssetCatalogTreeViewItem:: +std::unique_ptr<ui::AbstractViewItemDragController> AssetCatalogTreeViewItem:: create_drag_controller() const { return std::make_unique<AssetCatalogDragController>( @@ -351,7 +351,7 @@ std::unique_ptr<ui::AbstractTreeViewItemDragController> AssetCatalogTreeViewItem AssetCatalogDropController::AssetCatalogDropController(AssetCatalogTreeView &tree_view, AssetCatalogTreeItem &catalog_item) - : ui::AbstractTreeViewItemDropController(tree_view), catalog_item_(catalog_item) + : ui::AbstractViewItemDropController(tree_view), catalog_item_(catalog_item) { } @@ -422,10 +422,10 @@ bool AssetCatalogDropController::on_drop(struct bContext *C, const wmDrag &drag) { if (drag.type == WM_DRAG_ASSET_CATALOG) { return drop_asset_catalog_into_catalog( - drag, tree_view<AssetCatalogTreeView>(), catalog_item_.get_catalog_id()); + drag, get_view<AssetCatalogTreeView>(), catalog_item_.get_catalog_id()); } return drop_assets_into_catalog(C, - tree_view<AssetCatalogTreeView>(), + get_view<AssetCatalogTreeView>(), drag, catalog_item_.get_catalog_id(), catalog_item_.get_simple_name()); @@ -512,14 +512,14 @@ bool AssetCatalogDropController::has_droppable_asset(const wmDrag &drag, ::AssetLibrary &AssetCatalogDropController::get_asset_library() const { - return *tree_view<AssetCatalogTreeView>().asset_library_; + return *get_view<AssetCatalogTreeView>().asset_library_; } /* ---------------------------------------------------------------------- */ AssetCatalogDragController::AssetCatalogDragController(AssetCatalogTreeView &tree_view, AssetCatalogTreeItem &catalog_item) - : ui::AbstractTreeViewItemDragController(tree_view), catalog_item_(catalog_item) + : ui::AbstractViewItemDragController(tree_view), catalog_item_(catalog_item) { } @@ -538,7 +538,7 @@ void *AssetCatalogDragController::create_drag_data() const void AssetCatalogDragController::on_drag_start() { - AssetCatalogTreeView &tree_view_ = tree_view<AssetCatalogTreeView>(); + AssetCatalogTreeView &tree_view_ = get_view<AssetCatalogTreeView>(); tree_view_.activate_catalog_by_id(catalog_item_.get_catalog_id()); } @@ -551,15 +551,15 @@ void AssetCatalogTreeViewAllItem::build_row(uiLayout &row) PointerRNA *props; UI_but_extra_operator_icon_add( - (uiBut *)tree_row_button(), "ASSET_OT_catalogs_save", WM_OP_INVOKE_DEFAULT, ICON_FILE_TICK); + (uiBut *)view_item_button(), "ASSET_OT_catalogs_save", WM_OP_INVOKE_DEFAULT, ICON_FILE_TICK); props = UI_but_extra_operator_icon_add( - (uiBut *)tree_row_button(), "ASSET_OT_catalog_new", WM_OP_INVOKE_DEFAULT, ICON_ADD); + (uiBut *)view_item_button(), "ASSET_OT_catalog_new", WM_OP_INVOKE_DEFAULT, ICON_ADD); /* No parent path to use the root level. */ RNA_string_set(props, "parent_path", nullptr); } -std::unique_ptr<ui::AbstractTreeViewItemDropController> AssetCatalogTreeViewAllItem:: +std::unique_ptr<ui::AbstractViewItemDropController> AssetCatalogTreeViewAllItem:: create_drop_controller() const { return std::make_unique<AssetCatalogTreeViewAllItem::DropController>( @@ -567,7 +567,7 @@ std::unique_ptr<ui::AbstractTreeViewItemDropController> AssetCatalogTreeViewAllI } AssetCatalogTreeViewAllItem::DropController::DropController(AssetCatalogTreeView &tree_view) - : ui::AbstractTreeViewItemDropController(tree_view) + : ui::AbstractViewItemDropController(tree_view) { } @@ -579,7 +579,7 @@ bool AssetCatalogTreeViewAllItem::DropController::can_drop(const wmDrag &drag, } const AssetCatalog *drag_catalog = AssetCatalogDropController::get_drag_catalog( - drag, *tree_view<AssetCatalogTreeView>().asset_library_); + drag, *get_view<AssetCatalogTreeView>().asset_library_); if (drag_catalog->path.parent() == "") { *r_disabled_hint = "Catalog is already placed at the highest level"; return false; @@ -592,7 +592,7 @@ std::string AssetCatalogTreeViewAllItem::DropController::drop_tooltip(const wmDr { BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG); const AssetCatalog *drag_catalog = AssetCatalogDropController::get_drag_catalog( - drag, *tree_view<AssetCatalogTreeView>().asset_library_); + drag, *get_view<AssetCatalogTreeView>().asset_library_); return std::string(TIP_("Move Catalog")) + " '" + drag_catalog->path.name() + "' " + TIP_("to the top level of the tree"); @@ -604,14 +604,14 @@ bool AssetCatalogTreeViewAllItem::DropController::on_drop(struct bContext *UNUSE BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG); return AssetCatalogDropController::drop_asset_catalog_into_catalog( drag, - tree_view<AssetCatalogTreeView>(), + get_view<AssetCatalogTreeView>(), /* No value to drop into the root level. */ std::nullopt); } /* ---------------------------------------------------------------------- */ -std::unique_ptr<ui::AbstractTreeViewItemDropController> AssetCatalogTreeViewUnassignedItem:: +std::unique_ptr<ui::AbstractViewItemDropController> AssetCatalogTreeViewUnassignedItem:: create_drop_controller() const { return std::make_unique<AssetCatalogTreeViewUnassignedItem::DropController>( @@ -619,7 +619,7 @@ std::unique_ptr<ui::AbstractTreeViewItemDropController> AssetCatalogTreeViewUnas } AssetCatalogTreeViewUnassignedItem::DropController::DropController(AssetCatalogTreeView &tree_view) - : ui::AbstractTreeViewItemDropController(tree_view) + : ui::AbstractViewItemDropController(tree_view) { } @@ -647,7 +647,7 @@ bool AssetCatalogTreeViewUnassignedItem::DropController::on_drop(struct bContext { /* Assign to nil catalog ID. */ return AssetCatalogDropController::drop_assets_into_catalog( - C, tree_view<AssetCatalogTreeView>(), drag, CatalogID{}); + C, get_view<AssetCatalogTreeView>(), drag, CatalogID{}); } } // namespace blender::ed::asset_browser diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc index aa9b867264a..146b6091bde 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc @@ -145,7 +145,7 @@ void GeometryDataSetTreeViewItem::build_row(uiLayout &row) * to the right side of the number, which it didn't have with the button. */ char element_count[7]; BLI_str_format_decimal_unit(element_count, *count); - UI_but_hint_drawstr_set((uiBut *)this->tree_row_button(), element_count); + UI_but_hint_drawstr_set((uiBut *)this->view_item_button(), element_count); } } |