Refactor 'immediate search' feature
authorBastien Montagne <montagne29@wanadoo.fr>
Thu, 25 Dec 2014 11:53:13 +0000 (12:53 +0100)
committerBastien Montagne <montagne29@wanadoo.fr>
Thu, 25 Dec 2014 11:55:29 +0000 (12:55 +0100)
Currently, code just checks whether a text-edited button uses a given icon (VIEWZOOM) to decide to apply changes on each typed char.

This patch adds a propper button flag (UI_BUT_TEXTEDIT_UPDATE) and a dedicated RNA flag (PROP_TEXTEDIT_UPDATE) for that.
It's also now usable not only for text buttons, but also for example for num buttons when in 'text edit' mode, etc.

It also fixes an actual bug, which is for text properties, in 'immediate' mode, hitting escape would not restore org value, because `ui_apply_but_TEX()` would set its orgstr to NULL on first call (giving it to `but->rename_orig` instead of copying it).

Note no change in behavior is expected from user POV.
Update for addons using that 'VIEWZOOM' icon 'feature' will follow (if any).

Reviewers: campbellbarton

Reviewed By: campbellbarton

Projects: #user_interface, #bf_blender:_next

Differential Revision: https://developer.blender.org/D938

release/scripts/startup/bl_ui/__init__.py
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_utils.c
source/blender/makesrna/RNA_types.h
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_ui.c
source/blender/python/intern/bpy_props.c

index 6174dd95f2a9d4ee2e8a114d5529078aa8989689..99b1a7a090ae31227b43bde1c610b01a587d861a 100644 (file)
@@ -117,6 +117,7 @@ def register():
     WindowManager.addon_search = StringProperty(
             name="Search",
             description="Search within the selected filter",
+            options={'TEXTEDIT_UPDATE'},
             )
     WindowManager.addon_filter = EnumProperty(
             items=addon_filter_items,
index 2251f3fd0e42d3d61d20dc6b7d72e5bd909a3fc9..8789e837f176a087eb99a59660d3679500c033be 100644 (file)
@@ -159,31 +159,32 @@ enum {
 /* but->flag - general state flags. */
 enum {
        /* warning, the first 6 flags are internal */
-       UI_BUT_ICON_SUBMENU  = (1 << 6),
-       UI_BUT_ICON_PREVIEW  = (1 << 7),
-
-       UI_BUT_NODE_LINK     = (1 << 8),
-       UI_BUT_NODE_ACTIVE   = (1 << 9),
-       UI_BUT_DRAG_LOCK     = (1 << 10),
-       UI_BUT_DISABLED      = (1 << 11),
-       UI_BUT_COLOR_LOCK    = (1 << 12),
-       UI_BUT_ANIMATED      = (1 << 13),
-       UI_BUT_ANIMATED_KEY  = (1 << 14),
-       UI_BUT_DRIVEN        = (1 << 15),
-       UI_BUT_REDALERT      = (1 << 16),
-       UI_BUT_INACTIVE      = (1 << 17),
-       UI_BUT_LAST_ACTIVE   = (1 << 18),
-       UI_BUT_UNDO          = (1 << 19),
-       UI_BUT_IMMEDIATE     = (1 << 20),
-       UI_BUT_NO_UTF8       = (1 << 21),
-
-       UI_BUT_VEC_SIZE_LOCK = (1 << 22),  /* used to flag if color hsv-circle should keep luminance */
-       UI_BUT_COLOR_CUBIC   = (1 << 23),  /* cubic saturation for the color wheel */
-       UI_BUT_LIST_ITEM     = (1 << 24),  /* This but is "inside" a list item (currently used to change theme colors). */
-       UI_BUT_DRAG_MULTI    = (1 << 25),  /* edit this button as well as the active button (not just dragging) */
-       UI_BUT_SCA_LINK_GREY = (1 << 26),  /* used to flag if sca links shoud be grey out */
-       UI_BUT_HAS_SEP_CHAR  = (1 << 27),  /* but->str contains UI_SEP_CHAR, used for key shortcuts */
-       UI_BUT_TIP_FORCE     = (1 << 28),  /* force show tooltips when holding option/alt if U's USER_TOOLTIPS is off */
+       UI_BUT_ICON_SUBMENU    = (1 << 6),
+       UI_BUT_ICON_PREVIEW    = (1 << 7),
+
+       UI_BUT_NODE_LINK       = (1 << 8),
+       UI_BUT_NODE_ACTIVE     = (1 << 9),
+       UI_BUT_DRAG_LOCK       = (1 << 10),
+       UI_BUT_DISABLED        = (1 << 11),
+       UI_BUT_COLOR_LOCK      = (1 << 12),
+       UI_BUT_ANIMATED        = (1 << 13),
+       UI_BUT_ANIMATED_KEY    = (1 << 14),
+       UI_BUT_DRIVEN          = (1 << 15),
+       UI_BUT_REDALERT        = (1 << 16),
+       UI_BUT_INACTIVE        = (1 << 17),
+       UI_BUT_LAST_ACTIVE     = (1 << 18),
+       UI_BUT_UNDO            = (1 << 19),
+       UI_BUT_IMMEDIATE       = (1 << 20),
+       UI_BUT_NO_UTF8         = (1 << 21),
+
+       UI_BUT_VEC_SIZE_LOCK   = (1 << 22),  /* used to flag if color hsv-circle should keep luminance */
+       UI_BUT_COLOR_CUBIC     = (1 << 23),  /* cubic saturation for the color wheel */
+       UI_BUT_LIST_ITEM       = (1 << 24),  /* This but is "inside" a list item (currently used to change theme colors). */
+       UI_BUT_DRAG_MULTI      = (1 << 25),  /* edit this button as well as the active button (not just dragging) */
+       UI_BUT_SCA_LINK_GREY   = (1 << 26),  /* used to flag if sca links shoud be grey out */
+       UI_BUT_HAS_SEP_CHAR    = (1 << 27),  /* but->str contains UI_SEP_CHAR, used for key shortcuts */
+       UI_BUT_TIP_FORCE       = (1 << 28),  /* force show tooltips when holding option/alt if U's USER_TOOLTIPS is off */
+       UI_BUT_TEXTEDIT_UPDATE = (1 << 29),  /* when widget is in textedit mode, update value on each char stroke */
 };
 
 #define UI_PANEL_WIDTH          340
index 86414d989518f6793867d77d76388e45e4dad050..c7ceea05b4f3ae6fbe94f983a833fbf6e07ef1e9 100644 (file)
@@ -784,11 +784,18 @@ static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data)
        ui_but_string_set(C, but, data->str);
        ui_but_update(but);
 
-       /* give butfunc the original text too */
-       /* feature used for bone renaming, channels, etc */
-       /* afterfunc frees origstr */
-       but->rename_orig = data->origstr;
-       data->origstr = NULL;
+       /* give butfunc a copy of the original text too.
+        * feature used for bone renaming, channels, etc.
+        * afterfunc frees rename_orig */
+       if (data->origstr && (but->flag & UI_BUT_TEXTEDIT_UPDATE)) {
+               /* In this case, we need to keep origstr available, to restore real org string in case we cancel after
+                * having typed something already. */
+               but->rename_orig = BLI_strdup(data->origstr);
+       }
+       else {
+               but->rename_orig = data->origstr;
+               data->origstr = NULL;
+       }
        ui_apply_but_func(C, but);
 
        data->retval = but->retval;
@@ -2891,9 +2898,10 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                        retval = WM_UI_HANDLER_BREAK;
                        
                }
-               /* textbutton with magnifier icon: do live update for search button */
-               if (but->icon == ICON_VIEWZOOM)
+               /* textbutton with this flag: do live update (e.g. for search buttons) */
+               if (but->flag & UI_BUT_TEXTEDIT_UPDATE) {
                        update = true;
+               }
        }
 
 #ifdef WITH_INPUT_IME
index 6cd5f5a7e05580c6e21e9d46822c02aeb310aaab..c083a280763f0898ed66d0987962945c5e0b6481 100644 (file)
@@ -90,6 +90,10 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
                                but = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
                        else
                                but = uiDefButR_prop(block, UI_BTYPE_NUM, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+
+                       if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
+                               UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE);
+                       }
                        break;
                }
                case PROP_ENUM:
@@ -107,6 +111,10 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
                                but = uiDefIconTextButR_prop(block, UI_BTYPE_TEXT, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
                        else
                                but = uiDefButR_prop(block, UI_BTYPE_TEXT, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+
+                       if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
+                               UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE);
+                       }
                        break;
                case PROP_POINTER:
                {
index 83f3870c29ab5e643e34800ee96494fce5d44b0a..a9c0f591858e6d61109e26052e7b65a5c2b7ed12 100644 (file)
@@ -147,7 +147,7 @@ typedef enum PropertySubType {
 } PropertySubType;
 
 /* Make sure enums are updated with these */
-/* HIGHEST FLAG IN USE: 1 << 30 */
+/* HIGHEST FLAG IN USE: 1 << 31 */
 typedef enum PropertyFlag {
        /* editable means the property is editable in the user
         * interface, properties are editable by default except
@@ -165,6 +165,10 @@ typedef enum PropertyFlag {
         * and collections */
        PROP_ANIMATABLE              = (1 << 1),
 
+       /* This flag means when the property's widget is in 'textedit' mode, it will be updated after every typed char,
+        * instead of waiting final validation. Used e.g. for text searchbox. */
+       PROP_TEXTEDIT_UPDATE         = (1 << 31),
+
        /* icon */
        PROP_ICONS_CONSECUTIVE       = (1 << 12),
 
index 17d4c1bfebb9c57b555d38aac36828811e5b12e5..86beec78d3375da39ffcfb0bbd2781d8b90f1337 100644 (file)
@@ -1588,6 +1588,7 @@ static void rna_def_space_outliner(BlenderRNA *brna)
        prop = RNA_def_property(srna, "filter_text", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "search_string");
        RNA_def_property_ui_text(prop, "Display Filter", "Live search filtering string");
+       RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
        RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
        
        prop = RNA_def_property(srna, "use_filter_case_sensitive", PROP_BOOLEAN, PROP_NONE);
@@ -3376,6 +3377,7 @@ static void rna_def_space_userpref(BlenderRNA *brna)
 
        prop = RNA_def_property(srna, "filter_text", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "filter");
+       RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
        RNA_def_property_ui_text(prop, "Filter", "Search term for filtering in the UI");
 
 }
index 92c5530202bfb960772f038abafed8489632bcf1..a61846fa028c75c9461236fff0469ae019d82aed 100644 (file)
@@ -1062,6 +1062,7 @@ static void rna_def_uilist(BlenderRNA *brna)
 
        prop = RNA_def_property(srna, "filter_name", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "filter_byname");
+       RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
        RNA_def_property_ui_text(prop, "Filter by Name", "Only show items matching this name (use '*' as wildcard)");
 
        prop = RNA_def_property(srna, "use_filter_invert", PROP_BOOLEAN, PROP_NONE);
index b0232a4211c3e588bf87e2392f6f4bbb9260a3f2..b536e91bca8cf7aee681770dc2bfa174a61c01f9 100644 (file)
@@ -64,6 +64,7 @@ static EnumPropertyItem property_flag_items[] = {
        {PROP_ANIMATABLE, "ANIMATABLE", 0, "Animatable", ""},
        {PROP_LIB_EXCEPTION, "LIBRARY_EDITABLE", 0, "Library Editable", ""},
        {PROP_PROPORTIONAL, "PROPORTIONAL", 0, "Adjust values proportionally to eachother", ""},
+       {PROP_TEXTEDIT_UPDATE, "TEXTEDIT_UPDATE", 0, "Update on every keystroke in textedit 'mode'", ""},
        {0, NULL, 0, NULL, NULL}};
 
 #define BPY_PROPDEF_OPTIONS_DOC \