This PR refactors each UI template into its own `interface_template_*.cc` file. * Added `interface_templates_intern.hh` which exposes shared utility functions and macros. * Doxygen comment sections that were redundant of the file name were removed. If they contained additional description, they were added to the file Doxygen `\file` header. * Short templates that were closely related were kept together in single files (e.g `uiTemplateHistogram`, `uiTemplateWaveform` and `uiTemplateVectorScope` are all in `interface_template_scopes.cc`). In this case, Doxygen comment section were preserved. The only things remaining in `interface_templates.cc` are: * Common utility function exposed by `interface_templates_intern.hh` * Small independent templates (`uiTemplatePathBuilder`, `uiTemplateNodeSocket` and `uiTemplateFileSelectPath`) Ref: https://projects.blender.org/blender/blender/issues/117604 Pull Request: https://projects.blender.org/blender/blender/pulls/132468
114 lines
3.5 KiB
C++
114 lines
3.5 KiB
C++
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup edinterface
|
|
*/
|
|
|
|
#include "BKE_context.hh"
|
|
|
|
#include "BLI_string_ref.hh"
|
|
|
|
#include "RNA_access.hh"
|
|
|
|
#include "UI_interface.hh"
|
|
#include "interface_intern.hh"
|
|
|
|
using blender::StringRefNull;
|
|
|
|
static void handle_layer_buttons(bContext *C, void *arg1, void *arg2)
|
|
{
|
|
uiBut *but = static_cast<uiBut *>(arg1);
|
|
const int cur = POINTER_AS_INT(arg2);
|
|
wmWindow *win = CTX_wm_window(C);
|
|
const bool shift = win->eventstate->modifier & KM_SHIFT;
|
|
|
|
if (!shift) {
|
|
const int tot = RNA_property_array_length(&but->rnapoin, but->rnaprop);
|
|
|
|
/* Normally clicking only selects one layer */
|
|
RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, cur, true);
|
|
for (int i = 0; i < tot; i++) {
|
|
if (i != cur) {
|
|
RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, i, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* view3d layer change should update depsgraph (invisible object changed maybe) */
|
|
/* see `view3d_header.cc` */
|
|
}
|
|
|
|
void uiTemplateLayers(uiLayout *layout,
|
|
PointerRNA *ptr,
|
|
const StringRefNull propname,
|
|
PointerRNA *used_ptr,
|
|
const char *used_propname,
|
|
int active_layer)
|
|
{
|
|
const int cols_per_group = 5;
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(ptr, propname.c_str());
|
|
if (!prop) {
|
|
RNA_warning(
|
|
"layers property not found: %s.%s", RNA_struct_identifier(ptr->type), propname.c_str());
|
|
return;
|
|
}
|
|
|
|
/* the number of layers determines the way we group them
|
|
* - we want 2 rows only (for now)
|
|
* - The number of columns (cols) is the total number of buttons per row the 'remainder'
|
|
* is added to this, as it will be ok to have first row slightly wider if need be.
|
|
* - For now, only split into groups if group will have at least 5 items.
|
|
*/
|
|
const int layers = RNA_property_array_length(ptr, prop);
|
|
const int cols = (layers / 2) + (layers % 2);
|
|
const int groups = ((cols / 2) < cols_per_group) ? (1) : (cols / cols_per_group);
|
|
|
|
PropertyRNA *used_prop = nullptr;
|
|
if (used_ptr && used_propname) {
|
|
used_prop = RNA_struct_find_property(used_ptr, used_propname);
|
|
if (!used_prop) {
|
|
RNA_warning("used layers property not found: %s.%s",
|
|
RNA_struct_identifier(ptr->type),
|
|
used_propname);
|
|
return;
|
|
}
|
|
|
|
if (RNA_property_array_length(used_ptr, used_prop) < layers) {
|
|
used_prop = nullptr;
|
|
}
|
|
}
|
|
|
|
/* layers are laid out going across rows, with the columns being divided into groups */
|
|
|
|
for (int group = 0; group < groups; group++) {
|
|
uiLayout *uCol = uiLayoutColumn(layout, true);
|
|
|
|
for (int row = 0; row < 2; row++) {
|
|
uiLayout *uRow = uiLayoutRow(uCol, true);
|
|
uiBlock *block = uiLayoutGetBlock(uRow);
|
|
int layer = groups * cols_per_group * row + cols_per_group * group;
|
|
|
|
/* add layers as toggle buts */
|
|
for (int col = 0; (col < cols_per_group) && (layer < layers); col++, layer++) {
|
|
int icon = 0;
|
|
const int butlay = 1 << layer;
|
|
|
|
if (active_layer & butlay) {
|
|
icon = ICON_LAYER_ACTIVE;
|
|
}
|
|
else if (used_prop && RNA_property_boolean_get_index(used_ptr, used_prop, layer)) {
|
|
icon = ICON_LAYER_USED;
|
|
}
|
|
|
|
uiBut *but = uiDefAutoButR(
|
|
block, ptr, prop, layer, "", icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2);
|
|
UI_but_func_set(but, handle_layer_buttons, but, POINTER_FROM_INT(layer));
|
|
but->type = UI_BTYPE_TOGGLE;
|
|
}
|
|
}
|
|
}
|
|
}
|