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:
authorJulian Eisel <julian@blender.org>2022-04-26 23:26:15 +0300
committerJulian Eisel <julian@blender.org>2022-04-26 23:26:15 +0300
commit83c8f996f1618a51496100dc680a877a89be7a4e (patch)
treed4592e88ad598c18084489940fcc79c5a3fa4bcc
parent5fe1624b0eba8267325f166de8e75c4d2dd6989b (diff)
UI: Add callback for comparing button identity
The code to compare buttons from the previous to the current frame, to see if they match (an thus should keep the same state) was quite generic, and didn't allow much flexibility/customization. For some cases this isn't enough, and a more specific comparison is needed. Say if some buttons don't actually store comparable data themselves, only via the button context. This was the case in D14653.
-rw-r--r--source/blender/editors/include/UI_interface.h16
-rw-r--r--source/blender/editors/interface/interface.cc13
-rw-r--r--source/blender/editors/interface/interface_intern.h3
-rw-r--r--source/blender/editors/interface/interface_utils.cc5
4 files changed, 37 insertions, 0 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 94453ef5fac..1b817d06564 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -508,6 +508,10 @@ typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2);
typedef void (*uiButHandleHoldFunc)(struct bContext *C, struct ARegion *butregion, uiBut *but);
typedef int (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
+/** Function to compare the identity of two buttons over redraws, to check if they represent the
+ * same data, and thus should be considered the same button over redraws. */
+typedef bool (*uiButIdentityCompareFunc)(const uiBut *a, const uiBut *b);
+
/* Search types. */
typedef struct ARegion *(*uiButSearchCreateFn)(struct bContext *C,
struct ARegion *butregion,
@@ -1650,6 +1654,18 @@ eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout,
bool compact);
/**
+ * Callback to compare the identity of two buttons, used to identify buttons over redraws. If the
+ * callback returns true, the given buttons are considered to be matching and relevant state is
+ * preserved (copied from the old to the new button). If it returns false, it's considered
+ * non-matching and no further checks are done.
+ *
+ * If this is set, it is always executed instead of the default comparisons. However it is only
+ * executed for buttons that have the same type and the same callback. So callbacks can assume the
+ * button types match.
+ */
+void UI_but_func_identity_compare_set(uiBut *but, uiButIdentityCompareFunc cmp_fn);
+
+/**
* Public function exported for functions that use #UI_BTYPE_SEARCH_MENU.
*
* Use inside searchfunc to add items.
diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc
index 9310ede31fa..b7098c26bcd 100644
--- a/source/blender/editors/interface/interface.cc
+++ b/source/blender/editors/interface/interface.cc
@@ -725,6 +725,19 @@ bool ui_but_rna_equals_ex(const uiBut *but,
/* NOTE: if `but->poin` is allocated memory for every `uiDefBut*`, things fail. */
static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
{
+ if (but->identity_cmp_func) {
+ /* If the buttons have own identity comparator callbacks (and they match), use this to
+ * determine equality. */
+ if (but->identity_cmp_func && (but->type == oldbut->type) &&
+ (but->identity_cmp_func == oldbut->identity_cmp_func)) {
+ /* Test if the comparison is symmetrical (if a == b then b == a), may help catch some issues.
+ */
+ BLI_assert(but->identity_cmp_func(but, oldbut) == but->identity_cmp_func(oldbut, but));
+
+ return but->identity_cmp_func(but, oldbut);
+ }
+ }
+
/* various properties are being compared here, hopefully sufficient
* to catch all cases, but it is simple to add more checks later */
if (but->retval != oldbut->retval) {
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 05acdac3597..c09ff68bbca 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -183,6 +183,9 @@ struct uiBut {
uchar col[4];
+ /** See \ref UI_but_func_identity_compare_set(). */
+ uiButIdentityCompareFunc identity_cmp_func;
+
uiButHandleFunc func;
void *func_arg1;
void *func_arg2;
diff --git a/source/blender/editors/interface/interface_utils.cc b/source/blender/editors/interface/interface_utils.cc
index c59863f462a..993ccdf92f7 100644
--- a/source/blender/editors/interface/interface_utils.cc
+++ b/source/blender/editors/interface/interface_utils.cc
@@ -452,6 +452,11 @@ eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout,
return return_info;
}
+void UI_but_func_identity_compare_set(uiBut *but, uiButIdentityCompareFunc cmp_fn)
+{
+ but->identity_cmp_func = cmp_fn;
+}
+
/* *** RNA collection search menu *** */
struct CollItemSearch {