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
diff options
context:
space:
mode:
-rw-r--r--source/blender/editors/include/UI_interface.h6
-rw-r--r--source/blender/editors/interface/interface_ops.c73
-rw-r--r--source/blender/editors/interface/interface_panel.c76
-rw-r--r--source/blender/editors/interface/interface_regions.c35
-rw-r--r--source/blender/editors/screen/screen_ops.c8
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/rna_access.c39
7 files changed, 178 insertions, 60 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 49e5845e3ca..26a6fdd7d1f 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1021,6 +1021,12 @@ void ED_keymap_ui(struct wmKeyConfig *keyconf);
void UI_drop_color_copy(struct wmDrag *drag, struct wmDropBox *drop);
int UI_drop_color_poll(struct bContext *C, struct wmDrag *drag, const struct wmEvent *event);
+/* UI_OT_space_context_cycle direction */
+enum {
+ SPACE_CONTEXT_CYCLE_PREV,
+ SPACE_CONTEXT_CYCLE_NEXT,
+};
+
bool UI_context_copy_to_selected_list(
struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
struct ListBase *r_lb, bool *r_use_path_from_id, char **r_path);
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 1af6d902b18..cb539bb1c5d 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -1082,6 +1082,78 @@ static void UI_OT_drop_color(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected ");
}
+/* ------------------------------------------------------------------------- */
+
+static EnumPropertyItem space_context_cycle_direction[] = {
+ {SPACE_CONTEXT_CYCLE_PREV, "PREV", 0, "Previous", ""},
+ {SPACE_CONTEXT_CYCLE_NEXT, "NEXT", 0, "Next", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static int space_context_cycle_poll(bContext *C)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ return ELEM(sa->spacetype, SPACE_BUTS, SPACE_USERPREF);
+}
+
+/**
+ * Helper to get the correct RNA pointer/property pair for changing
+ * the display context of active space type in \sa.
+ */
+static void context_cycle_prop_get(
+ bScreen *screen, const ScrArea *sa,
+ PointerRNA *r_ptr, PropertyRNA **r_prop)
+{
+ const char *propname;
+
+ switch (sa->spacetype) {
+ case SPACE_BUTS:
+ RNA_pointer_create(&screen->id, &RNA_SpaceProperties, sa->spacedata.first, r_ptr);
+ propname = "context";
+ break;
+ case SPACE_USERPREF:
+ RNA_pointer_create(NULL, &RNA_UserPreferences, &U, r_ptr);
+ propname = "active_section";
+ break;
+ }
+
+ *r_prop = RNA_struct_find_property(r_ptr, propname);
+}
+
+static int space_context_cycle_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ const int direction = RNA_enum_get(op->ptr, "direction");
+
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ context_cycle_prop_get(CTX_wm_screen(C), CTX_wm_area(C), &ptr, &prop);
+
+ const int old_context = RNA_property_enum_get(&ptr, prop);
+ const int new_context = RNA_property_enum_step(
+ C, &ptr, prop, old_context,
+ direction == SPACE_CONTEXT_CYCLE_PREV ? -1 : 1);
+ RNA_property_enum_set(&ptr, prop, new_context);
+ RNA_property_update(C, &ptr, prop);
+
+ return OPERATOR_FINISHED;
+}
+
+static void UI_OT_space_context_cycle(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Cycle Space Context";
+ ot->description = "Cycle through the editor context by activating the next/previous one";
+ ot->idname = "UI_OT_space_context_cycle";
+
+ /* api callbacks */
+ ot->invoke = space_context_cycle_invoke;
+ ot->poll = space_context_cycle_poll;
+
+ ot->flag = 0;
+
+ RNA_def_enum(ot->srna, "direction", space_context_cycle_direction, SPACE_CONTEXT_CYCLE_NEXT, "Direction",
+ "Direction to cycle through");
+}
/* ********************************************************* */
@@ -1102,6 +1174,7 @@ void ED_operatortypes_ui(void)
WM_operatortype_append(UI_OT_edittranslation_init);
#endif
WM_operatortype_append(UI_OT_reloadtranslation);
+ WM_operatortype_append(UI_OT_space_context_cycle);
/* external */
WM_operatortype_append(UI_OT_eyedropper_color);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 79961eae79d..c131bcb8e14 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -1841,6 +1841,52 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
#undef USE_FLAT_INACTIVE
}
+static int ui_handle_panel_category_cycling(const wmEvent *event, ARegion *ar, const uiBut *active_but)
+{
+ const bool is_mousewheel = ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE);
+ const bool inside_tabregion = (event->mval[0] < ((PanelCategoryDyn *)ar->panels_category.first)->rect.xmax);
+
+ /* if mouse is inside non-tab region, ctrl key is required */
+ if (is_mousewheel && !event->ctrl && !inside_tabregion)
+ return WM_UI_HANDLER_CONTINUE;
+
+
+ if (active_but && ui_but_supports_cycling(active_but)) {
+ /* skip - exception to make cycling buttons
+ * using ctrl+mousewheel work in tabbed regions */
+ }
+ else {
+ const char *category = UI_panel_category_active_get(ar, false);
+ if (LIKELY(category)) {
+ PanelCategoryDyn *pc_dyn = UI_panel_category_find(ar, category);
+ if (LIKELY(pc_dyn)) {
+ if (is_mousewheel) {
+ /* we can probably get rid of this and only allow ctrl+tabbing */
+ pc_dyn = (event->type == WHEELDOWNMOUSE) ? pc_dyn->next : pc_dyn->prev;
+ }
+ else {
+ const bool backwards = event->shift;
+ pc_dyn = backwards ? pc_dyn->prev : pc_dyn->next;
+ if (!pc_dyn) {
+ /* proper cyclic behavior, back to first/last category (only used for ctrl+tab) */
+ pc_dyn = backwards ? ar->panels_category.last : ar->panels_category.first;
+ }
+ }
+
+ if (pc_dyn) {
+ /* intentionally don't reset scroll in this case,
+ * this allows for quick browsing between tabs */
+ UI_panel_category_active_set(ar, pc_dyn->idname);
+ ED_region_tag_redraw(ar);
+ }
+ }
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
+}
+
/* XXX should become modal keymap */
/* AKey is opening/closing panels, independent of button state now */
@@ -1853,6 +1899,7 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar, cons
retval = WM_UI_HANDLER_CONTINUE;
+ /* handle category tabs */
if (has_category_tabs) {
if (event->val == KM_PRESS) {
if (event->type == LEFTMOUSE) {
@@ -1867,32 +1914,9 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar, cons
retval = WM_UI_HANDLER_BREAK;
}
}
- else if (ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
- /* mouse wheel cycle tabs */
-
- /* first check if the mouse is in the tab region */
- if (event->ctrl || (event->mval[0] < ((PanelCategoryDyn *)ar->panels_category.first)->rect.xmax)) {
- if (active_but && ui_but_supports_cycling(active_but)) {
- /* skip - exception to make cycling buttons
- * using ctrl+mousewheel work in tabbed regions */
- }
- else {
- const char *category = UI_panel_category_active_get(ar, false);
- if (LIKELY(category)) {
- PanelCategoryDyn *pc_dyn = UI_panel_category_find(ar, category);
- if (LIKELY(pc_dyn)) {
- pc_dyn = (event->type == WHEELDOWNMOUSE) ? pc_dyn->next : pc_dyn->prev;
- if (pc_dyn) {
- /* intentionally don't reset scroll in this case,
- * this allows for quick browsing between tabs */
- UI_panel_category_active_set(ar, pc_dyn->idname);
- ED_region_tag_redraw(ar);
- }
- }
- }
- retval = WM_UI_HANDLER_BREAK;
- }
- }
+ else if ((event->type == TABKEY && event->ctrl) || ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
+ /* cycle tabs */
+ retval = ui_handle_panel_category_cycling(event, ar, active_but);
}
}
}
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index c507401b9a0..4ea5e2092b6 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -73,38 +73,6 @@
#define MENU_PADDING (int)(0.2f * UI_UNIT_Y)
#define MENU_BORDER (int)(0.3f * U.widget_unit)
-static int rna_property_enum_step(const bContext *C, PointerRNA *ptr, PropertyRNA *prop, int direction)
-{
- EnumPropertyItem *item_array;
- int totitem;
- bool free;
- int value;
- int i, i_init;
- int step = (direction < 0) ? -1 : 1;
- int step_tot = 0;
-
- RNA_property_enum_items((bContext *)C, ptr, prop, &item_array, &totitem, &free);
- value = RNA_property_enum_get(ptr, prop);
- i = RNA_enum_from_value(item_array, value);
- i_init = i;
-
- do {
- i = mod_i(i + step, totitem);
- if (item_array[i].identifier[0]) {
- step_tot += step;
- }
- } while ((i != i_init) && (step_tot != direction));
-
- if (i != i_init) {
- value = item_array[i].value;
- }
-
- if (free) {
- MEM_freeN(item_array);
- }
-
- return value;
-}
bool ui_but_menu_step_poll(const uiBut *but)
{
@@ -122,7 +90,8 @@ int ui_but_menu_step(uiBut *but, int direction)
return but->menu_step_func(but->block->evil_C, direction, but->poin);
}
else {
- return rna_property_enum_step(but->block->evil_C, &but->rnapoin, but->rnaprop, direction);
+ const int curval = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
+ return RNA_property_enum_step(but->block->evil_C, &but->rnapoin, but->rnaprop, curval, direction);
}
}
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 6dbb5db53d0..e446194a1da 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -4331,7 +4331,13 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "SCREEN_OT_screenshot", F3KEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "SCREEN_OT_screencast", F3KEY, KM_PRESS, KM_ALT, 0);
-
+
+ /* UI */
+ kmi = WM_keymap_add_item(keymap, "UI_OT_space_context_cycle", TABKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_enum_set(kmi->ptr, "direction", SPACE_CONTEXT_CYCLE_NEXT);
+ kmi = WM_keymap_add_item(keymap, "UI_OT_space_context_cycle", TABKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "direction", SPACE_CONTEXT_CYCLE_PREV);
+
/* tests */
WM_keymap_add_item(keymap, "SCREEN_OT_region_quadview", QKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
WM_keymap_verify_item(keymap, "SCREEN_OT_repeat_history", F3KEY, KM_PRESS, 0, 0);
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 9cbe132282f..820465ee7d1 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -916,6 +916,7 @@ int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value);
int RNA_property_enum_get_default(PointerRNA *ptr, PropertyRNA *prop);
void *RNA_property_enum_py_data_get(PropertyRNA *prop);
+int RNA_property_enum_step(const struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int from_value, int direction);
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value);
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 047e5ea17ab..6879a0534e9 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -2873,6 +2873,45 @@ void *RNA_property_enum_py_data_get(PropertyRNA *prop)
return eprop->py_data;
}
+/**
+ * Get the value of the item that is \a step items away from \a from_value.
+ *
+ * \param from_value: Item value to start stepping from.
+ * \param step: Absolute value defines step size, sign defines direction.
+ * E.g to get the next item, pass 1, for the previous -1.
+ */
+int RNA_property_enum_step(const bContext *C, PointerRNA *ptr, PropertyRNA *prop, int from_value, int step)
+{
+ EnumPropertyItem *item_array;
+ int totitem;
+ bool free;
+ int result_value = from_value;
+ int i, i_init;
+ int single_step = (step < 0) ? -1 : 1;
+ int step_tot = 0;
+
+ RNA_property_enum_items((bContext *)C, ptr, prop, &item_array, &totitem, &free);
+ i = RNA_enum_from_value(item_array, from_value);
+ i_init = i;
+
+ do {
+ i = mod_i(i + single_step, totitem);
+ if (item_array[i].identifier[0]) {
+ step_tot += single_step;
+ }
+ } while ((i != i_init) && (step_tot != step));
+
+ if (i != i_init) {
+ result_value = item_array[i].value;
+ }
+
+ if (free) {
+ MEM_freeN(item_array);
+ }
+
+ return result_value;
+}
+
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
{
PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;