Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/include/ED_node.h1
-rw-r--r--source/blender/editors/include/UI_interface.hh25
-rw-r--r--source/blender/editors/interface/CMakeLists.txt1
-rw-r--r--source/blender/editors/interface/interface_context_path.cc85
-rw-r--r--source/blender/editors/space_node/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_node/node_context_path.cc184
-rw-r--r--source/blender/editors/space_node/node_draw.cc39
-rw-r--r--source/blender/editors/space_node/node_intern.h8
-rw-r--r--source/blender/editors/space_node/space_node.c21
-rw-r--r--source/blender/makesrna/intern/rna_gpencil_modifier.c4
10 files changed, 337 insertions, 32 deletions
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index 1ba52552902..e68617f7867 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -64,7 +64,6 @@ void ED_node_cursor_location_set(struct SpaceNode *snode, const float value[2]);
int ED_node_tree_path_length(struct SpaceNode *snode);
void ED_node_tree_path_get(struct SpaceNode *snode, char *value);
-void ED_node_tree_path_get_fixedbuf(struct SpaceNode *snode, char *value, int max_length);
void ED_node_tree_start(struct SpaceNode *snode,
struct bNodeTree *ntree,
diff --git a/source/blender/editors/include/UI_interface.hh b/source/blender/editors/include/UI_interface.hh
index 5edccfa8c88..b14ee6c4a59 100644
--- a/source/blender/editors/include/UI_interface.hh
+++ b/source/blender/editors/include/UI_interface.hh
@@ -23,15 +23,40 @@
#include <memory>
#include "BLI_string_ref.hh"
+#include "BLI_vector.hh"
+
+#include "UI_resources.h"
namespace blender::nodes::geometry_nodes_eval_log {
struct GeometryAttributeInfo;
}
struct uiBlock;
+struct StructRNA;
+struct uiSearchItems;
+
namespace blender::ui {
+
class AbstractTreeView;
+/**
+ * An item in a breadcrumb-like context. Currently this struct is very simple, but more
+ * could be added to it in the future, to support interactivity or tooltips, for example.
+ */
+struct ContextPathItem {
+ /* Text to display in the UI. */
+ std::string name;
+ /* #BIFIconID */
+ int icon;
+};
+
+void context_path_add_generic(Vector<ContextPathItem> &path,
+ StructRNA &rna_type,
+ void *ptr,
+ const BIFIconID icon_override = ICON_NONE);
+
+void template_breadcrumbs(uiLayout &layout, Span<ContextPathItem> context_path);
+
void attribute_search_add_items(
StringRefNull str,
const bool is_output,
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index b2659f5ed52..84172c7efce 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -43,6 +43,7 @@ set(SRC
interface_anim.c
interface_button_group.c
interface_context_menu.c
+ interface_context_path.cc
interface_draw.c
interface_dropboxes.cc
interface_eyedropper.c
diff --git a/source/blender/editors/interface/interface_context_path.cc b/source/blender/editors/interface/interface_context_path.cc
new file mode 100644
index 00000000000..b0f8d186afa
--- /dev/null
+++ b/source/blender/editors/interface/interface_context_path.cc
@@ -0,0 +1,85 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2021 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edinterface
+ */
+
+#include "BLI_vector.hh"
+
+#include "BKE_screen.h"
+
+#include "RNA_access.h"
+
+#include "ED_screen.h"
+
+#include "UI_interface.h"
+#include "UI_interface.hh"
+#include "UI_resources.h"
+
+#include "WM_api.h"
+
+namespace blender::ui {
+
+void context_path_add_generic(Vector<ContextPathItem> &path,
+ StructRNA &rna_type,
+ void *ptr,
+ const BIFIconID icon_override)
+{
+ /* Add the null check here to make calling functions less verbose. */
+ if (!ptr) {
+ return;
+ }
+
+ PointerRNA rna_ptr;
+ RNA_pointer_create(nullptr, &rna_type, ptr, &rna_ptr);
+ char name[128];
+ RNA_struct_name_get_alloc(&rna_ptr, name, sizeof(name), nullptr);
+
+ /* Use a blank icon by default to check whether to retrieve it automatically from the type. */
+ const BIFIconID icon = icon_override == ICON_NONE ?
+ static_cast<BIFIconID>(RNA_struct_ui_icon(rna_ptr.type)) :
+ icon_override;
+
+ path.append({name, static_cast<int>(icon)});
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Breadcrumb Template
+ * \{ */
+
+void template_breadcrumbs(uiLayout &layout, Span<ContextPathItem> context_path)
+{
+ uiLayout *row = uiLayoutRow(&layout, true);
+ uiLayoutSetAlignment(&layout, UI_LAYOUT_ALIGN_LEFT);
+
+ for (const int i : context_path.index_range()) {
+ uiLayout *sub_row = uiLayoutRow(row, true);
+ uiLayoutSetAlignment(sub_row, UI_LAYOUT_ALIGN_LEFT);
+
+ if (i > 0) {
+ uiItemL(sub_row, "", ICON_RIGHTARROW_THIN);
+ }
+ uiItemL(sub_row, context_path[i].name.c_str(), context_path[i].icon);
+ }
+}
+
+} // namespace blender::ui
+
+/** \} */ \ No newline at end of file
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index 80d3b43bf6b..600309c2c86 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -40,6 +40,7 @@ set(INC
set(SRC
drawnode.cc
node_add.cc
+ node_context_path.cc
node_draw.cc
node_edit.cc
node_geometry_attribute_search.cc
diff --git a/source/blender/editors/space_node/node_context_path.cc b/source/blender/editors/space_node/node_context_path.cc
new file mode 100644
index 00000000000..a0ff7f3ce25
--- /dev/null
+++ b/source/blender/editors/space_node/node_context_path.cc
@@ -0,0 +1,184 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup spnode
+ * \brief Node breadcrumbs drawing
+ */
+
+#include "BLI_vector.hh"
+
+#include "DNA_node_types.h"
+
+#include "BKE_context.h"
+#include "BKE_material.h"
+#include "BKE_modifier.h"
+#include "BKE_object.h"
+
+#include "BKE_screen.h"
+
+#include "RNA_access.h"
+
+#include "ED_screen.h"
+
+#include "UI_interface.h"
+#include "UI_interface.hh"
+#include "UI_resources.h"
+
+#include "UI_interface.hh"
+
+#include "node_intern.h"
+
+struct Mesh;
+struct Curve;
+struct Light;
+struct World;
+struct Material;
+
+namespace blender::ed::space_node {
+
+static void context_path_add_object_data(Vector<ui::ContextPathItem> &path, Object &object)
+{
+ if (object.type == OB_MESH && object.data) {
+ Mesh *mesh = (Mesh *)object.data;
+ ui::context_path_add_generic(path, RNA_Mesh, mesh);
+ }
+ if (object.type == OB_LAMP && object.data) {
+ Light *light = (Light *)object.data;
+ ui::context_path_add_generic(path, RNA_Light, light);
+ }
+ if (ELEM(object.type, OB_CURVE, OB_FONT, OB_SURF) && object.data) {
+ Curve *curve = (Curve *)object.data;
+ ui::context_path_add_generic(path, RNA_Curve, curve);
+ }
+}
+
+static void context_path_add_node_tree_and_node_groups(const SpaceNode &snode,
+ Vector<ui::ContextPathItem> &path,
+ const bool skip_base = false)
+{
+ Vector<const bNodeTreePath *> tree_path = snode.treepath;
+ for (const bNodeTreePath *path_item : tree_path.as_span().drop_front(int(skip_base))) {
+ ui::context_path_add_generic(path, RNA_NodeTree, path_item->nodetree, ICON_NODETREE);
+ }
+}
+
+static void get_context_path_node_shader(const bContext &C,
+ SpaceNode &snode,
+ Vector<ui::ContextPathItem> &path)
+{
+ if (snode.flag & SNODE_PIN) {
+ if (snode.shaderfrom == SNODE_SHADER_WORLD) {
+ Scene *scene = CTX_data_scene(&C);
+ ui::context_path_add_generic(path, RNA_Scene, scene);
+ if (scene != nullptr) {
+ World *world = scene->world;
+ ui::context_path_add_generic(path, RNA_World, world);
+ }
+ /* Skip the base node tree here, because the world contains a node tree already. */
+ context_path_add_node_tree_and_node_groups(snode, path, true);
+ }
+ else {
+ context_path_add_node_tree_and_node_groups(snode, path);
+ }
+ }
+ else {
+ Object *object = CTX_data_active_object(&C);
+ if (snode.shaderfrom == SNODE_SHADER_OBJECT && object != nullptr) {
+ ui::context_path_add_generic(path, RNA_Object, object);
+ if (!(object->matbits && object->matbits[object->actcol - 1])) {
+ context_path_add_object_data(path, *object);
+ }
+ Material *material = BKE_object_material_get(object, object->actcol);
+ ui::context_path_add_generic(path, RNA_Material, material);
+ }
+ else if (snode.shaderfrom == SNODE_SHADER_WORLD) {
+ Scene *scene = CTX_data_scene(&C);
+ ui::context_path_add_generic(path, RNA_Scene, scene);
+ if (scene != nullptr) {
+ World *world = scene->world;
+ ui::context_path_add_generic(path, RNA_World, world);
+ }
+ }
+#ifdef WITH_FREESTYLE
+ else if (snode.shaderfrom == SNODE_SHADER_LINESTYLE) {
+ ViewLayer *viewlayer = CTX_data_view_layer(&C);
+ FreestyleLineStyle *linestyle = BKE_linestyle_active_from_view_layer(viewlayer);
+ ui::context_path_add_generic(path, RNA_ViewLayer, viewlayer);
+ Material *mat = BKE_object_material_get(object, object->actcol);
+ ui::context_path_add_generic(path, RNA_Material, mat);
+ }
+#endif
+ context_path_add_node_tree_and_node_groups(snode, path, true);
+ }
+}
+
+static void get_context_path_node_compositor(const bContext &C,
+ SpaceNode &snode,
+ Vector<ui::ContextPathItem> &path)
+{
+ if (snode.flag & SNODE_PIN) {
+ context_path_add_node_tree_and_node_groups(snode, path);
+ }
+ else {
+ Scene *scene = CTX_data_scene(&C);
+ ui::context_path_add_generic(path, RNA_Scene, scene);
+ context_path_add_node_tree_and_node_groups(snode, path);
+ }
+}
+
+static void get_context_path_node_geometry(const bContext &C,
+ SpaceNode &snode,
+ Vector<ui::ContextPathItem> &path)
+{
+ if (snode.flag & SNODE_PIN) {
+ context_path_add_node_tree_and_node_groups(snode, path);
+ }
+ else {
+ Object *object = CTX_data_active_object(&C);
+ ui::context_path_add_generic(path, RNA_Object, object);
+ ModifierData *modifier = BKE_object_active_modifier(object);
+ ui::context_path_add_generic(path, RNA_Modifier, modifier, ICON_MODIFIER);
+ context_path_add_node_tree_and_node_groups(snode, path);
+ }
+}
+
+Vector<ui::ContextPathItem> context_path_for_space_node(const bContext &C)
+{
+ SpaceNode *snode = CTX_wm_space_node(&C);
+ if (snode == nullptr) {
+ return {};
+ }
+
+ Vector<ui::ContextPathItem> context_path;
+
+ if (snode->edittree->type == NTREE_GEOMETRY) {
+ get_context_path_node_geometry(C, *snode, context_path);
+ }
+ else if (snode->edittree->type == NTREE_SHADER) {
+ get_context_path_node_shader(C, *snode, context_path);
+ }
+ else if (snode->edittree->type == NTREE_COMPOSIT) {
+ get_context_path_node_compositor(C, *snode, context_path);
+ }
+
+ return context_path;
+}
+
+} // namespace blender::ed::space_node
diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc
index 9e91d394fef..ea65eaa0a14 100644
--- a/source/blender/editors/space_node/node_draw.cc
+++ b/source/blender/editors/space_node/node_draw.cc
@@ -71,8 +71,10 @@
#include "ED_gpencil.h"
#include "ED_node.h"
+#include "ED_screen.h"
#include "ED_space_api.h"
+#include "UI_interface.hh"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -2158,15 +2160,34 @@ void node_draw_nodetree(const bContext *C,
}
}
-/* Draw tree path info in lower left corner. */
-static void draw_tree_path(SpaceNode *snode)
+/* Draw the breadcrumb on the bottom of the editor. */
+static void draw_tree_path(const bContext &C, ARegion &region)
{
- char info[256];
+ using namespace blender;
- ED_node_tree_path_get_fixedbuf(snode, info, sizeof(info));
+ GPU_matrix_push_projection();
+ wmOrtho2_region_pixelspace(&region);
- UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
- BLF_draw_default(1.5f * UI_UNIT_X, 1.5f * UI_UNIT_Y, 0.0f, info, sizeof(info));
+ const rcti *rect = ED_region_visible_rect(&region);
+
+ const uiStyle *style = UI_style_get_dpi();
+ const float padding_x = 16 * UI_DPI_FAC;
+ const int x = rect->xmin + padding_x;
+ const int y = region.winy - UI_UNIT_Y * 0.6f;
+ const int width = BLI_rcti_size_x(rect) - 2 * padding_x;
+
+ uiBlock *block = UI_block_begin(&C, &region, __func__, UI_EMBOSS_NONE);
+ uiLayout *layout = UI_block_layout(
+ block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, x, y, width, 1, 0, style);
+
+ Vector<ui::ContextPathItem> context_path = ed::space_node::context_path_for_space_node(C);
+ ui::template_breadcrumbs(*layout, context_path);
+
+ UI_block_layout_resolve(block, nullptr, nullptr);
+ UI_block_end(&C, block);
+ UI_block_draw(&C, block);
+
+ GPU_matrix_pop_projection();
}
static void snode_setup_v2d(SpaceNode *snode, ARegion *region, const float center[2])
@@ -2336,8 +2357,10 @@ void node_draw_space(const bContext *C, ARegion *region)
}
}
- /* Tree path info. */
- draw_tree_path(snode);
+ /* Draw context path. */
+ if (snode->edittree) {
+ draw_tree_path(*C, *region);
+ }
/* Scrollers. */
UI_view2d_scrollers_draw(v2d, nullptr);
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index f069038cc09..e7d9a12a52c 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -341,3 +341,11 @@ extern const char *node_context_dir[];
#ifdef __cplusplus
}
#endif
+
+#ifdef __cplusplus
+# include "BLI_vector.hh"
+# include "UI_interface.hh"
+namespace blender::ed::space_node {
+Vector<ui::ContextPathItem> context_path_for_space_node(const bContext &C);
+}
+#endif \ No newline at end of file
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 8c015a56fa1..0b5d7cdda82 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -201,27 +201,6 @@ void ED_node_tree_path_get(SpaceNode *snode, char *value)
}
}
-void ED_node_tree_path_get_fixedbuf(SpaceNode *snode, char *value, int max_length)
-{
- int size;
-
- value[0] = '\0';
- int i = 0;
- LISTBASE_FOREACH_INDEX (bNodeTreePath *, path, &snode->treepath, i) {
- if (i == 0) {
- size = BLI_strncpy_rlen(value, path->display_name, max_length);
- }
- else {
- size = BLI_snprintf_rlen(value, max_length, "/%s", path->display_name);
- }
- max_length -= size;
- if (max_length <= 0) {
- break;
- }
- value += size;
- }
-}
-
void ED_node_set_active_viewer_key(SpaceNode *snode)
{
bNodeTreePath *path = snode->treepath.last;
diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c
index fdce35ba2de..79125e5d40e 100644
--- a/source/blender/makesrna/intern/rna_gpencil_modifier.c
+++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c
@@ -3211,8 +3211,8 @@ static void rna_def_modifier_gpencillineart(BlenderRNA *brna)
"Stroke Depth Offset",
"Move strokes slightly towards the camera to avoid clipping while "
"preserve depth for the viewport");
- RNA_def_property_range(prop, 0.0f, FLT_MAX);
- RNA_def_property_ui_range(prop, 0.0f, 0.5f, 0.001f, 4);
+ RNA_def_property_ui_range(prop, 0.0, 0.5, 0.001, 4);
+ RNA_def_property_range(prop, -0.1, FLT_MAX);
RNA_def_property_update(prop, NC_SCENE, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "offset_towards_custom_camera", PROP_BOOLEAN, PROP_NONE);