Blender V5.0
interface_template_layers.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BKE_context.hh"
10
11#include "BLI_array.hh"
12#include "BLI_string_ref.hh"
13
14#include "RNA_access.hh"
15
17#include "interface_intern.hh"
18
20
21static void handle_layer_buttons(bContext *C, void *arg1, void *arg2)
22{
23 uiBut *but = static_cast<uiBut *>(arg1);
24 const int cur = POINTER_AS_INT(arg2);
25 wmWindow *win = CTX_wm_window(C);
26 const bool shift = win->eventstate->modifier & KM_SHIFT;
27
28 if (!shift) {
29 const int tot = RNA_property_array_length(&but->rnapoin, but->rnaprop);
30
31 BLI_assert(cur < tot);
33 value_array.fill(false);
34 value_array[cur] = true;
35
36 /* Normally clicking only selects one layer */
37 RNA_property_boolean_set_array(&but->rnapoin, but->rnaprop, value_array.data());
38 }
39
40 /* view3d layer change should update depsgraph (invisible object changed maybe) */
41 /* see `view3d_header.cc` */
42}
43
46 const StringRefNull propname,
47 PointerRNA *used_ptr,
48 const char *used_propname,
49 int active_layer)
50{
51 const int cols_per_group = 5;
52
53 PropertyRNA *prop = RNA_struct_find_property(ptr, propname.c_str());
54 if (!prop) {
56 "layers property not found: %s.%s", RNA_struct_identifier(ptr->type), propname.c_str());
57 return;
58 }
59
60 /* the number of layers determines the way we group them
61 * - we want 2 rows only (for now)
62 * - The number of columns (cols) is the total number of buttons per row the 'remainder'
63 * is added to this, as it will be ok to have first row slightly wider if need be.
64 * - For now, only split into groups if group will have at least 5 items.
65 */
66 const int layers = RNA_property_array_length(ptr, prop);
67 const int cols = (layers / 2) + (layers % 2);
68 const int groups = ((cols / 2) < cols_per_group) ? (1) : (cols / cols_per_group);
69
70 PropertyRNA *used_prop = nullptr;
71 if (used_ptr && used_propname) {
72 used_prop = RNA_struct_find_property(used_ptr, used_propname);
73 if (!used_prop) {
74 RNA_warning("used layers property not found: %s.%s",
76 used_propname);
77 return;
78 }
79
80 if (RNA_property_array_length(used_ptr, used_prop) < layers) {
81 used_prop = nullptr;
82 }
83 }
84
85 /* layers are laid out going across rows, with the columns being divided into groups */
86
87 for (int group = 0; group < groups; group++) {
88 uiLayout *uCol = &layout->column(true);
89
90 for (int row = 0; row < 2; row++) {
91 uiLayout *uRow = &uCol->row(true);
92 uiBlock *block = uRow->block();
93 int layer = groups * cols_per_group * row + cols_per_group * group;
94
95 /* add layers as toggle buts */
96 for (int col = 0; (col < cols_per_group) && (layer < layers); col++, layer++) {
97 int icon = 0;
98 const int butlay = 1 << layer;
99
100 if (active_layer & butlay) {
101 icon = ICON_LAYER_ACTIVE;
102 }
103 else if (used_prop && RNA_property_boolean_get_index(used_ptr, used_prop, layer)) {
104 icon = ICON_LAYER_USED;
105 }
106
107 uiBut *but = uiDefAutoButR(
108 block, ptr, prop, layer, "", icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2);
110 but->type = ButType::Toggle;
111 }
112 }
113 }
114}
wmWindow * CTX_wm_window(const bContext *C)
#define BLI_assert(a)
Definition BLI_assert.h:46
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
#define RNA_warning(format,...)
#define C
Definition RandGen.cpp:29
void UI_but_func_set(uiBut *but, std::function< void(bContext &)> func)
#define UI_UNIT_Y
uiBut * uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, std::optional< blender::StringRef > name, int icon, int x, int y, int width, int height)
#define UI_UNIT_X
@ KM_SHIFT
Definition WM_types.hh:278
const T * data() const
Definition BLI_array.hh:312
void fill(const T &value) const
Definition BLI_array.hh:272
constexpr const char * c_str() const
uint col
void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, const StringRefNull propname, PointerRNA *used_ptr, const char *used_propname, int active_layer)
static void handle_layer_buttons(bContext *C, void *arg1, void *arg2)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
const char * RNA_struct_identifier(const StructRNA *type)
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const bool *values)
PropertyRNA * rnaprop
ButType type
PointerRNA rnapoin
uiBlock * block() const
uiLayout & column(bool align)
uiLayout & row(bool align)
wmEventModifierFlag modifier
Definition WM_types.hh:774
struct wmEvent * eventstate
PointerRNA * ptr
Definition wm_files.cc:4238