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, | ||||
| bool split_row) | |||||
| { | { | ||||
| /* 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); | ||||
| if (split_row) { | |||||
| uiLayout *column_layout = uiLayoutColumn(layout, true); | |||||
| uiLayout *local_layout = uiLayoutRow(column_layout, true); | |||||
| RNA_property_enum_items_gettexted(block->evil_C, ptr, prop, &item_array, NULL, &free); | |||||
| /* we dont want nested rows, cols in menus */ | |||||
| UI_block_layout_set_current(block, local_layout); | |||||
| for (item = item_array; item->identifier; item++) { | |||||
| const bool is_first = item == item_array; | |||||
| if (!item->identifier[0]) { | |||||
| const EnumPropertyItem *next_item = item + 1; | |||||
| /* Separate items, potentially with a label. */ | |||||
| if (next_item->identifier) { | |||||
| /* Item without identifier but with name: | |||||
| * Add group label for the following items. */ | |||||
| if (item->name) { | |||||
| if (!is_first) { | |||||
| uiItemS(block->curlayout); | |||||
| } | |||||
| uiItemL(block->curlayout, item->name, item->icon); | |||||
| } | |||||
| else { | |||||
| local_layout = uiLayoutRow(column_layout, true); | |||||
| UI_block_layout_set_current(block, local_layout); | |||||
| } | |||||
| } | |||||
| continue; | |||||
| } | |||||
| ui_item_enum_expand_elem_exec( | |||||
| local_layout, block, ptr, prop, uiname, h, but_type, icon_only, item, is_first); | |||||
| } | |||||
| } | |||||
| else { | |||||
| 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 (layout->root->type != UI_LAYOUT_MENU) { | ||||
| UI_block_layout_set_current(block, ui_item_local_sublayout(layout, layout, 1)); | UI_block_layout_set_current(block, ui_item_local_sublayout(layout, layout, 1)); | ||||
| } | } | ||||
| else { | else { | ||||
| UI_block_layout_set_current(block, layout); | UI_block_layout_set_current(block, layout); | ||||
| } | } | ||||
| 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, | ||||
| PointerRNA *ptr, | PointerRNA *ptr, | ||||
| PropertyRNA *prop, | PropertyRNA *prop, | ||||
| const char *uiname, | const char *uiname, | ||||
| int h, | int h, | ||||
| bool icon_only) | bool icon_only) | ||||
| { | { | ||||
| ui_item_enum_expand_exec(layout, block, ptr, prop, uiname, h, UI_BTYPE_ROW, icon_only); | ui_item_enum_expand_exec(layout, block, ptr, prop, uiname, h, UI_BTYPE_ROW, icon_only, false); | ||||
| } | |||||
| static void ui_item_enum_expand_split_row(uiLayout *layout, | |||||
| uiBlock *block, | |||||
| PointerRNA *ptr, | |||||
| PropertyRNA *prop, | |||||
| const char *uiname, | |||||
| int h, | |||||
| bool icon_only) | |||||
| { | |||||
| ui_item_enum_expand_exec(layout, block, ptr, prop, uiname, h, UI_BTYPE_ROW, icon_only, true); | |||||
| } | } | ||||
| static void ui_item_enum_expand_tabs(uiLayout *layout, | static void ui_item_enum_expand_tabs(uiLayout *layout, | ||||
| bContext *C, | bContext *C, | ||||
| uiBlock *block, | uiBlock *block, | ||||
| PointerRNA *ptr, | PointerRNA *ptr, | ||||
| PropertyRNA *prop, | PropertyRNA *prop, | ||||
| const char *uiname, | const char *uiname, | ||||
| int h, | int h, | ||||
| bool icon_only) | bool icon_only) | ||||
| { | { | ||||
| uiBut *last = block->buttons.last; | uiBut *last = block->buttons.last; | ||||
| ui_item_enum_expand_exec(layout, block, ptr, prop, uiname, h, UI_BTYPE_TAB, icon_only); | ui_item_enum_expand_exec(layout, block, ptr, prop, uiname, h, UI_BTYPE_TAB, icon_only, false); | ||||
| BLI_assert(last != block->buttons.last); | BLI_assert(last != block->buttons.last); | ||||
| for (uiBut *tab = last ? last->next : block->buttons.first; tab; tab = tab->next) { | for (uiBut *tab = last ? last->next : block->buttons.first; tab; tab = tab->next) { | ||||
| UI_but_drawflag_enable(tab, ui_but_align_opposite_to_area_align_get(CTX_wm_region(C))); | UI_but_drawflag_enable(tab, ui_but_align_opposite_to_area_align_get(CTX_wm_region(C))); | ||||
| } | } | ||||
| } | } | ||||
| /* callback for keymap item change button */ | /* callback for keymap item change button */ | ||||
| static void ui_keymap_but_cb(bContext *UNUSED(C), void *but_v, void *UNUSED(key_v)) | static void ui_keymap_but_cb(bContext *UNUSED(C), void *but_v, void *UNUSED(key_v)) | ||||
| ▲ Show 20 Lines • Show All 953 Lines • ▼ Show 20 Lines | void uiItemFullR(uiLayout *layout, | ||||
| const char *name, | const char *name, | ||||
| int icon) | int icon) | ||||
| { | { | ||||
| uiBlock *block = layout->root->block; | uiBlock *block = layout->root->block; | ||||
| uiBut *but = NULL; | uiBut *but = NULL; | ||||
| PropertyType type; | PropertyType type; | ||||
| char namestr[UI_MAX_NAME_STR]; | char namestr[UI_MAX_NAME_STR]; | ||||
| int len, w, h; | int len, w, h; | ||||
| bool slider, toggle, expand, icon_only, no_bg, compact; | bool slider, toggle, expand, icon_only, no_bg, compact, split_row; | ||||
| bool is_array; | bool is_array; | ||||
| const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0); | const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0); | ||||
| /* By default 'use_prop_sep' uses a separate column for labels. | /* By default 'use_prop_sep' uses a separate column for labels. | ||||
| * This is an exception for check-boxes otherwise only the small checkbox region is clickable. | * This is an exception for check-boxes otherwise only the small checkbox region is clickable. | ||||
| * | * | ||||
| * Keep using 'use_prop_sep' instead of disabling it entirely because | * Keep using 'use_prop_sep' instead of disabling it entirely because | ||||
| * we need the ability to have decorators still. */ | * we need the ability to have decorators still. */ | ||||
| ▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | #endif | ||||
| if ((type == PROP_ENUM) && (RNA_property_flag(prop) & PROP_ENUM_FLAG)) { | if ((type == PROP_ENUM) && (RNA_property_flag(prop) & PROP_ENUM_FLAG)) { | ||||
| flag |= UI_ITEM_R_EXPAND; | flag |= UI_ITEM_R_EXPAND; | ||||
| } | } | ||||
| slider = (flag & UI_ITEM_R_SLIDER) != 0; | slider = (flag & UI_ITEM_R_SLIDER) != 0; | ||||
| toggle = (flag & UI_ITEM_R_TOGGLE) != 0; | toggle = (flag & UI_ITEM_R_TOGGLE) != 0; | ||||
| expand = (flag & UI_ITEM_R_EXPAND) != 0; | expand = (flag & UI_ITEM_R_EXPAND) != 0; | ||||
| split_row = (flag & UI_ITEM_R_SPLIT_ROW) != 0; | |||||
| no_bg = (flag & UI_ITEM_R_NO_BG) != 0; | no_bg = (flag & UI_ITEM_R_NO_BG) != 0; | ||||
| compact = (flag & UI_ITEM_R_COMPACT) != 0; | compact = (flag & UI_ITEM_R_COMPACT) != 0; | ||||
| /* get size */ | /* get size */ | ||||
| ui_item_rna_size(layout, name, icon, ptr, prop, index, icon_only, compact, &w, &h); | ui_item_rna_size(layout, name, icon, ptr, prop, index, icon_only, compact, &w, &h); | ||||
| int prev_emboss = layout->emboss; | int prev_emboss = layout->emboss; | ||||
| if (no_bg) { | if (no_bg) { | ||||
| ▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | else if (type == PROP_ENUM && index == RNA_ENUM_VALUE) { | ||||
| } | } | ||||
| else { | else { | ||||
| uiDefButR_prop( | uiDefButR_prop( | ||||
| block, UI_BTYPE_ROW, 0, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL); | block, UI_BTYPE_ROW, 0, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL); | ||||
| } | } | ||||
| } | } | ||||
| /* expanded enum */ | /* expanded enum */ | ||||
| else if (type == PROP_ENUM && expand) { | else if (type == PROP_ENUM && expand) { | ||||
| if (split_row) { | |||||
| ui_item_enum_expand_split_row(layout, block, ptr, prop, name, h, icon_only); | |||||
| } | |||||
| else { | |||||
| ui_item_enum_expand(layout, block, ptr, prop, name, h, icon_only); | ui_item_enum_expand(layout, block, ptr, prop, name, h, icon_only); | ||||
| } | } | ||||
| } | |||||
| /* property with separate label */ | /* property with separate label */ | ||||
| else if (type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) { | else if (type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) { | ||||
| but = ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h, flag); | but = ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h, flag); | ||||
| ui_but_add_search(but, ptr, prop, NULL, NULL); | ui_but_add_search(but, ptr, prop, NULL, NULL); | ||||
| if (layout->redalert) { | if (layout->redalert) { | ||||
| UI_but_flag_enable(but, UI_BUT_REDALERT); | UI_but_flag_enable(but, UI_BUT_REDALERT); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 3,090 Lines • Show Last 20 Lines | |||||