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
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2018-11-29 09:32:35 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-11-29 09:32:35 +0300
commit8055871e5be765958d11160e086c0e5589fefe48 (patch)
tree02fecc6dc7b13908665f57a7feafdc9dc56d14f6 /source
parenta740cc53ea1061fde58ca0a36986fc04bfe1dad7 (diff)
UI: support enum key shortcut detection
Shows shortcuts in space-selector.
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/interface/interface.c103
1 files changed, 81 insertions, 22 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 6fc627d3847..aeee93b055b 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -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(prop));
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_Area)) {
/* data should be directly on here... */
- data_path = BLI_sprintfN("space_data.%s", RNA_property_identifier(but->rnaprop));
+ 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;