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
diff options
context:
space:
mode:
-rw-r--r--source/blender/editors/interface/interface.c1
-rw-r--r--source/blender/editors/interface/interface_intern.h1
-rw-r--r--source/blender/editors/interface/interface_layout.c91
3 files changed, 90 insertions, 3 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 8e7fc807835..b9a001a9571 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -3943,6 +3943,7 @@ uiBut *ui_but_change_type(uiBut *but, eButType new_type)
const bool found_layout = ui_layout_replace_but_ptr(but->layout, old_but_ptr, but);
BLI_assert(found_layout);
UNUSED_VARS_NDEBUG(found_layout);
+ ui_button_group_replace_but_ptr(but->layout, old_but_ptr, but);
}
}
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 4661d0816ae..edaadd880d7 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -994,6 +994,7 @@ void ui_resources_free(void);
/* interface_layout.c */
void ui_layout_add_but(uiLayout *layout, uiBut *but);
bool ui_layout_replace_but_ptr(uiLayout *layout, const void *old_but_ptr, uiBut *new_but);
+void ui_button_group_replace_but_ptr(uiLayout *layout, const void *old_but_ptr, uiBut *new_but);
uiBut *ui_but_add_search(uiBut *but,
PointerRNA *ptr,
PropertyRNA *prop,
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index f73e4bb0540..c3bcaff0d0c 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -80,12 +80,25 @@
/* uiLayoutRoot */
+/**
+ * A group of button references, used by property search to keep track of sets of buttons that
+ * should be searched together. For example, in property split layouts number buttons and their
+ * labels (and even their decorators) are separate buttons, but they must be searched and
+ * highlighted together.
+ */
+typedef struct uiButtonGroup {
+ void *next, *prev;
+ ListBase buttons; /* #LinkData with #uiBut data field. */
+} uiButtonGroup;
+
typedef struct uiLayoutRoot {
struct uiLayoutRoot *next, *prev;
int type;
int opcontext;
+ ListBase button_groups; /* #uiButtonGroup. */
+
int emw, emh;
int padding;
@@ -415,6 +428,58 @@ static void ui_item_move(uiItem *item, int delta_xmin, int delta_xmax)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Button Groups
+ * \{ */
+
+/**
+ * Every function that adds a set of buttons must create another group,
+ * then #ui_def_but adds buttons to the current group (the last).
+ */
+static void layout_root_new_button_group(uiLayoutRoot *root)
+{
+ uiButtonGroup *new_group = MEM_mallocN(sizeof(uiButtonGroup), __func__);
+ BLI_listbase_clear(&new_group->buttons);
+ BLI_addtail(&root->button_groups, new_group);
+}
+
+static void button_group_add_but(uiLayoutRoot *root, uiBut *but)
+{
+ BLI_assert(root != NULL);
+
+ uiButtonGroup *current_button_group = root->button_groups.last;
+ BLI_assert(current_button_group != NULL);
+
+ /* We can't use the button directly because adding it to
+ * this list would mess with its prev and next pointers. */
+ LinkData *button_link = BLI_genericNodeN(but);
+ BLI_addtail(&current_button_group->buttons, button_link);
+}
+
+static void button_group_free(uiButtonGroup *button_group)
+{
+ BLI_freelistN(&button_group->buttons);
+ MEM_freeN(button_group);
+}
+
+/* This function should be removed whenever #ui_layout_replace_but_ptr is removed. */
+void ui_button_group_replace_but_ptr(uiLayout *layout, const void *old_but_ptr, uiBut *new_but)
+{
+ LISTBASE_FOREACH (uiButtonGroup *, button_group, &layout->root->button_groups) {
+ LISTBASE_FOREACH (LinkData *, link, &button_group->buttons) {
+ if (link->data == old_but_ptr) {
+ link->data = new_but;
+ return;
+ }
+ }
+ }
+
+ /* The button should be in a group. */
+ BLI_assert(false);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Special RNA Items
* \{ */
@@ -2019,6 +2084,7 @@ void uiItemFullR(uiLayout *layout,
#endif /* UI_PROP_DECORATE */
UI_block_layout_set_current(block, layout);
+ layout_root_new_button_group(layout->root);
/* retrieve info */
const PropertyType type = RNA_property_type(prop);
@@ -2769,6 +2835,8 @@ void uiItemPointerR_prop(uiLayout *layout,
char namestr[UI_MAX_NAME_STR];
const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
+ layout_root_new_button_group(layout->root);
+
type = RNA_property_type(prop);
if (!ELEM(type, PROP_POINTER, PROP_STRING, PROP_ENUM)) {
RNA_warning("Property %s.%s must be a pointer, string or enum",
@@ -2874,6 +2942,7 @@ static uiBut *ui_item_menu(uiLayout *layout,
int w, h;
UI_block_layout_set_current(block, layout);
+ layout_root_new_button_group(layout->root);
if (!name) {
name = "";
@@ -3141,6 +3210,7 @@ static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon)
int w;
UI_block_layout_set_current(block, layout);
+ layout_root_new_button_group(layout->root);
if (!name) {
name = "";
@@ -5306,6 +5376,16 @@ static void ui_layout_free(uiLayout *layout)
MEM_freeN(layout);
}
+static void layout_root_free(uiLayoutRoot *root)
+{
+ ui_layout_free(root->layout);
+
+ LISTBASE_FOREACH_MUTABLE (uiButtonGroup *, button_group, &root->button_groups) {
+ button_group_free(button_group);
+ }
+ MEM_freeN(root);
+}
+
static void ui_layout_add_padding_button(uiLayoutRoot *root)
{
if (root->padding) {
@@ -5340,6 +5420,9 @@ uiLayout *UI_block_layout(uiBlock *block,
root->padding = padding;
root->opcontext = WM_OP_INVOKE_REGION_WIN;
+ BLI_listbase_clear(&root->button_groups);
+ layout_root_new_button_group(root);
+
layout = MEM_callocN(sizeof(uiLayout), "uiLayout");
layout->item.type = (type == UI_LAYOUT_VERT_BAR) ? ITEM_LAYOUT_COLUMN : ITEM_LAYOUT_ROOT;
@@ -5424,6 +5507,8 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but)
if (layout->emboss != UI_EMBOSS_UNDEFINED) {
but->emboss = layout->emboss;
}
+
+ button_group_add_but(layout->root, but);
}
bool ui_layout_replace_but_ptr(uiLayout *layout, const void *old_but_ptr, uiBut *new_but)
@@ -5489,15 +5574,15 @@ void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y)
block->curlayout = NULL;
- LISTBASE_FOREACH (uiLayoutRoot *, root, &block->layouts) {
+ LISTBASE_FOREACH_MUTABLE (uiLayoutRoot *, root, &block->layouts) {
ui_layout_add_padding_button(root);
/* NULL in advance so we don't interfere when adding button */
ui_layout_end(block, root->layout, r_x, r_y);
- ui_layout_free(root->layout);
+ layout_root_free(root);
}
- BLI_freelistN(&block->layouts);
+ BLI_listbase_clear(&block->layouts);
/* XXX silly trick, interface_templates.c doesn't get linked
* because it's not used by other files in this module? */