[Bf-blender-cvs] [5d7d55c] temp_pie_max_items_fix: Pies: Support object mode pie with more than 8 items
Julian Eisel
noreply at git.blender.org
Mon Feb 15 17:04:26 CET 2016
Commit: 5d7d55c1ef627f2769a2e80e3e5aa6636a8d9b32
Author: Julian Eisel
Date: Mon Feb 15 15:28:56 2016 +0100
Branches: temp_pie_max_items_fix
https://developer.blender.org/rB5d7d55c1ef627f2769a2e80e3e5aa6636a8d9b32
Pies: Support object mode pie with more than 8 items
Fixes changing position of items introduced in rB669fdca6818b.
Since release is comming closer, I decided to try implementing support for more than 8 items per pie. This would require bigger changes which might not be safe to apply before relase though. For now, this should be good enough.
There are a few ugly things in the patch, but improving would not be trivial and require bigger changes. Was already tricky enough to get this working ;)
Reviewers: campbellbarton
Projects: #user_interface
Differential Revision: https://developer.blender.org/D1800
===================================================================
M source/blender/editors/include/UI_interface.h
M source/blender/editors/interface/interface_intern.h
M source/blender/editors/interface/interface_layout.c
M source/blender/editors/interface/interface_regions.c
===================================================================
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 617b0d1..8c89b5d 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -978,6 +978,10 @@ void uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *pr
void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname);
void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, struct PointerRNA *searchptr, const char *searchpropname, const char *name, int icon);
void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname, struct IDProperty *properties, int context, int flag);
+void uiItemsFullEnumO_array(
+ uiLayout *layout, EnumPropertyItem *item_array, const int totitem,
+ struct wmOperatorType *ot, PointerRNA ptr, PropertyRNA *prop, const char *propname, IDProperty *properties,
+ const int context, const int flag);
void uiItemL(uiLayout *layout, const char *name, int icon); /* label */
void uiItemLDrag(uiLayout *layout, struct PointerRNA *ptr, const char *name, int icon); /* label icon for dragging */
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 06de5f9..4ceb216 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -182,6 +182,9 @@ enum {
#define PIE_CLICK_THRESHOLD_SQ 50.0f
+/* max amount of items a radial menu (pie menu) can contain */
+#define PIE_MAX_ITEMS 8
+
typedef struct uiLinkLine { /* only for draw/edit */
struct uiLinkLine *next, *prev;
struct uiBut *from, *to;
@@ -332,6 +335,7 @@ typedef struct ColorPickerData {
} ColorPickerData;
struct PieMenuData {
+ const char *title;
float pie_dir[2];
float pie_center_init[2];
float pie_center_spawned[2];
@@ -603,6 +607,10 @@ uiPopupBlockHandle *ui_popup_menu_create(
struct bContext *C, struct ARegion *butregion, uiBut *but,
uiMenuCreateFunc create_func, void *arg);
+void ui_pie_menu_level_create(
+ uiBlock *block, struct wmOperatorType *ot, const char *propname, IDProperty *properties,
+ EnumPropertyItem *items, int totitem, int context, int flag);
+
void ui_popup_block_free(struct bContext *C, uiPopupBlockHandle *handle);
int ui_but_menu_step(uiBut *but, int step);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 0b53232..5e83a65 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -883,6 +883,120 @@ void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int ico
}
+static bool ui_layout_is_radial(const uiLayout *layout)
+{
+ return (layout->item.type == ITEM_LAYOUT_RADIAL) ||
+ ((layout->item.type == ITEM_LAYOUT_ROOT) && (layout->root->type == UI_LAYOUT_PIEMENU));
+}
+
+/**
+ * Create ui items for enum items in \a item_array.
+ */
+void uiItemsFullEnumO_array(
+ uiLayout *layout, EnumPropertyItem *item_array, const int totitem,
+ wmOperatorType *ot, PointerRNA ptr, PropertyRNA *prop, const char *propname, IDProperty *properties,
+ const int context, const int flag)
+{
+ /* passing prop and ptr is optional, search for them if needed */
+ if (!ptr.data) {
+ WM_operator_properties_create_ptr(&ptr, ot);
+ /* so the context is passed to itemf functions (some need it) */
+ WM_operator_properties_sanitize(&ptr, false);
+ }
+ if (!prop) {
+ prop = RNA_struct_find_property(&ptr, propname);
+ }
+
+ if (!(prop && RNA_property_type(prop) == PROP_ENUM)) {
+ if (prop) {
+ RNA_warning("%s.%s, not an enum type", RNA_struct_identifier(ptr.type), propname);
+ }
+ else {
+ RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname);
+ }
+ return;
+ }
+
+
+ uiLayout *target, *split;
+ EnumPropertyItem *item;
+ uiBlock *block = layout->root->block;
+ const bool radial = ui_layout_is_radial(layout);
+ int i;
+
+ if (radial) {
+ target = uiLayoutRadial(layout);
+ }
+ else {
+ split = uiLayoutSplit(layout, 0.0f, false);
+ target = uiLayoutColumn(split, layout->align);
+ }
+
+ for (i = 1, item = item_array; item->identifier; i++, item++) {
+ /* handle oversized pies */
+ if (radial && i >= PIE_MAX_ITEMS) {
+ /* only create a new pie level if there's a visible item for it */
+ if (item->name) {
+ ui_pie_menu_level_create(block, ot, propname, properties, item_array, totitem, context, flag);
+ break;
+ }
+ continue;
+ }
+
+ if (item->identifier[0]) {
+ PointerRNA tptr;
+
+ WM_operator_properties_create_ptr(&tptr, ot);
+ if (properties) {
+ if (tptr.data) {
+ IDP_FreeProperty(tptr.data);
+ MEM_freeN(tptr.data);
+ }
+ tptr.data = IDP_CopyProperty(properties);
+ }
+ RNA_property_enum_set(&tptr, prop, item->value);
+
+ uiItemFullO_ptr(target, ot, item->name, item->icon, tptr.data, context, flag);
+
+ ui_but_tip_from_enum_item(block->buttons.last, item);
+ }
+ else {
+ if (item->name) {
+ uiBut *but;
+
+ if (item != item_array && !radial) {
+ target = uiLayoutColumn(split, target->align);
+
+ /* inconsistent, but menus with labels do not look good flipped */
+ block->flag |= UI_BLOCK_NO_FLIP;
+ }
+
+ if (item->icon || radial) {
+ uiItemL(target, item->name, item->icon);
+
+ but = block->buttons.last;
+ }
+ else {
+ /* Do not use uiItemL here, as our root layout is a menu one, it will add a fake blank icon! */
+ but = uiDefBut(block, UI_BTYPE_LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL,
+ 0.0, 0.0, 0, 0, "");
+ }
+ ui_but_tip_from_enum_item(but, item);
+ }
+ else {
+ if (radial) {
+ /* invisible dummy button to ensure all items are always at the same position */
+ uiItemS(target);
+ }
+ else {
+ /* XXX bug here, colums draw bottom item badly */
+ uiItemS(target);
+ }
+ }
+ }
+ }
+}
+
void uiItemsFullEnumO(
uiLayout *layout, const char *opname, const char *propname, IDProperty *properties,
int context, int flag)
@@ -892,8 +1006,6 @@ void uiItemsFullEnumO(
PointerRNA ptr;
PropertyRNA *prop;
uiBlock *block = layout->root->block;
- const bool radial = (layout->item.type == ITEM_LAYOUT_RADIAL) ||
- ((layout->item.type == ITEM_LAYOUT_ROOT) && (layout->root->type == UI_LAYOUT_PIEMENU));
if (!ot || !ot->srna) {
ui_item_disabled(layout, opname);
@@ -910,89 +1022,20 @@ void uiItemsFullEnumO(
BLI_assert((prop == NULL) || (RNA_property_type(prop) == PROP_ENUM));
if (prop && RNA_property_type(prop) == PROP_ENUM) {
- EnumPropertyItem *item, *item_array = NULL;
+ EnumPropertyItem *item_array = NULL;
+ int totitem;
bool free;
- uiLayout *split = NULL;
- uiLayout *target;
- if (radial) {
- target = uiLayoutRadial(layout);
+ if (ui_layout_is_radial(layout)) {
+ RNA_property_enum_items_gettexted_all(block->evil_C, &ptr, prop, &item_array, &totitem, &free);
}
else {
- split = uiLayoutSplit(layout, 0.0f, false);
- target = uiLayoutColumn(split, layout->align);
- }
-
- if (0 && radial) {
- /* XXX Disabled as temporary workaround!
- *
- * Normally, we always draw a button for all items even if they're unavailable (we draw invisible
- * dummy buttons then), so items are always at the same position. This causes issues with current
- * 'Object Mode' pie since more than 8 modes exist now (see T46973).
- * Disabling this until more than 8 items per pie are supported (or a better solution is found).
- * We should work on that ASAP though.
- *
- * - Julian (Dec 2015)
- */
- RNA_property_enum_items_gettexted_all(block->evil_C, &ptr, prop, &item_array, NULL, &free);
- }
- else {
- RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, NULL, &free);
+ RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, &totitem, &free);
}
- for (item = item_array; item->identifier; item++) {
- if (item->identifier[0]) {
- PointerRNA tptr;
-
- WM_operator_properties_create_ptr(&tptr, ot);
- if (properties) {
- if (tptr.data) {
- IDP_FreeProperty(tptr.data);
- MEM_freeN(tptr.data);
- }
- tptr.data = IDP_CopyProperty(properties);
- }
- RNA_property_enum_set(&tptr, prop, item->value);
-
- uiItemFullO_ptr(target, ot, item->name, item->icon, tptr.data, context, flag);
-
- ui_but_tip_from_enum_item(block->buttons.last, item);
- }
- else {
- if (item->name) {
- uiBut *but;
-
- if (item != item_array && !radial) {
- target = uiLayoutColumn(split, layout->align);
-
- /* inconsistent, but menus with labels do not look good flipped */
- block->flag |= UI_BLOCK_NO_FLIP;
- }
-
- if (item->icon || radial) {
- uiItemL(target, item->name, item->icon);
+ /* add items */
+ uiItemsFullEnumO_array(layout, item_array, totitem, ot, ptr, prop, propname, properties, context, flag);
- but = block->buttons.last;
- }
- else {
- /* Do not use uiItemL here, as our root layout is a menu one, it will add a fake blank icon! */
- but = uiDefBut(block, UI_BTYPE_LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL,
- 0.0, 0.0, 0, 0, "");
- }
- ui_but_tip_from_enum_item(but, item);
- }
- else {
- if (radial) {
- /* invisible dummy button to ensure all items are always at the same position */
- uiItemS(target);
- }
- else {
- /* XXX bug here, colums draw bottom item badly */
- uiItemS(target);
- }
- }
- }
- }
if (free) {
MEM_freeN(item_array);
}
@@ -2178,9 +2221,9 @@ static RadialDirection ui_get_radialbut_vec(float vec[2], short itemnum)
{
RadialDirection dir;
- if (itemnum >= 8) {
- itemnum %= 8;
- printf("Warning: Pie menus with more than 8 items are currently unsupported\n");
+ if (itemnum >= PIE_MAX_ITEMS) {
+ itemnum %= PIE_MAX_ITEMS;
+ printf("Warning: Pie menus with more than %i items are currently unsupported\n", PIE_MAX_ITEMS);
}
dir
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list