UI: support enum key shortcut detection
Shows shortcuts in space-selector.
This commit is contained in:
parent
a740cc53ea
commit
8055871e5b
|
@ -90,6 +90,7 @@
|
|||
|
||||
/* prototypes. */
|
||||
static void ui_but_to_pixelrect(struct rcti *rect, const struct ARegion *ar, struct uiBlock *block, struct uiBut *but);
|
||||
static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *but_p);
|
||||
|
||||
/* avoid unneeded calls to ui_but_value_get */
|
||||
#define UI_BUT_VALUE_UNSET DBL_MAX
|
||||
|
@ -1067,12 +1068,35 @@ static bool ui_but_event_property_operator_string(
|
|||
"WM_OT_context_menu_enum",
|
||||
NULL
|
||||
};
|
||||
const size_t num_ops = sizeof(ctx_toggle_opnames) / sizeof(const char *);
|
||||
|
||||
const char *ctx_enum_opnames[] = {
|
||||
"WM_OT_context_set_enum",
|
||||
NULL
|
||||
};
|
||||
|
||||
int prop_enum_value = -1;
|
||||
bool prop_enum_value_ok = false;
|
||||
PointerRNA *ptr = &but->rnapoin;
|
||||
PropertyRNA *prop = but->rnaprop;
|
||||
if ((but->type == UI_BTYPE_BUT_MENU) && (but->block->handle != NULL)) {
|
||||
uiBut *but_parent = but->block->handle->popup_create_vars.but;
|
||||
if ((but->type == UI_BTYPE_BUT_MENU) &&
|
||||
but_parent && (but_parent->menu_create_func == ui_def_but_rna__menu))
|
||||
{
|
||||
prop_enum_value = (int)but->hardmin;
|
||||
ptr = &but->block->handle->popup_create_vars.but->rnapoin;
|
||||
prop = but->block->handle->popup_create_vars.but->rnaprop;
|
||||
prop_enum_value_ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
|
||||
/* Don't use the button again. */
|
||||
but = NULL;
|
||||
|
||||
/* this version is only for finding hotkeys for properties (which get set via context using operators) */
|
||||
if (but->rnaprop) {
|
||||
if (prop) {
|
||||
/* to avoid massive slowdowns on property panels, for now, we only check the
|
||||
* hotkeys for Editor / Scene settings...
|
||||
*
|
||||
|
@ -1081,40 +1105,51 @@ static bool ui_but_event_property_operator_string(
|
|||
// TODO: value (for enum stuff)?
|
||||
char *data_path = NULL;
|
||||
|
||||
if (but->rnapoin.id.data) {
|
||||
ID *id = but->rnapoin.id.data;
|
||||
if (ptr->id.data) {
|
||||
ID *id = ptr->id.data;
|
||||
|
||||
if (GS(id->name) == ID_SCR) {
|
||||
/* screen/editor property
|
||||
* NOTE: in most cases, there is actually no info for backwards tracing
|
||||
* how to get back to ID from the editor data we may be dealing with
|
||||
*/
|
||||
if (RNA_struct_is_a(but->rnapoin.type, &RNA_Space)) {
|
||||
if (RNA_struct_is_a(ptr->type, &RNA_Space)) {
|
||||
/* data should be directly on here... */
|
||||
data_path = BLI_sprintfN("space_data.%s", RNA_property_identifier(but->rnaprop));
|
||||
data_path = BLI_sprintfN("space_data.%s", RNA_property_identifier(prop));
|
||||
}
|
||||
else if (RNA_struct_is_a(ptr->type, &RNA_Area)) {
|
||||
/* data should be directly on here... */
|
||||
const char *prop_id = RNA_property_identifier(prop);
|
||||
/* Hack since keys access 'type'. */
|
||||
if (STREQ(prop_id, "ui_type")) {
|
||||
prop_id = "type";
|
||||
prop_enum_value >>= 16;
|
||||
prop = RNA_struct_find_property(ptr, prop_id);
|
||||
}
|
||||
data_path = BLI_sprintfN("area.%s", prop_id);
|
||||
}
|
||||
else {
|
||||
/* special exceptions for common nested data in editors... */
|
||||
if (RNA_struct_is_a(but->rnapoin.type, &RNA_DopeSheet)) {
|
||||
if (RNA_struct_is_a(ptr->type, &RNA_DopeSheet)) {
|
||||
/* dopesheet filtering options... */
|
||||
data_path = BLI_sprintfN("space_data.dopesheet.%s", RNA_property_identifier(but->rnaprop));
|
||||
data_path = BLI_sprintfN("space_data.dopesheet.%s", RNA_property_identifier(prop));
|
||||
}
|
||||
else if (RNA_struct_is_a(but->rnapoin.type, &RNA_FileSelectParams)) {
|
||||
else if (RNA_struct_is_a(ptr->type, &RNA_FileSelectParams)) {
|
||||
/* Filebrowser options... */
|
||||
data_path = BLI_sprintfN("space_data.params.%s", RNA_property_identifier(but->rnaprop));
|
||||
data_path = BLI_sprintfN("space_data.params.%s", RNA_property_identifier(prop));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (GS(id->name) == ID_SCE) {
|
||||
if (RNA_struct_is_a(but->rnapoin.type, &RNA_ToolSettings)) {
|
||||
if (RNA_struct_is_a(ptr->type, &RNA_ToolSettings)) {
|
||||
/* toolsettings property
|
||||
* NOTE: toolsettings is usually accessed directly (i.e. not through scene)
|
||||
*/
|
||||
data_path = RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop);
|
||||
data_path = RNA_path_from_ID_to_property(ptr, prop);
|
||||
}
|
||||
else {
|
||||
/* scene property */
|
||||
char *path = RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop);
|
||||
char *path = RNA_path_from_ID_to_property(ptr, prop);
|
||||
|
||||
if (path) {
|
||||
data_path = BLI_sprintfN("scene.%s", path);
|
||||
|
@ -1123,7 +1158,7 @@ static bool ui_but_event_property_operator_string(
|
|||
#if 0
|
||||
else {
|
||||
printf("ERROR in %s(): Couldn't get path for scene property - %s\n",
|
||||
__func__, RNA_property_identifier(but->rnaprop));
|
||||
__func__, RNA_property_identifier(prop));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1132,26 +1167,50 @@ static bool ui_but_event_property_operator_string(
|
|||
//puts("other id");
|
||||
}
|
||||
|
||||
//printf("prop shortcut: '%s' (%s)\n", RNA_property_identifier(but->rnaprop), data_path);
|
||||
//printf("prop shortcut: '%s' (%s)\n", RNA_property_identifier(prop), data_path);
|
||||
}
|
||||
|
||||
/* we have a datapath! */
|
||||
if (data_path) {
|
||||
size_t i;
|
||||
|
||||
/* create a property to host the "datapath" property we're sending to the operators */
|
||||
IDProperty *prop_path;
|
||||
IDProperty *prop_path_value;
|
||||
|
||||
IDPropertyTemplate val = {0};
|
||||
prop_path = IDP_New(IDP_GROUP, &val, __func__);
|
||||
prop_path_value = IDP_NewString(data_path, "data_path", strlen(data_path) + 1);
|
||||
IDP_AddToGroup(prop_path, prop_path_value);
|
||||
IDP_AddToGroup(prop_path, IDP_NewString(data_path, "data_path", strlen(data_path) + 1));
|
||||
|
||||
const char **opnames;
|
||||
int opnames_len;
|
||||
|
||||
if (prop_enum_value_ok && prop && RNA_property_type(prop) == PROP_ENUM) {
|
||||
opnames_len = ARRAY_SIZE(ctx_enum_opnames) - 1;
|
||||
opnames = ctx_enum_opnames;
|
||||
|
||||
const EnumPropertyItem *item;
|
||||
bool free;
|
||||
RNA_property_enum_items((bContext *)C, ptr, prop, &item, NULL, &free);
|
||||
int index = RNA_enum_from_value(item, prop_enum_value);
|
||||
if (index != -1) {
|
||||
const char *id = item[index].identifier;
|
||||
IDP_AddToGroup(prop_path, IDP_NewString(id, "value", strlen(id) + 1));
|
||||
}
|
||||
else {
|
||||
opnames_len = 0; /* Do nothing. */
|
||||
}
|
||||
if (free) {
|
||||
MEM_freeN((void *)item);
|
||||
}
|
||||
}
|
||||
else {
|
||||
opnames_len = ARRAY_SIZE(ctx_toggle_opnames) - 1;
|
||||
opnames = ctx_toggle_opnames;
|
||||
}
|
||||
|
||||
/* check each until one works... */
|
||||
for (i = 0; (i < num_ops) && (ctx_toggle_opnames[i]); i++) {
|
||||
|
||||
for (int i = 0; (i < opnames_len) && (opnames[i]); i++) {
|
||||
if (WM_key_event_operator_string(
|
||||
C, ctx_toggle_opnames[i], WM_OP_INVOKE_REGION_WIN, prop_path, false,
|
||||
C, opnames[i], WM_OP_INVOKE_REGION_WIN, prop_path, false,
|
||||
buf, buf_len))
|
||||
{
|
||||
found = true;
|
||||
|
|
Loading…
Reference in New Issue