Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/interface/interface_layout.c
| Show First 20 Lines • Show All 716 Lines • ▼ Show 20 Lines | if (!(current_value & enum_value)) { | ||||
| current_value = enum_value; | current_value = enum_value; | ||||
| } | } | ||||
| else { | else { | ||||
| current_value &= enum_value; | current_value &= enum_value; | ||||
| } | } | ||||
| RNA_property_enum_set(&but->rnapoin, but->rnaprop, current_value); | RNA_property_enum_set(&but->rnapoin, but->rnaprop, current_value); | ||||
| } | } | ||||
| } | } | ||||
| static void ui_item_enum_expand_elem_exec(uiLayout *layout, | |||||
| uiBlock *block, | |||||
| PointerRNA *ptr, | |||||
| PropertyRNA *prop, | |||||
| const char *uiname, | |||||
| int h, | |||||
| int but_type, | |||||
| bool icon_only, | |||||
| const EnumPropertyItem *item, | |||||
| bool is_first) | |||||
| { | |||||
| uiBut *but; | |||||
| const char *name; | |||||
| int itemw, icon, value; | |||||
| name = (!uiname || uiname[0]) ? item->name : ""; | |||||
| icon = item->icon; | |||||
| value = item->value; | |||||
| itemw = ui_text_icon_width(block->curlayout, icon_only ? "" : name, icon, 0); | |||||
| if (icon && name[0] && !icon_only) { | |||||
| but = uiDefIconTextButR_prop( | |||||
| block, but_type, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); | |||||
| } | |||||
| else if (icon) { | |||||
| but = uiDefIconButR_prop(block, | |||||
| but_type, | |||||
| 0, | |||||
| icon, | |||||
| 0, | |||||
| 0, | |||||
| (is_first) ? itemw : ceilf(itemw - U.pixelsize), | |||||
| h, | |||||
| ptr, | |||||
| prop, | |||||
| -1, | |||||
| 0, | |||||
| value, | |||||
| -1, | |||||
| -1, | |||||
| NULL); | |||||
| } | |||||
| else { | |||||
| but = uiDefButR_prop( | |||||
| block, but_type, 0, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); | |||||
| } | |||||
| if (RNA_property_flag(prop) & PROP_ENUM_FLAG) { | |||||
| /* If this is set, assert since we're clobbering someone elses callback. */ | |||||
| BLI_assert(but->func == NULL); | |||||
| UI_but_func_set(but, ui_item_enum_expand_handle, but, POINTER_FROM_INT(value)); | |||||
| } | |||||
| if (uiLayoutGetLocalDir(layout) != UI_LAYOUT_HORIZONTAL) { | |||||
| but->drawflag |= UI_BUT_TEXT_LEFT; | |||||
| } | |||||
| /* Allow quick, inaccurate swipe motions to switch tabs | |||||
| * (no need to keep cursor over them). */ | |||||
| if (but_type == UI_BTYPE_TAB) { | |||||
| but->flag |= UI_BUT_DRAG_LOCK; | |||||
| } | |||||
| } | |||||
| static void ui_item_enum_expand_exec(uiLayout *layout, | static void ui_item_enum_expand_exec(uiLayout *layout, | ||||
| uiBlock *block, | uiBlock *block, | ||||
| PointerRNA *ptr, | PointerRNA *ptr, | ||||
| PropertyRNA *prop, | PropertyRNA *prop, | ||||
| const char *uiname, | const char *uiname, | ||||
| int h, | int h, | ||||
| int but_type, | int but_type, | ||||
| bool icon_only) | bool icon_only) | ||||
| { | { | ||||
| /* XXX: The way this function currently handles uiname parameter | /* XXX: The way this function currently handles uiname parameter | ||||
| * is insane and inconsistent with general UI API: | * is insane and inconsistent with general UI API: | ||||
| * | * | ||||
| * - uiname is the *enum property* label. | * - uiname is the *enum property* label. | ||||
| * - when it is NULL or empty, we do not draw *enum items* labels, | * - when it is NULL or empty, we do not draw *enum items* labels, | ||||
| * this doubles the icon_only parameter. | * this doubles the icon_only parameter. | ||||
| * - we *never* draw (i.e. really use) the enum label uiname, it is just used as a mere flag! | * - we *never* draw (i.e. really use) the enum label uiname, it is just used as a mere flag! | ||||
| * | * | ||||
| * Unfortunately, fixing this implies an API "soft break", so better to defer it for later... :/ | * Unfortunately, fixing this implies an API "soft break", so better to defer it for later... :/ | ||||
| * - mont29 | * - mont29 | ||||
| */ | */ | ||||
| uiBut *but; | |||||
| uiLayout *layout_radial = NULL; | |||||
| const EnumPropertyItem *item, *item_array; | const EnumPropertyItem *item, *item_array; | ||||
| const char *name; | |||||
| int itemw, icon, value; | |||||
| bool free; | bool free; | ||||
| bool radial = (layout->root->type == UI_LAYOUT_PIEMENU); | |||||
| BLI_assert(RNA_property_type(prop) == PROP_ENUM); | BLI_assert(RNA_property_type(prop) == PROP_ENUM); | ||||
| uiLayout *layout_radial = NULL; | |||||
| bool radial = (layout->root->type == UI_LAYOUT_PIEMENU); | |||||
| if (radial) { | if (radial) { | ||||
| RNA_property_enum_items_gettexted_all(block->evil_C, ptr, prop, &item_array, NULL, &free); | RNA_property_enum_items_gettexted_all(block->evil_C, ptr, prop, &item_array, NULL, &free); | ||||
| } | } | ||||
| else { | 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, NULL, &free); | ||||
| } | } | ||||
| /* we dont want nested rows, cols in menus */ | /* we dont want nested rows, cols in menus */ | ||||
| if (radial) { | if (radial) { | ||||
| if (layout->root->layout == layout) { | if (layout->root->layout == layout) { | ||||
| layout_radial = uiLayoutRadial(layout); | layout_radial = uiLayoutRadial(layout); | ||||
| UI_block_layout_set_current(block, layout_radial); | UI_block_layout_set_current(block, layout_radial); | ||||
| } | } | ||||
| else { | else { | ||||
| if (layout->item.type == ITEM_LAYOUT_RADIAL) { | if (layout->item.type == ITEM_LAYOUT_RADIAL) { | ||||
| layout_radial = layout; | layout_radial = layout; | ||||
| } | } | ||||
| UI_block_layout_set_current(block, layout); | UI_block_layout_set_current(block, layout); | ||||
| } | } | ||||
| } | } | ||||
| else if (layout->root->type != UI_LAYOUT_MENU) { | else if (ELEM(layout->item.type, ITEM_LAYOUT_GRID_FLOW, ITEM_LAYOUT_COLUMN_FLOW) || | ||||
| UI_block_layout_set_current(block, ui_item_local_sublayout(layout, layout, 1)); | layout->root->type == UI_LAYOUT_MENU) { | ||||
| UI_block_layout_set_current(block, layout); | |||||
jbakker: TODO: clang-format | |||||
| } | } | ||||
| else { | else { | ||||
| UI_block_layout_set_current(block, layout); | UI_block_layout_set_current(block, ui_item_local_sublayout(layout, layout, 1)); | ||||
| } | } | ||||
| for (item = item_array; item->identifier; item++) { | for (item = item_array; item->identifier; item++) { | ||||
| const bool is_first = item == item_array; | const bool is_first = item == item_array; | ||||
| if (!item->identifier[0]) { | if (!item->identifier[0]) { | ||||
| const EnumPropertyItem *next_item = item + 1; | const EnumPropertyItem *next_item = item + 1; | ||||
| /* Separate items, potentially with a label. */ | /* Separate items, potentially with a label. */ | ||||
| if (next_item->identifier) { | if (next_item->identifier) { | ||||
| /* Item without identifier but with name: | /* Item without identifier but with name: | ||||
| * Add group label for the following items. */ | * Add group label for the following items. */ | ||||
| if (item->name) { | if (item->name) { | ||||
| if (!is_first) { | if (!is_first) { | ||||
| uiItemS(block->curlayout); | uiItemS(block->curlayout); | ||||
| } | } | ||||
| uiItemL(block->curlayout, item->name, item->icon); | uiItemL(block->curlayout, item->name, item->icon); | ||||
| } | } | ||||
| else if (radial && layout_radial) { | else if (radial && layout_radial) { | ||||
| uiItemS(layout_radial); | uiItemS(layout_radial); | ||||
| } | } | ||||
| else { | else { | ||||
| uiItemS(block->curlayout); | uiItemS(block->curlayout); | ||||
| } | } | ||||
| } | } | ||||
| continue; | continue; | ||||
| } | } | ||||
| name = (!uiname || uiname[0]) ? item->name : ""; | ui_item_enum_expand_elem_exec( | ||||
| icon = item->icon; | layout, block, ptr, prop, uiname, h, but_type, icon_only, item, is_first); | ||||
| value = item->value; | |||||
| itemw = ui_text_icon_width(block->curlayout, icon_only ? "" : name, icon, 0); | |||||
| if (icon && name[0] && !icon_only) { | |||||
| but = uiDefIconTextButR_prop( | |||||
| block, but_type, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); | |||||
| } | |||||
| else if (icon) { | |||||
| but = uiDefIconButR_prop(block, | |||||
| but_type, | |||||
| 0, | |||||
| icon, | |||||
| 0, | |||||
| 0, | |||||
| (is_first) ? itemw : ceilf(itemw - U.pixelsize), | |||||
| h, | |||||
| ptr, | |||||
| prop, | |||||
| -1, | |||||
| 0, | |||||
| value, | |||||
| -1, | |||||
| -1, | |||||
| NULL); | |||||
| } | |||||
| else { | |||||
| but = uiDefButR_prop( | |||||
| block, but_type, 0, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); | |||||
| } | } | ||||
| if (RNA_property_flag(prop) & PROP_ENUM_FLAG) { | |||||
| /* If this is set, assert since we're clobbering someone elses callback. */ | |||||
| BLI_assert(but->func == NULL); | |||||
| UI_but_func_set(but, ui_item_enum_expand_handle, but, POINTER_FROM_INT(value)); | |||||
| } | |||||
| if (uiLayoutGetLocalDir(layout) != UI_LAYOUT_HORIZONTAL) { | |||||
| but->drawflag |= UI_BUT_TEXT_LEFT; | |||||
| } | |||||
| /* Allow quick, inaccurate swipe motions to switch tabs | |||||
| * (no need to keep cursor over them). */ | |||||
| if (but_type == UI_BTYPE_TAB) { | |||||
| but->flag |= UI_BUT_DRAG_LOCK; | |||||
| } | |||||
| } | |||||
| UI_block_layout_set_current(block, layout); | UI_block_layout_set_current(block, layout); | ||||
| if (free) { | if (free) { | ||||
| MEM_freeN((void *)item_array); | MEM_freeN((void *)item_array); | ||||
| } | } | ||||
| } | } | ||||
| static void ui_item_enum_expand(uiLayout *layout, | static void ui_item_enum_expand(uiLayout *layout, | ||||
| uiBlock *block, | uiBlock *block, | ||||
| ▲ Show 20 Lines • Show All 4,360 Lines • Show Last 20 Lines | |||||
TODO: clang-format