UI: Support pressing Ctrl+F over UI lists to search
Adds an operator invoked by default with Ctrl+F that while hovering a UI list, opens the search field of the list and enables text input for it. With this commit the search button may actually be out of view after Ctrl+F still. The following commit adds auto-scroll to solve that. A downside is that in the Properties, there also is Ctrl+F to start the editor-wide search. That's not unusual in Blender though (e.g. scolling with the mouse over a UI list also scrolls the list, not the region).
This commit is contained in:
parent
87c1c8112f
commit
89fd3afd1e
Notes:
blender-bot
2023-02-14 09:02:41 +01:00
Referenced by issue #96705, Regression: Crash when pressing F3 outside a Blender window if Developer extras is on
|
@ -730,6 +730,8 @@ def km_user_interface(_params):
|
|||
("anim.keyingset_button_add", {"type": 'K', "value": 'PRESS'}, None),
|
||||
("anim.keyingset_button_remove", {"type": 'K', "value": 'PRESS', "alt": True}, None),
|
||||
("ui.reset_default_button", {"type": 'BACK_SPACE', "value": 'PRESS'}, {"properties": [("all", True)]}),
|
||||
# UI lists (polls check if there's a UI list under the cursor).
|
||||
("ui.list_start_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
|
||||
])
|
||||
|
||||
return keymap
|
||||
|
|
|
@ -74,6 +74,32 @@
|
|||
#include "ED_screen.h"
|
||||
#include "ED_text.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Immediate redraw helper
|
||||
*
|
||||
* Generally handlers shouldn't do any redrawing, that includes the layout/button definitions. That
|
||||
* violates the Model-View-Controller pattern.
|
||||
*
|
||||
* But there are some operators which really need to re-run the layout definitions for various
|
||||
* reasons. For example, "Edit Source" does it to find out which exact Python code added a button.
|
||||
* Other operators may need to access buttons that aren't currently visible. In Blender's UI code
|
||||
* design that typically means just not adding the button in the first place, for a particular
|
||||
* redraw. So the operator needs to change context and re-create the layout, so the button becomes
|
||||
* available to act on.
|
||||
*
|
||||
* \{ */
|
||||
|
||||
static void ui_region_redraw_immediately(bContext *C, ARegion *region)
|
||||
{
|
||||
ED_region_do_layout(C, region);
|
||||
WM_draw_region_viewport_bind(region);
|
||||
ED_region_do_draw(C, region);
|
||||
WM_draw_region_viewport_unbind(region);
|
||||
region->do_draw = false;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Copy Data Path Operator
|
||||
* \{ */
|
||||
|
@ -1379,11 +1405,7 @@ static int editsource_exec(bContext *C, wmOperator *op)
|
|||
ui_editsource_active_but_set(but);
|
||||
|
||||
/* redraw and get active button python info */
|
||||
ED_region_do_layout(C, region);
|
||||
WM_draw_region_viewport_bind(region);
|
||||
ED_region_do_draw(C, region);
|
||||
WM_draw_region_viewport_unbind(region);
|
||||
region->do_draw = false;
|
||||
ui_region_redraw_immediately(C, region);
|
||||
|
||||
for (BLI_ghashIterator_init(&ghi, ui_editsource_info->hash);
|
||||
BLI_ghashIterator_done(&ghi) == false;
|
||||
|
@ -1835,6 +1857,64 @@ static void UI_OT_drop_color(wmOperatorType *ot)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name UI List Search Operator
|
||||
* \{ */
|
||||
|
||||
static bool ui_list_focused_poll(bContext *C)
|
||||
{
|
||||
const ARegion *region = CTX_wm_region(C);
|
||||
const wmWindow *win = CTX_wm_window(C);
|
||||
const uiList *list = UI_list_find_mouse_over(region, win->eventstate);
|
||||
|
||||
return list != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the filter options are set to be visible in the UI list.
|
||||
* \return if the visibility changed, requiring a redraw.
|
||||
*/
|
||||
static bool ui_list_unhide_filter_options(uiList *list)
|
||||
{
|
||||
if (list->filter_flag & UILST_FLT_SHOW) {
|
||||
/* Nothing to be done. */
|
||||
return false;
|
||||
}
|
||||
|
||||
list->filter_flag |= UILST_FLT_SHOW;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ui_list_start_filter_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
|
||||
{
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
uiList *list = UI_list_find_mouse_over(region, event);
|
||||
/* Poll should check. */
|
||||
BLI_assert(list != NULL);
|
||||
|
||||
if (ui_list_unhide_filter_options(list)) {
|
||||
ui_region_redraw_immediately(C, region);
|
||||
}
|
||||
|
||||
if (!UI_textbutton_activate_rna(C, region, list, "filter_name")) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void UI_OT_list_start_filter(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "List Filter";
|
||||
ot->idname = "UI_OT_list_start_filter";
|
||||
ot->description = "Start entering filter text for the list in focus";
|
||||
|
||||
ot->invoke = ui_list_start_filter_invoke;
|
||||
ot->poll = ui_list_focused_poll;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Operator & Keymap Registration
|
||||
* \{ */
|
||||
|
@ -1860,6 +1940,8 @@ void ED_operatortypes_ui(void)
|
|||
WM_operatortype_append(UI_OT_button_execute);
|
||||
WM_operatortype_append(UI_OT_button_string_clear);
|
||||
|
||||
WM_operatortype_append(UI_OT_list_start_filter);
|
||||
|
||||
/* external */
|
||||
WM_operatortype_append(UI_OT_eyedropper_color);
|
||||
WM_operatortype_append(UI_OT_eyedropper_colorramp);
|
||||
|
|
Loading…
Reference in New Issue