2023-08-16 00:20:26 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
2023-05-31 16:19:06 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2021-09-23 18:56:29 +02:00
|
|
|
|
|
|
|
|
/** \file
|
|
|
|
|
* \ingroup editorui
|
2021-10-06 13:06:20 +02:00
|
|
|
*
|
2021-12-09 12:07:34 +01:00
|
|
|
* API for simple creation of tree UIs supporting typically needed features.
|
2024-01-18 16:10:52 +01:00
|
|
|
* https://developer.blender.org/docs/features/interface/views/tree_views/
|
2021-09-23 18:56:29 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
2021-09-23 12:33:27 -06:00
|
|
|
#include <functional>
|
2021-09-23 18:56:29 +02:00
|
|
|
#include <memory>
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
#include "BLI_function_ref.hh"
|
UI: Basic tree-view drag & drop reordering and inserting support
No user visible changes expected, these are just the internal API preparations.
Modifies the Drop API for views so that tree-views can choose to insert items
before, after and into other items.
Note: While there is support for drag-tooltips that can explain how an item
will be inserted, there is no drawing yet like in the Outliner, that indicates
if an item is inserted before, after or into. There is some work on that but
that can be done separately.
Changes:
- Removes `AbstractViewDropTarget` that was shared between tree- and
grid-views, and adds `AbstractTreeViewDropTarget` and
`AbstractGridViewDropTarget`. The tree-view needs specialized handling now,
and although they could share some code still, it's not worth having another
level of inheritance.
- Modifies the drop-target API to use `DragInfo` which contains more info about
the dragging operation than just the `wmDrag`.
- Adds `determine_drop_location()` to the `DropTargetInterface` which drop
targets can use to determine when dropping means inserting before, after or
into.
- Store the block and region in the view. This is needed unfortunately but
shouldn't be an issue since the tree view is recreated on redraws, together
with the block.
- Various smaller tweaks and additions to views as needed.
TODO (outside scope of this change): Increase row height so there is no gap
between tree view items, but keep things visually the same otherwise. This
reduces flickering while dragging.
Pull Request: https://projects.blender.org/blender/blender/pulls/109825
2023-07-11 14:30:26 +02:00
|
|
|
#include "BLI_math_vector_types.hh"
|
2021-09-23 18:56:29 +02:00
|
|
|
#include "BLI_vector.hh"
|
|
|
|
|
|
UI: Add AbstractView base class for views, unify reconstruction in there
No user visible changes expected.
There's plenty of duplicated code in the grid and the tree view, and I expect
this to become more. This starts the process of unifying these parts, which
should also make it easier to add new views. Complexity in the view classes is
reduced, and some type shenanigans for C compatibility and general view
management can be removed, since there is now a common base type.
For the start this ports some of the view reconstruction, where the view and
its items are compared to the version of itself in the previous redraw, so that
state (highlighted, active, renaming, collapsed, ...) can be preserved.
Notifier listening is also ported.
2022-07-02 21:49:21 +02:00
|
|
|
#include "UI_abstract_view.hh"
|
2023-08-05 02:57:52 +02:00
|
|
|
#include "UI_resources.hh"
|
2021-09-23 18:56:29 +02:00
|
|
|
|
2021-09-30 16:26:56 +02:00
|
|
|
struct bContext;
|
2021-09-23 18:56:29 +02:00
|
|
|
struct uiBlock;
|
|
|
|
|
struct uiBut;
|
|
|
|
|
struct uiLayout;
|
|
|
|
|
|
|
|
|
|
namespace blender::ui {
|
|
|
|
|
|
|
|
|
|
class AbstractTreeView;
|
|
|
|
|
class AbstractTreeViewItem;
|
UI: Basic tree-view drag & drop reordering and inserting support
No user visible changes expected, these are just the internal API preparations.
Modifies the Drop API for views so that tree-views can choose to insert items
before, after and into other items.
Note: While there is support for drag-tooltips that can explain how an item
will be inserted, there is no drawing yet like in the Outliner, that indicates
if an item is inserted before, after or into. There is some work on that but
that can be done separately.
Changes:
- Removes `AbstractViewDropTarget` that was shared between tree- and
grid-views, and adds `AbstractTreeViewDropTarget` and
`AbstractGridViewDropTarget`. The tree-view needs specialized handling now,
and although they could share some code still, it's not worth having another
level of inheritance.
- Modifies the drop-target API to use `DragInfo` which contains more info about
the dragging operation than just the `wmDrag`.
- Adds `determine_drop_location()` to the `DropTargetInterface` which drop
targets can use to determine when dropping means inserting before, after or
into.
- Store the block and region in the view. This is needed unfortunately but
shouldn't be an issue since the tree view is recreated on redraws, together
with the block.
- Various smaller tweaks and additions to views as needed.
TODO (outside scope of this change): Increase row height so there is no gap
between tree view items, but keep things visually the same otherwise. This
reduces flickering while dragging.
Pull Request: https://projects.blender.org/blender/blender/pulls/109825
2023-07-11 14:30:26 +02:00
|
|
|
class TreeViewItemDropTarget;
|
2021-09-23 18:56:29 +02:00
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
|
/** \name Tree-View Item Container
|
2021-12-09 12:07:34 +01:00
|
|
|
*
|
|
|
|
|
* Base class for tree-view and tree-view items, so both can contain children.
|
2021-09-23 18:56:29 +02:00
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
/**
|
2021-12-09 12:07:34 +01:00
|
|
|
* Both the tree-view (as the root of the tree) and the items can have children. This is the base
|
|
|
|
|
* class for both, to store and manage child items. Children are owned by their parent container
|
|
|
|
|
* (tree-view or item).
|
2021-09-23 18:56:29 +02:00
|
|
|
*
|
2021-12-09 12:07:34 +01:00
|
|
|
* That means this type can be used whenever either an #AbstractTreeView or an
|
|
|
|
|
* #AbstractTreeViewItem is needed, but the #TreeViewOrItem alias is a better name to use then.
|
2021-09-23 18:56:29 +02:00
|
|
|
*/
|
|
|
|
|
class TreeViewItemContainer {
|
|
|
|
|
friend class AbstractTreeView;
|
|
|
|
|
friend class AbstractTreeViewItem;
|
|
|
|
|
|
|
|
|
|
/* Private constructor, so only the friends above can create this! */
|
|
|
|
|
TreeViewItemContainer() = default;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
Vector<std::unique_ptr<AbstractTreeViewItem>> children_;
|
|
|
|
|
/** Adding the first item to the root will set this, then it's passed on to all children. */
|
|
|
|
|
TreeViewItemContainer *root_ = nullptr;
|
|
|
|
|
/** Pointer back to the owning item. */
|
|
|
|
|
AbstractTreeViewItem *parent_ = nullptr;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
enum class IterOptions {
|
|
|
|
|
None = 0,
|
|
|
|
|
SkipCollapsed = 1 << 0,
|
2023-06-12 11:41:00 +02:00
|
|
|
SkipFiltered = 1 << 1,
|
2021-09-23 18:56:29 +02:00
|
|
|
|
|
|
|
|
/* Keep ENUM_OPERATORS() below updated! */
|
|
|
|
|
};
|
|
|
|
|
using ItemIterFn = FunctionRef<void(AbstractTreeViewItem &)>;
|
|
|
|
|
|
|
|
|
|
/**
|
2021-10-06 13:06:20 +02:00
|
|
|
* Convenience wrapper constructing the item by forwarding given arguments to the constructor of
|
|
|
|
|
* the type (\a ItemT).
|
|
|
|
|
*
|
|
|
|
|
* E.g. if your tree-item type has the following constructor:
|
|
|
|
|
* \code{.cpp}
|
|
|
|
|
* MyTreeItem(std::string str, int i);
|
|
|
|
|
* \endcode
|
|
|
|
|
* You can add an item like this:
|
|
|
|
|
* \code
|
|
|
|
|
* add_tree_item<MyTreeItem>("blabla", 42);
|
|
|
|
|
* \endcode
|
|
|
|
|
*/
|
|
|
|
|
template<class ItemT, typename... Args> inline ItemT &add_tree_item(Args &&...args);
|
|
|
|
|
/**
|
|
|
|
|
* Add an already constructed tree item to this parent. Ownership is moved to it.
|
|
|
|
|
* All tree items must be added through this, it handles important invariants!
|
2021-09-23 18:56:29 +02:00
|
|
|
*/
|
|
|
|
|
AbstractTreeViewItem &add_tree_item(std::unique_ptr<AbstractTreeViewItem> item);
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
void foreach_item_recursive(ItemIterFn iter_fn, IterOptions options = IterOptions::None) const;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ENUM_OPERATORS(TreeViewItemContainer::IterOptions,
|
|
|
|
|
TreeViewItemContainer::IterOptions::SkipCollapsed);
|
|
|
|
|
|
2023-11-30 14:15:11 +11:00
|
|
|
/**
|
|
|
|
|
* The container class is the base for both the tree-view and the items. This alias gives it a
|
2021-12-09 12:07:34 +01:00
|
|
|
* clearer name for handles that accept both. Use whenever something wants to act on child-items,
|
2023-11-30 14:15:11 +11:00
|
|
|
* irrespective of if they are stored at root level or as children of some other item.
|
|
|
|
|
*/
|
2021-12-09 12:07:34 +01:00
|
|
|
using TreeViewOrItem = TreeViewItemContainer;
|
2021-09-23 18:56:29 +02:00
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
|
/** \name Tree-View Base Class
|
|
|
|
|
* \{ */
|
|
|
|
|
|
UI: Add AbstractView base class for views, unify reconstruction in there
No user visible changes expected.
There's plenty of duplicated code in the grid and the tree view, and I expect
this to become more. This starts the process of unifying these parts, which
should also make it easier to add new views. Complexity in the view classes is
reduced, and some type shenanigans for C compatibility and general view
management can be removed, since there is now a common base type.
For the start this ports some of the view reconstruction, where the view and
its items are compared to the version of itself in the previous redraw, so that
state (highlighted, active, renaming, collapsed, ...) can be preserved.
Notifier listening is also ported.
2022-07-02 21:49:21 +02:00
|
|
|
class AbstractTreeView : public AbstractView, public TreeViewItemContainer {
|
2023-03-28 12:33:35 +02:00
|
|
|
int min_rows_ = 0;
|
|
|
|
|
|
2021-12-09 12:07:34 +01:00
|
|
|
friend class AbstractTreeViewItem;
|
|
|
|
|
friend class TreeViewBuilder;
|
UI: Basic tree-view drag & drop reordering and inserting support
No user visible changes expected, these are just the internal API preparations.
Modifies the Drop API for views so that tree-views can choose to insert items
before, after and into other items.
Note: While there is support for drag-tooltips that can explain how an item
will be inserted, there is no drawing yet like in the Outliner, that indicates
if an item is inserted before, after or into. There is some work on that but
that can be done separately.
Changes:
- Removes `AbstractViewDropTarget` that was shared between tree- and
grid-views, and adds `AbstractTreeViewDropTarget` and
`AbstractGridViewDropTarget`. The tree-view needs specialized handling now,
and although they could share some code still, it's not worth having another
level of inheritance.
- Modifies the drop-target API to use `DragInfo` which contains more info about
the dragging operation than just the `wmDrag`.
- Adds `determine_drop_location()` to the `DropTargetInterface` which drop
targets can use to determine when dropping means inserting before, after or
into.
- Store the block and region in the view. This is needed unfortunately but
shouldn't be an issue since the tree view is recreated on redraws, together
with the block.
- Various smaller tweaks and additions to views as needed.
TODO (outside scope of this change): Increase row height so there is no gap
between tree view items, but keep things visually the same otherwise. This
reduces flickering while dragging.
Pull Request: https://projects.blender.org/blender/blender/pulls/109825
2023-07-11 14:30:26 +02:00
|
|
|
friend class TreeViewItemDropTarget;
|
2021-10-06 14:18:12 +02:00
|
|
|
|
2021-09-23 18:56:29 +02:00
|
|
|
public:
|
2023-07-26 15:08:21 +02:00
|
|
|
/* virtual */ ~AbstractTreeView() override = default;
|
2021-09-23 18:56:29 +02:00
|
|
|
|
2023-07-06 17:00:44 +02:00
|
|
|
void draw_overlays(const ARegion ®ion) const override;
|
|
|
|
|
|
2021-09-23 18:56:29 +02:00
|
|
|
void foreach_item(ItemIterFn iter_fn, IterOptions options = IterOptions::None) const;
|
|
|
|
|
|
UI: Basic tree-view drag & drop reordering and inserting support
No user visible changes expected, these are just the internal API preparations.
Modifies the Drop API for views so that tree-views can choose to insert items
before, after and into other items.
Note: While there is support for drag-tooltips that can explain how an item
will be inserted, there is no drawing yet like in the Outliner, that indicates
if an item is inserted before, after or into. There is some work on that but
that can be done separately.
Changes:
- Removes `AbstractViewDropTarget` that was shared between tree- and
grid-views, and adds `AbstractTreeViewDropTarget` and
`AbstractGridViewDropTarget`. The tree-view needs specialized handling now,
and although they could share some code still, it's not worth having another
level of inheritance.
- Modifies the drop-target API to use `DragInfo` which contains more info about
the dragging operation than just the `wmDrag`.
- Adds `determine_drop_location()` to the `DropTargetInterface` which drop
targets can use to determine when dropping means inserting before, after or
into.
- Store the block and region in the view. This is needed unfortunately but
shouldn't be an issue since the tree view is recreated on redraws, together
with the block.
- Various smaller tweaks and additions to views as needed.
TODO (outside scope of this change): Increase row height so there is no gap
between tree view items, but keep things visually the same otherwise. This
reduces flickering while dragging.
Pull Request: https://projects.blender.org/blender/blender/pulls/109825
2023-07-11 14:30:26 +02:00
|
|
|
/**
|
|
|
|
|
* \param xy: The mouse coordinates in window space.
|
|
|
|
|
*/
|
|
|
|
|
AbstractTreeViewItem *find_hovered(const ARegion ®ion, const int2 &xy);
|
|
|
|
|
|
2023-03-28 12:33:35 +02:00
|
|
|
/** Visual feature: Define a number of item rows the view will always show at minimum. If there
|
|
|
|
|
* are fewer items, empty dummy items will be added. These contribute to the view bounds, so the
|
|
|
|
|
* drop target of the view includes them, but they are not interactive (e.g. no mouse-hover
|
|
|
|
|
* highlight). */
|
|
|
|
|
void set_min_rows(int min_rows);
|
|
|
|
|
|
2021-12-09 12:07:34 +01:00
|
|
|
protected:
|
|
|
|
|
virtual void build_tree() = 0;
|
|
|
|
|
|
2021-09-23 18:56:29 +02:00
|
|
|
private:
|
2023-07-26 16:33:28 +02:00
|
|
|
void foreach_view_item(FunctionRef<void(AbstractViewItem &)> iter_fn) const final;
|
UI: Add AbstractView base class for views, unify reconstruction in there
No user visible changes expected.
There's plenty of duplicated code in the grid and the tree view, and I expect
this to become more. This starts the process of unifying these parts, which
should also make it easier to add new views. Complexity in the view classes is
reduced, and some type shenanigans for C compatibility and general view
management can be removed, since there is now a common base type.
For the start this ports some of the view reconstruction, where the view and
its items are compared to the version of itself in the previous redraw, so that
state (highlighted, active, renaming, collapsed, ...) can be preserved.
Notifier listening is also ported.
2022-07-02 21:49:21 +02:00
|
|
|
void update_children_from_old(const AbstractView &old_view) override;
|
2021-12-09 12:07:34 +01:00
|
|
|
static void update_children_from_old_recursive(const TreeViewOrItem &new_items,
|
|
|
|
|
const TreeViewOrItem &old_items);
|
2021-09-23 18:56:29 +02:00
|
|
|
static AbstractTreeViewItem *find_matching_child(const AbstractTreeViewItem &lookup_item,
|
2021-12-09 12:07:34 +01:00
|
|
|
const TreeViewOrItem &items);
|
2021-10-06 16:29:10 +02:00
|
|
|
|
2023-07-06 17:00:44 +02:00
|
|
|
void draw_hierarchy_lines(const ARegion ®ion) const;
|
|
|
|
|
void draw_hierarchy_lines_recursive(const ARegion ®ion,
|
|
|
|
|
const TreeViewOrItem &parent,
|
2024-01-23 20:39:15 +01:00
|
|
|
const uint pos,
|
|
|
|
|
const float aspect) const;
|
|
|
|
|
|
2023-07-06 17:00:44 +02:00
|
|
|
AbstractTreeViewItem *find_last_visible_descendant(const AbstractTreeViewItem &parent) const;
|
2021-09-23 18:56:29 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
|
/** \name Tree-View Item Type
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
/** \brief Abstract base class for defining a customizable tree-view item.
|
|
|
|
|
*
|
|
|
|
|
* The tree-view item defines how to build its data into a tree-row. There are implementations for
|
|
|
|
|
* common layouts, e.g. #BasicTreeViewItem.
|
|
|
|
|
* It also stores state information that needs to be persistent over redraws, like the collapsed
|
|
|
|
|
* state.
|
|
|
|
|
*/
|
2022-07-18 16:51:57 +02:00
|
|
|
class AbstractTreeViewItem : public AbstractViewItem, public TreeViewItemContainer {
|
2021-09-23 18:56:29 +02:00
|
|
|
friend class AbstractTreeView;
|
2021-10-06 14:18:12 +02:00
|
|
|
friend class TreeViewLayoutBuilder;
|
2021-12-09 12:07:34 +01:00
|
|
|
/* Higher-level API. */
|
|
|
|
|
friend class TreeViewItemAPIWrapper;
|
2021-09-23 18:56:29 +02:00
|
|
|
|
2021-10-05 16:01:01 +02:00
|
|
|
private:
|
2021-09-23 18:56:29 +02:00
|
|
|
bool is_open_ = false;
|
|
|
|
|
|
|
|
|
|
protected:
|
2022-06-16 11:29:20 +02:00
|
|
|
/** This label is used as the default way to identifying an item within its parent. */
|
2024-02-02 11:08:07 -05:00
|
|
|
std::string label_;
|
2021-09-23 18:56:29 +02:00
|
|
|
|
|
|
|
|
public:
|
2023-07-26 15:08:21 +02:00
|
|
|
/* virtual */ ~AbstractTreeViewItem() override = default;
|
2021-09-23 18:56:29 +02:00
|
|
|
|
|
|
|
|
virtual void build_row(uiLayout &row) = 0;
|
|
|
|
|
|
2023-07-26 15:08:21 +02:00
|
|
|
std::unique_ptr<DropTargetInterface> create_item_drop_target() final;
|
UI: Basic tree-view drag & drop reordering and inserting support
No user visible changes expected, these are just the internal API preparations.
Modifies the Drop API for views so that tree-views can choose to insert items
before, after and into other items.
Note: While there is support for drag-tooltips that can explain how an item
will be inserted, there is no drawing yet like in the Outliner, that indicates
if an item is inserted before, after or into. There is some work on that but
that can be done separately.
Changes:
- Removes `AbstractViewDropTarget` that was shared between tree- and
grid-views, and adds `AbstractTreeViewDropTarget` and
`AbstractGridViewDropTarget`. The tree-view needs specialized handling now,
and although they could share some code still, it's not worth having another
level of inheritance.
- Modifies the drop-target API to use `DragInfo` which contains more info about
the dragging operation than just the `wmDrag`.
- Adds `determine_drop_location()` to the `DropTargetInterface` which drop
targets can use to determine when dropping means inserting before, after or
into.
- Store the block and region in the view. This is needed unfortunately but
shouldn't be an issue since the tree view is recreated on redraws, together
with the block.
- Various smaller tweaks and additions to views as needed.
TODO (outside scope of this change): Increase row height so there is no gap
between tree view items, but keep things visually the same otherwise. This
reduces flickering while dragging.
Pull Request: https://projects.blender.org/blender/blender/pulls/109825
2023-07-11 14:30:26 +02:00
|
|
|
virtual std::unique_ptr<TreeViewItemDropTarget> create_drop_target();
|
|
|
|
|
|
2021-12-09 12:07:34 +01:00
|
|
|
AbstractTreeView &get_tree_view() const;
|
UI: Basic tree-view drag & drop reordering and inserting support
No user visible changes expected, these are just the internal API preparations.
Modifies the Drop API for views so that tree-views can choose to insert items
before, after and into other items.
Note: While there is support for drag-tooltips that can explain how an item
will be inserted, there is no drawing yet like in the Outliner, that indicates
if an item is inserted before, after or into. There is some work on that but
that can be done separately.
Changes:
- Removes `AbstractViewDropTarget` that was shared between tree- and
grid-views, and adds `AbstractTreeViewDropTarget` and
`AbstractGridViewDropTarget`. The tree-view needs specialized handling now,
and although they could share some code still, it's not worth having another
level of inheritance.
- Modifies the drop-target API to use `DragInfo` which contains more info about
the dragging operation than just the `wmDrag`.
- Adds `determine_drop_location()` to the `DropTargetInterface` which drop
targets can use to determine when dropping means inserting before, after or
into.
- Store the block and region in the view. This is needed unfortunately but
shouldn't be an issue since the tree view is recreated on redraws, together
with the block.
- Various smaller tweaks and additions to views as needed.
TODO (outside scope of this change): Increase row height so there is no gap
between tree view items, but keep things visually the same otherwise. This
reduces flickering while dragging.
Pull Request: https://projects.blender.org/blender/blender/pulls/109825
2023-07-11 14:30:26 +02:00
|
|
|
/**
|
|
|
|
|
* Calculate the view item rectangle from its view-item button, converted to window space.
|
|
|
|
|
* Returns an unset optional if there is no view item button for this item.
|
|
|
|
|
*/
|
|
|
|
|
std::optional<rctf> get_win_rect(const ARegion ®ion) const;
|
2021-12-09 12:07:34 +01:00
|
|
|
|
|
|
|
|
void begin_renaming();
|
2024-02-02 12:28:22 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Toggle the expanded/collapsed state.
|
|
|
|
|
*
|
|
|
|
|
* \note this does not call #on_collapse_change().
|
|
|
|
|
* \returns true when the collapsed state was changed, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
bool toggle_collapsed();
|
|
|
|
|
/**
|
|
|
|
|
* Expand or collapse this tree view item.
|
|
|
|
|
*
|
|
|
|
|
* \note this does not call #on_collapse_change().
|
|
|
|
|
* \returns true when the collapsed state was changed, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
virtual bool set_collapsed(bool collapsed);
|
2024-03-18 19:32:53 +01:00
|
|
|
/**
|
2024-03-21 10:01:43 +11:00
|
|
|
* Make this item be uncollapsed on first draw (may later be overridden by
|
2024-03-18 19:32:53 +01:00
|
|
|
* #should_be_collapsed()). Must only be done during tree building.
|
|
|
|
|
*
|
|
|
|
|
* \note this does not call #on_collapse_change() or #set_collapsed() overrides.
|
|
|
|
|
*/
|
|
|
|
|
void uncollapse_by_default();
|
2024-02-02 12:28:22 +01:00
|
|
|
|
2021-12-09 12:07:34 +01:00
|
|
|
/**
|
|
|
|
|
* Requires the tree to have completed reconstruction, see #is_reconstructed(). Otherwise we
|
|
|
|
|
* can't be sure about the item state.
|
|
|
|
|
*/
|
|
|
|
|
bool is_collapsed() const;
|
UI: Basic tree-view drag & drop reordering and inserting support
No user visible changes expected, these are just the internal API preparations.
Modifies the Drop API for views so that tree-views can choose to insert items
before, after and into other items.
Note: While there is support for drag-tooltips that can explain how an item
will be inserted, there is no drawing yet like in the Outliner, that indicates
if an item is inserted before, after or into. There is some work on that but
that can be done separately.
Changes:
- Removes `AbstractViewDropTarget` that was shared between tree- and
grid-views, and adds `AbstractTreeViewDropTarget` and
`AbstractGridViewDropTarget`. The tree-view needs specialized handling now,
and although they could share some code still, it's not worth having another
level of inheritance.
- Modifies the drop-target API to use `DragInfo` which contains more info about
the dragging operation than just the `wmDrag`.
- Adds `determine_drop_location()` to the `DropTargetInterface` which drop
targets can use to determine when dropping means inserting before, after or
into.
- Store the block and region in the view. This is needed unfortunately but
shouldn't be an issue since the tree view is recreated on redraws, together
with the block.
- Various smaller tweaks and additions to views as needed.
TODO (outside scope of this change): Increase row height so there is no gap
between tree view items, but keep things visually the same otherwise. This
reduces flickering while dragging.
Pull Request: https://projects.blender.org/blender/blender/pulls/109825
2023-07-11 14:30:26 +02:00
|
|
|
bool is_collapsible() const;
|
2021-12-09 12:07:34 +01:00
|
|
|
|
2024-02-02 12:28:22 +01:00
|
|
|
/**
|
|
|
|
|
* Called when the view changes an item's state from expanded to collapsed, or vice versa. Will
|
|
|
|
|
* only be called if the state change is triggered through the view, not through external
|
|
|
|
|
* changes. E.g. a click on an item calls it, a change in the value returned by
|
|
|
|
|
* #should_be_collapsed() to reflect an external state change does not.
|
|
|
|
|
*/
|
|
|
|
|
virtual void on_collapse_change(bContext &C, bool is_collapsed);
|
|
|
|
|
/**
|
|
|
|
|
* If the result is not empty, it controls whether the item should be collapsed or not, usually
|
|
|
|
|
* depending on the data that the view represents.
|
|
|
|
|
*/
|
|
|
|
|
virtual std::optional<bool> should_be_collapsed() const;
|
|
|
|
|
|
2021-12-09 12:07:34 +01:00
|
|
|
protected:
|
UI: Port view item features to base class, merge view item button types
No user visible changes expected.
Merges the tree row and grid tile button types, which were mostly doing
the same things. The idea is that there is a button type for
highlighting, as well as supporting general view item features (e.g.
renaming, drag/drop, etc.). So instead there is a view item button type
now. Also ports view item features like renaming, custom context menus,
drag controllers and drop controllers to `ui::AbstractViewItem` (the new
base class for all view items).
This should be quite an improvement because:
- Merges code that was duplicated over view items.
- Mentioned features (renaming, drag & drop, ...) are much easier to
implement in new view types now. Most of it comes "for free".
- Further features will immediately become availalbe to all views (e.g.
selection).
- Simplifies APIs, there don't have to be functions for individual view
item types anymore.
- View item classes are split and thus less overwhelming visually.
- View item buttons now share all code (drawing, handling, etc.)
- We're soon running out of available button types, this commit merges
two into one.
I was hoping I could do this in multiple smaller commits, but things
were quite intertwined so that would've taken quite some effort.
2022-07-19 16:14:42 +02:00
|
|
|
/** See AbstractViewItem::get_rename_string(). */
|
2023-07-26 15:08:21 +02:00
|
|
|
/* virtual */ StringRef get_rename_string() const override;
|
UI: Port view item features to base class, merge view item button types
No user visible changes expected.
Merges the tree row and grid tile button types, which were mostly doing
the same things. The idea is that there is a button type for
highlighting, as well as supporting general view item features (e.g.
renaming, drag/drop, etc.). So instead there is a view item button type
now. Also ports view item features like renaming, custom context menus,
drag controllers and drop controllers to `ui::AbstractViewItem` (the new
base class for all view items).
This should be quite an improvement because:
- Merges code that was duplicated over view items.
- Mentioned features (renaming, drag & drop, ...) are much easier to
implement in new view types now. Most of it comes "for free".
- Further features will immediately become availalbe to all views (e.g.
selection).
- Simplifies APIs, there don't have to be functions for individual view
item types anymore.
- View item classes are split and thus less overwhelming visually.
- View item buttons now share all code (drawing, handling, etc.)
- We're soon running out of available button types, this commit merges
two into one.
I was hoping I could do this in multiple smaller commits, but things
were quite intertwined so that would've taken quite some effort.
2022-07-19 16:14:42 +02:00
|
|
|
/** See AbstractViewItem::rename(). */
|
2023-08-25 16:00:05 +02:00
|
|
|
/* virtual */ bool rename(const bContext &C, StringRefNull new_name) override;
|
2021-09-30 16:26:56 +02:00
|
|
|
|
2021-12-09 12:07:34 +01:00
|
|
|
/**
|
|
|
|
|
* Return whether the item can be collapsed. Used to disable collapsing for items with children.
|
2023-07-11 15:32:02 +02:00
|
|
|
* The default implementation returns true.
|
2021-12-09 12:07:34 +01:00
|
|
|
*/
|
|
|
|
|
virtual bool supports_collapsing() const;
|
|
|
|
|
|
2024-02-02 12:28:22 +01:00
|
|
|
/**
|
|
|
|
|
* Toggle the collapsed/expanded state, and call on_collapse_change() if it changed.
|
|
|
|
|
*/
|
|
|
|
|
void toggle_collapsed_from_view(bContext &C);
|
|
|
|
|
|
|
|
|
|
void change_state_delayed() override;
|
|
|
|
|
|
UI: Port view item features to base class, merge view item button types
No user visible changes expected.
Merges the tree row and grid tile button types, which were mostly doing
the same things. The idea is that there is a button type for
highlighting, as well as supporting general view item features (e.g.
renaming, drag/drop, etc.). So instead there is a view item button type
now. Also ports view item features like renaming, custom context menus,
drag controllers and drop controllers to `ui::AbstractViewItem` (the new
base class for all view items).
This should be quite an improvement because:
- Merges code that was duplicated over view items.
- Mentioned features (renaming, drag & drop, ...) are much easier to
implement in new view types now. Most of it comes "for free".
- Further features will immediately become availalbe to all views (e.g.
selection).
- Simplifies APIs, there don't have to be functions for individual view
item types anymore.
- View item classes are split and thus less overwhelming visually.
- View item buttons now share all code (drawing, handling, etc.)
- We're soon running out of available button types, this commit merges
two into one.
I was hoping I could do this in multiple smaller commits, but things
were quite intertwined so that would've taken quite some effort.
2022-07-19 16:14:42 +02:00
|
|
|
/** See #AbstractViewItem::matches(). */
|
2023-07-26 15:08:21 +02:00
|
|
|
/* virtual */ bool matches(const AbstractViewItem &other) const override;
|
UI: Port view item features to base class, merge view item button types
No user visible changes expected.
Merges the tree row and grid tile button types, which were mostly doing
the same things. The idea is that there is a button type for
highlighting, as well as supporting general view item features (e.g.
renaming, drag/drop, etc.). So instead there is a view item button type
now. Also ports view item features like renaming, custom context menus,
drag controllers and drop controllers to `ui::AbstractViewItem` (the new
base class for all view items).
This should be quite an improvement because:
- Merges code that was duplicated over view items.
- Mentioned features (renaming, drag & drop, ...) are much easier to
implement in new view types now. Most of it comes "for free".
- Further features will immediately become availalbe to all views (e.g.
selection).
- Simplifies APIs, there don't have to be functions for individual view
item types anymore.
- View item classes are split and thus less overwhelming visually.
- View item buttons now share all code (drawing, handling, etc.)
- We're soon running out of available button types, this commit merges
two into one.
I was hoping I could do this in multiple smaller commits, but things
were quite intertwined so that would've taken quite some effort.
2022-07-19 16:14:42 +02:00
|
|
|
|
2022-07-18 16:51:57 +02:00
|
|
|
/** See #AbstractViewItem::update_from_old(). */
|
2023-07-26 15:08:21 +02:00
|
|
|
/* virtual */ void update_from_old(const AbstractViewItem &old) override;
|
2021-12-09 12:07:34 +01:00
|
|
|
|
2021-10-06 13:06:20 +02:00
|
|
|
/**
|
|
|
|
|
* Compare this item 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.
|
2021-09-29 17:01:13 +02:00
|
|
|
* open/closed, active, etc.). Items are only matched if their parents also match.
|
2021-10-06 13:06:20 +02:00
|
|
|
* 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.
|
2021-10-24 18:51:12 +02:00
|
|
|
*
|
UI: Port view item features to base class, merge view item button types
No user visible changes expected.
Merges the tree row and grid tile button types, which were mostly doing
the same things. The idea is that there is a button type for
highlighting, as well as supporting general view item features (e.g.
renaming, drag/drop, etc.). So instead there is a view item button type
now. Also ports view item features like renaming, custom context menus,
drag controllers and drop controllers to `ui::AbstractViewItem` (the new
base class for all view items).
This should be quite an improvement because:
- Merges code that was duplicated over view items.
- Mentioned features (renaming, drag & drop, ...) are much easier to
implement in new view types now. Most of it comes "for free".
- Further features will immediately become availalbe to all views (e.g.
selection).
- Simplifies APIs, there don't have to be functions for individual view
item types anymore.
- View item classes are split and thus less overwhelming visually.
- View item buttons now share all code (drawing, handling, etc.)
- We're soon running out of available button types, this commit merges
two into one.
I was hoping I could do this in multiple smaller commits, but things
were quite intertwined so that would've taken quite some effort.
2022-07-19 16:14:42 +02:00
|
|
|
* 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.
|
2021-10-24 18:51:12 +02:00
|
|
|
*/
|
UI: Port view item features to base class, merge view item button types
No user visible changes expected.
Merges the tree row and grid tile button types, which were mostly doing
the same things. The idea is that there is a button type for
highlighting, as well as supporting general view item features (e.g.
renaming, drag/drop, etc.). So instead there is a view item button type
now. Also ports view item features like renaming, custom context menus,
drag controllers and drop controllers to `ui::AbstractViewItem` (the new
base class for all view items).
This should be quite an improvement because:
- Merges code that was duplicated over view items.
- Mentioned features (renaming, drag & drop, ...) are much easier to
implement in new view types now. Most of it comes "for free".
- Further features will immediately become availalbe to all views (e.g.
selection).
- Simplifies APIs, there don't have to be functions for individual view
item types anymore.
- View item classes are split and thus less overwhelming visually.
- View item buttons now share all code (drawing, handling, etc.)
- We're soon running out of available button types, this commit merges
two into one.
I was hoping I could do this in multiple smaller commits, but things
were quite intertwined so that would've taken quite some effort.
2022-07-19 16:14:42 +02:00
|
|
|
virtual bool matches_single(const AbstractTreeViewItem &other) const;
|
2021-10-24 18:51:12 +02:00
|
|
|
|
2021-10-06 16:29:10 +02:00
|
|
|
/**
|
|
|
|
|
* Can be called from the #AbstractTreeViewItem::build_row() implementation, but not earlier. The
|
|
|
|
|
* hovered state can't be queried reliably otherwise.
|
|
|
|
|
* Note that this does a linear lookup in the old block, so isn't too great performance-wise.
|
|
|
|
|
*/
|
|
|
|
|
bool is_hovered() const;
|
2021-10-06 14:18:12 +02:00
|
|
|
|
2021-10-04 16:17:59 +02:00
|
|
|
void ensure_parents_uncollapsed();
|
2021-10-05 16:01:01 +02:00
|
|
|
|
|
|
|
|
private:
|
2023-08-02 23:59:31 -04:00
|
|
|
static void tree_row_click_fn(bContext *, void *, void *);
|
2021-10-07 14:59:43 +02:00
|
|
|
static void collapse_chevron_click_fn(bContext *, void *but_arg1, void *);
|
2021-10-06 14:18:12 +02:00
|
|
|
|
2023-07-26 15:32:26 +02:00
|
|
|
/**
|
2023-07-26 16:33:28 +02:00
|
|
|
* Override of #AbstractViewItem::set_state_active() that also ensures the parents of this
|
|
|
|
|
* element are uncollapsed so that the item is visible.
|
2023-07-26 15:32:26 +02:00
|
|
|
*/
|
2023-07-26 16:33:28 +02:00
|
|
|
bool set_state_active() final;
|
2021-10-07 14:59:43 +02:00
|
|
|
|
2021-10-06 14:18:12 +02:00
|
|
|
void add_treerow_button(uiBlock &block);
|
2023-07-06 17:00:44 +02:00
|
|
|
int indent_width() const;
|
2021-10-07 14:59:43 +02:00
|
|
|
void add_indent(uiLayout &row) const;
|
|
|
|
|
void add_collapse_chevron(uiBlock &block) const;
|
|
|
|
|
void add_rename_button(uiLayout &row);
|
2021-10-20 11:49:33 +02:00
|
|
|
|
|
|
|
|
bool has_active_child() const;
|
2021-12-09 12:07:34 +01:00
|
|
|
int count_parents() const;
|
2021-09-23 18:56:29 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
|
/** \name Predefined Tree-View Item Types
|
|
|
|
|
*
|
|
|
|
|
* Common, Basic Tree-View Item Types.
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The most basic type, just a label with an icon.
|
|
|
|
|
*/
|
|
|
|
|
class BasicTreeViewItem : public AbstractTreeViewItem {
|
|
|
|
|
public:
|
2021-11-19 17:36:11 -05:00
|
|
|
using IsActiveFn = std::function<bool()>;
|
2023-07-26 16:47:17 +02:00
|
|
|
using ActivateFn = std::function<void(bContext &C, BasicTreeViewItem &new_active)>;
|
2021-09-23 18:56:29 +02:00
|
|
|
BIFIconID icon;
|
|
|
|
|
|
2021-10-27 12:05:23 +02:00
|
|
|
explicit BasicTreeViewItem(StringRef label, BIFIconID icon = ICON_NONE);
|
2021-09-23 18:56:29 +02:00
|
|
|
|
|
|
|
|
void build_row(uiLayout &row) override;
|
2021-10-27 12:06:31 +02:00
|
|
|
void add_label(uiLayout &layout, StringRefNull label_override = "");
|
2021-11-19 17:36:11 -05:00
|
|
|
void set_on_activate_fn(ActivateFn fn);
|
|
|
|
|
/**
|
|
|
|
|
* Set a custom callback to check if this item should be active.
|
|
|
|
|
*/
|
|
|
|
|
void set_is_active_fn(IsActiveFn fn);
|
2021-09-23 18:56:29 +02:00
|
|
|
|
|
|
|
|
protected:
|
2021-10-06 13:06:20 +02:00
|
|
|
/**
|
2023-09-01 22:57:50 -04:00
|
|
|
* Called when activating this tree view item. This way users don't have to sub-class
|
|
|
|
|
* #BasicTreeViewItem, just to implement custom activation behavior (a common thing to do).
|
2021-10-06 13:06:20 +02:00
|
|
|
*/
|
2021-09-23 18:56:29 +02:00
|
|
|
ActivateFn activate_fn_;
|
|
|
|
|
|
2021-11-19 17:36:11 -05:00
|
|
|
IsActiveFn is_active_fn_;
|
|
|
|
|
|
2021-10-05 16:01:01 +02:00
|
|
|
private:
|
2023-08-02 23:59:31 -04:00
|
|
|
static void tree_row_click_fn(bContext *C, void *arg1, void *arg2);
|
2021-10-05 16:01:01 +02:00
|
|
|
|
2021-11-19 17:36:11 -05:00
|
|
|
std::optional<bool> should_be_active() const override;
|
2023-07-26 16:47:17 +02:00
|
|
|
void on_activate(bContext &C) override;
|
2021-09-23 18:56:29 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
UI: Basic tree-view drag & drop reordering and inserting support
No user visible changes expected, these are just the internal API preparations.
Modifies the Drop API for views so that tree-views can choose to insert items
before, after and into other items.
Note: While there is support for drag-tooltips that can explain how an item
will be inserted, there is no drawing yet like in the Outliner, that indicates
if an item is inserted before, after or into. There is some work on that but
that can be done separately.
Changes:
- Removes `AbstractViewDropTarget` that was shared between tree- and
grid-views, and adds `AbstractTreeViewDropTarget` and
`AbstractGridViewDropTarget`. The tree-view needs specialized handling now,
and although they could share some code still, it's not worth having another
level of inheritance.
- Modifies the drop-target API to use `DragInfo` which contains more info about
the dragging operation than just the `wmDrag`.
- Adds `determine_drop_location()` to the `DropTargetInterface` which drop
targets can use to determine when dropping means inserting before, after or
into.
- Store the block and region in the view. This is needed unfortunately but
shouldn't be an issue since the tree view is recreated on redraws, together
with the block.
- Various smaller tweaks and additions to views as needed.
TODO (outside scope of this change): Increase row height so there is no gap
between tree view items, but keep things visually the same otherwise. This
reduces flickering while dragging.
Pull Request: https://projects.blender.org/blender/blender/pulls/109825
2023-07-11 14:30:26 +02:00
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
|
/** \name Drag & Drop
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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 target for itself via a custom
|
|
|
|
|
* implementation of #AbstractTreeViewItem::create_drop_target().
|
|
|
|
|
*
|
|
|
|
|
* By default the drop target only supports dropping into/onto itself. To support
|
|
|
|
|
* inserting/reordering behavior, where dropping before or after the drop-target is supported, pass
|
|
|
|
|
* a different #DropBehavior to the constructor.
|
|
|
|
|
*/
|
|
|
|
|
class TreeViewItemDropTarget : public DropTargetInterface {
|
|
|
|
|
protected:
|
2023-10-12 17:06:15 +02:00
|
|
|
AbstractTreeViewItem &view_item_;
|
UI: Basic tree-view drag & drop reordering and inserting support
No user visible changes expected, these are just the internal API preparations.
Modifies the Drop API for views so that tree-views can choose to insert items
before, after and into other items.
Note: While there is support for drag-tooltips that can explain how an item
will be inserted, there is no drawing yet like in the Outliner, that indicates
if an item is inserted before, after or into. There is some work on that but
that can be done separately.
Changes:
- Removes `AbstractViewDropTarget` that was shared between tree- and
grid-views, and adds `AbstractTreeViewDropTarget` and
`AbstractGridViewDropTarget`. The tree-view needs specialized handling now,
and although they could share some code still, it's not worth having another
level of inheritance.
- Modifies the drop-target API to use `DragInfo` which contains more info about
the dragging operation than just the `wmDrag`.
- Adds `determine_drop_location()` to the `DropTargetInterface` which drop
targets can use to determine when dropping means inserting before, after or
into.
- Store the block and region in the view. This is needed unfortunately but
shouldn't be an issue since the tree view is recreated on redraws, together
with the block.
- Various smaller tweaks and additions to views as needed.
TODO (outside scope of this change): Increase row height so there is no gap
between tree view items, but keep things visually the same otherwise. This
reduces flickering while dragging.
Pull Request: https://projects.blender.org/blender/blender/pulls/109825
2023-07-11 14:30:26 +02:00
|
|
|
const DropBehavior behavior_;
|
|
|
|
|
|
|
|
|
|
public:
|
2023-10-12 17:06:15 +02:00
|
|
|
TreeViewItemDropTarget(AbstractTreeViewItem &view_item,
|
|
|
|
|
DropBehavior behavior = DropBehavior::Insert);
|
UI: Basic tree-view drag & drop reordering and inserting support
No user visible changes expected, these are just the internal API preparations.
Modifies the Drop API for views so that tree-views can choose to insert items
before, after and into other items.
Note: While there is support for drag-tooltips that can explain how an item
will be inserted, there is no drawing yet like in the Outliner, that indicates
if an item is inserted before, after or into. There is some work on that but
that can be done separately.
Changes:
- Removes `AbstractViewDropTarget` that was shared between tree- and
grid-views, and adds `AbstractTreeViewDropTarget` and
`AbstractGridViewDropTarget`. The tree-view needs specialized handling now,
and although they could share some code still, it's not worth having another
level of inheritance.
- Modifies the drop-target API to use `DragInfo` which contains more info about
the dragging operation than just the `wmDrag`.
- Adds `determine_drop_location()` to the `DropTargetInterface` which drop
targets can use to determine when dropping means inserting before, after or
into.
- Store the block and region in the view. This is needed unfortunately but
shouldn't be an issue since the tree view is recreated on redraws, together
with the block.
- Various smaller tweaks and additions to views as needed.
TODO (outside scope of this change): Increase row height so there is no gap
between tree view items, but keep things visually the same otherwise. This
reduces flickering while dragging.
Pull Request: https://projects.blender.org/blender/blender/pulls/109825
2023-07-11 14:30:26 +02:00
|
|
|
|
|
|
|
|
std::optional<DropLocation> choose_drop_location(const ARegion ®ion,
|
2023-07-26 15:08:21 +02:00
|
|
|
const wmEvent &event) const override;
|
UI: Basic tree-view drag & drop reordering and inserting support
No user visible changes expected, these are just the internal API preparations.
Modifies the Drop API for views so that tree-views can choose to insert items
before, after and into other items.
Note: While there is support for drag-tooltips that can explain how an item
will be inserted, there is no drawing yet like in the Outliner, that indicates
if an item is inserted before, after or into. There is some work on that but
that can be done separately.
Changes:
- Removes `AbstractViewDropTarget` that was shared between tree- and
grid-views, and adds `AbstractTreeViewDropTarget` and
`AbstractGridViewDropTarget`. The tree-view needs specialized handling now,
and although they could share some code still, it's not worth having another
level of inheritance.
- Modifies the drop-target API to use `DragInfo` which contains more info about
the dragging operation than just the `wmDrag`.
- Adds `determine_drop_location()` to the `DropTargetInterface` which drop
targets can use to determine when dropping means inserting before, after or
into.
- Store the block and region in the view. This is needed unfortunately but
shouldn't be an issue since the tree view is recreated on redraws, together
with the block.
- Various smaller tweaks and additions to views as needed.
TODO (outside scope of this change): Increase row height so there is no gap
between tree view items, but keep things visually the same otherwise. This
reduces flickering while dragging.
Pull Request: https://projects.blender.org/blender/blender/pulls/109825
2023-07-11 14:30:26 +02:00
|
|
|
|
|
|
|
|
/** 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;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
2021-12-09 12:07:34 +01:00
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
|
/** \name Tree-View Builder
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
class TreeViewBuilder {
|
|
|
|
|
public:
|
2023-03-20 11:35:45 +01:00
|
|
|
static void build_tree_view(AbstractTreeView &tree_view, uiLayout &layout);
|
2023-03-28 12:33:35 +02:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
static void ensure_min_rows_items(AbstractTreeView &tree_view);
|
2021-12-09 12:07:34 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
2021-10-06 13:06:20 +02:00
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
template<class ItemT, typename... Args>
|
|
|
|
|
inline ItemT &TreeViewItemContainer::add_tree_item(Args &&...args)
|
|
|
|
|
{
|
|
|
|
|
static_assert(std::is_base_of<AbstractTreeViewItem, ItemT>::value,
|
|
|
|
|
"Type must derive from and implement the AbstractTreeViewItem interface");
|
|
|
|
|
|
|
|
|
|
return dynamic_cast<ItemT &>(
|
|
|
|
|
add_tree_item(std::make_unique<ItemT>(std::forward<Args>(args)...)));
|
|
|
|
|
}
|
|
|
|
|
|
UI: Basic tree-view drag & drop reordering and inserting support
No user visible changes expected, these are just the internal API preparations.
Modifies the Drop API for views so that tree-views can choose to insert items
before, after and into other items.
Note: While there is support for drag-tooltips that can explain how an item
will be inserted, there is no drawing yet like in the Outliner, that indicates
if an item is inserted before, after or into. There is some work on that but
that can be done separately.
Changes:
- Removes `AbstractViewDropTarget` that was shared between tree- and
grid-views, and adds `AbstractTreeViewDropTarget` and
`AbstractGridViewDropTarget`. The tree-view needs specialized handling now,
and although they could share some code still, it's not worth having another
level of inheritance.
- Modifies the drop-target API to use `DragInfo` which contains more info about
the dragging operation than just the `wmDrag`.
- Adds `determine_drop_location()` to the `DropTargetInterface` which drop
targets can use to determine when dropping means inserting before, after or
into.
- Store the block and region in the view. This is needed unfortunately but
shouldn't be an issue since the tree view is recreated on redraws, together
with the block.
- Various smaller tweaks and additions to views as needed.
TODO (outside scope of this change): Increase row height so there is no gap
between tree view items, but keep things visually the same otherwise. This
reduces flickering while dragging.
Pull Request: https://projects.blender.org/blender/blender/pulls/109825
2023-07-11 14:30:26 +02:00
|
|
|
template<class ViewType> ViewType &TreeViewItemDropTarget::get_view() const
|
|
|
|
|
{
|
|
|
|
|
static_assert(std::is_base_of<AbstractTreeView, ViewType>::value,
|
|
|
|
|
"Type must derive from and implement the ui::AbstractTreeView interface");
|
2023-10-12 17:06:15 +02:00
|
|
|
return dynamic_cast<ViewType &>(view_item_.get_tree_view());
|
UI: Basic tree-view drag & drop reordering and inserting support
No user visible changes expected, these are just the internal API preparations.
Modifies the Drop API for views so that tree-views can choose to insert items
before, after and into other items.
Note: While there is support for drag-tooltips that can explain how an item
will be inserted, there is no drawing yet like in the Outliner, that indicates
if an item is inserted before, after or into. There is some work on that but
that can be done separately.
Changes:
- Removes `AbstractViewDropTarget` that was shared between tree- and
grid-views, and adds `AbstractTreeViewDropTarget` and
`AbstractGridViewDropTarget`. The tree-view needs specialized handling now,
and although they could share some code still, it's not worth having another
level of inheritance.
- Modifies the drop-target API to use `DragInfo` which contains more info about
the dragging operation than just the `wmDrag`.
- Adds `determine_drop_location()` to the `DropTargetInterface` which drop
targets can use to determine when dropping means inserting before, after or
into.
- Store the block and region in the view. This is needed unfortunately but
shouldn't be an issue since the tree view is recreated on redraws, together
with the block.
- Various smaller tweaks and additions to views as needed.
TODO (outside scope of this change): Increase row height so there is no gap
between tree view items, but keep things visually the same otherwise. This
reduces flickering while dragging.
Pull Request: https://projects.blender.org/blender/blender/pulls/109825
2023-07-11 14:30:26 +02:00
|
|
|
}
|
|
|
|
|
|
2021-09-23 18:56:29 +02:00
|
|
|
} // namespace blender::ui
|