Animation UI: Make Ctrl+F use textbox instead of pop-up

Avoid blocking the UI when searching for animation channels with Ctrl+F.

Instead of showing a single text input in a blocking popup, Ctrl+F now
just focuses the search box above the channel list. It feels nicer to
use and has the niceties that come from using that textbox, like
searching per keystroke, compared to the old pop-up method.

As the behaviour of the operator has changed considerably, this also
changes the operator name from `anim.channels_find` to
`anim.channels_select_filter` and updates the keymaps.

Reviewed By: ChrisLend, sybren

Differential Revision: https://developer.blender.org/D12146
This commit is contained in:
bird_d 2021-10-26 11:14:06 +02:00 committed by Sybren A. Stüvel
parent 816d3f830b
commit 41a4c62c31
3 changed files with 47 additions and 48 deletions

View File

@ -1637,7 +1637,7 @@ def km_graph_editor_generic(_params):
sidebar_key={"type": 'N', "value": 'PRESS'},
),
("graph.extrapolation_type", {"type": 'E', "value": 'PRESS', "shift": True}, None),
("anim.channels_find", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
("anim.channels_select_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
*_template_items_hide_reveal_actions("graph.hide", "graph.reveal"),
("wm.context_set_enum", {"type": 'TAB', "value": 'PRESS', "ctrl": True},
{"properties": [("data_path", 'area.type'), ("value", 'DOPESHEET_EDITOR')]}),
@ -2359,7 +2359,7 @@ def km_dopesheet(params):
("action.view_selected", {"type": 'NUMPAD_PERIOD', "value": 'PRESS'}, None),
("action.view_frame", {"type": 'NUMPAD_0', "value": 'PRESS'}, None),
("anim.channels_editable_toggle", {"type": 'TAB', "value": 'PRESS'}, None),
("anim.channels_find", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
("anim.channels_select_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
("transform.transform", {"type": 'G', "value": 'PRESS'},
{"properties": [("mode", 'TIME_TRANSLATE')]}),
("transform.transform", {"type": params.select_tweak, "value": 'ANY'},
@ -2400,7 +2400,7 @@ def km_nla_generic(_params):
{"properties": [("isolate_action", True)]}),
("nla.tweakmode_exit", {"type": 'TAB', "value": 'PRESS', "shift": True},
{"properties": [("isolate_action", True)]}),
("anim.channels_find", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
("anim.channels_select_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
])
return keymap
@ -3328,7 +3328,7 @@ def km_animation_channels(params):
("anim.channel_select_keys", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK', "shift": True},
{"properties": [("extend", True)]}),
# Find (setting the name filter).
("anim.channels_find", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
("anim.channels_select_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
# Selection.
*_template_items_select_actions(params, "anim.channels_select_all"),
("anim.channels_select_box", {"type": 'B', "value": 'PRESS'}, None),

View File

@ -875,7 +875,7 @@ def km_graph_editor_generic(params):
items.extend([
op_panel("TOPBAR_PT_name", {"type": 'RET', "value": 'PRESS'}, [("keep_open", False)]),
("anim.channels_find", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
("anim.channels_select_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
("graph.hide", {"type": 'H', "value": 'PRESS', "ctrl": True},
{"properties": [("unselected", False)]}),
("graph.hide", {"type": 'H', "value": 'PRESS', "shift": True},
@ -1439,7 +1439,7 @@ def km_dopesheet(params):
("action.view_selected", {"type": 'F', "value": 'PRESS'}, None),
("action.view_frame", {"type": 'NUMPAD_0', "value": 'PRESS'}, None),
("anim.channels_editable_toggle", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None),
("anim.channels_find", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
("anim.channels_select_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
("transform.transform", {"type": 'W', "value": 'PRESS'},
{"properties": [("mode", 'TIME_TRANSLATE')]}),
("transform.transform", {"type": 'EVT_TWEAK_L', "value": 'ANY'},
@ -1477,7 +1477,7 @@ def km_nla_generic(params):
*_template_items_animation(),
("nla.tweakmode_enter", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None),
("nla.tweakmode_exit", {"type": 'ESC', "value": 'PRESS'}, None),
("anim.channels_find", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
("anim.channels_select_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
])
return keymap
@ -2234,7 +2234,7 @@ def km_animation_channels(params):
("anim.channel_select_keys", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK', "shift": True},
{"properties": [("extend", True)]}),
# Find (setting the name filter).
("anim.channels_find", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
("anim.channels_select_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
# Selection.
("anim.channels_select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}),
("anim.channels_select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}),

View File

@ -51,6 +51,7 @@
#include "BKE_mask.h"
#include "BKE_nla.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
@ -2522,10 +2523,10 @@ static void ANIM_OT_channels_fcurves_enable(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ****************** Find / Set Filter Operator ******************** */
/* ****************** Select Filter Textbox Operator ******************** */
/* XXX: make this generic? */
static bool animchannels_find_poll(bContext *C)
static bool animchannels_select_filter_poll(bContext *C)
{
ScrArea *area = CTX_wm_area(C);
@ -2537,64 +2538,62 @@ static bool animchannels_find_poll(bContext *C)
return ELEM(area->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA);
}
/* find_invoke() - Get initial channels */
static int animchannels_find_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int animchannels_select_filter_invoke(struct bContext *C,
struct wmOperator *op,
const struct wmEvent *UNUSED(event))
{
bAnimContext ac;
ScrArea *area = CTX_wm_area(C);
ARegion *region_ctx = CTX_wm_region(C);
ARegion *region_channels = BKE_area_find_region_type(area, RGN_TYPE_CHANNELS);
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0) {
return OPERATOR_CANCELLED;
CTX_wm_region_set(C, region_channels);
/* Show the channel region if it's hidden. This means that direct activation of the input field
* is impossible, as it may not exist yet. For that reason, the actual activation is deferred to
* the modal callback function; by the time it runs, the screen has been redrawn and the UI
* element is there to activate. */
if (region_channels->flag & RGN_FLAG_HIDDEN) {
ED_region_toggle_hidden(C, region_channels);
ED_region_tag_redraw(region_channels);
}
/* set initial filter text, and enable filter */
RNA_string_set(op->ptr, "query", ac.ads->searchstr);
WM_event_add_modal_handler(C, op);
/* defer to popup */
return WM_operator_props_popup(C, op, event);
CTX_wm_region_set(C, region_ctx);
return OPERATOR_RUNNING_MODAL;
}
/* find_exec() - Called to set the value */
static int animchannels_find_exec(bContext *C, wmOperator *op)
static int animchannels_select_filter_modal(bContext *C,
wmOperator *UNUSED(op),
const wmEvent *UNUSED(event))
{
bAnimContext ac;
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0) {
return OPERATOR_CANCELLED;
}
/* update filter text */
RNA_string_get(op->ptr, "query", ac.ads->searchstr);
/* redraw */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
ARegion *region = CTX_wm_region(C);
if (UI_textbutton_activate_rna(C, region, ac.ads, "filter_text")) {
/* Redraw to make sure it shows the cursor after activating */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
}
return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_find(wmOperatorType *ot)
static void ANIM_OT_channels_select_filter(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Find Channels";
ot->idname = "ANIM_OT_channels_find";
ot->description = "Filter the set of channels shown to only include those with matching names";
ot->name = "Filter Channels";
ot->idname = "ANIM_OT_channels_select_filter";
ot->description =
"Start entering text which filters the set of channels shown to only include those with "
"matching names";
/* callbacks */
ot->invoke = animchannels_find_invoke;
ot->exec = animchannels_find_exec;
ot->poll = animchannels_find_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
ot->prop = RNA_def_string(ot->srna,
"query",
"Query",
sizeof(((bDopeSheet *)NULL)->searchstr),
"",
"Text to search for in channel names");
ot->invoke = animchannels_select_filter_invoke;
ot->modal = animchannels_select_filter_modal;
ot->poll = animchannels_select_filter_poll;
}
/* ********************** Select All Operator *********************** */
@ -3563,7 +3562,7 @@ void ED_operatortypes_animchannels(void)
WM_operatortype_append(ANIM_OT_channel_select_keys);
WM_operatortype_append(ANIM_OT_channels_rename);
WM_operatortype_append(ANIM_OT_channels_find);
WM_operatortype_append(ANIM_OT_channels_select_filter);
WM_operatortype_append(ANIM_OT_channels_setting_enable);
WM_operatortype_append(ANIM_OT_channels_setting_disable);