UI: Consistent Menu/Block/Popup Content Ordering #109798

Merged
Harley Acheson merged 13 commits from Harley/blender:MenuDirection into main 2023-08-31 20:25:02 +02:00
18 changed files with 23 additions and 159 deletions

View File

@ -871,6 +871,9 @@ void blo_do_versions_userdef(UserDef *userdef)
*/
{
/* Keep this block, even when empty. */
/* Clear deprecated USER_MENUFIXEDORDER user flag for reuse. */
userdef->uiflag &= ~USER_UIFLAG_UNUSED_4;
}
LISTBASE_FOREACH (bTheme *, btheme, &userdef->themes) {

View File

@ -145,23 +145,19 @@ enum {
/** #uiBlock.flag (controls) */
enum {
UI_BLOCK_LOOP = 1 << 0,
/** Indicate that items in a popup are drawn with inverted order. Used for arrow key navigation
* so that it knows to invert the navigation direction to match the drawing order. */
UI_BLOCK_IS_FLIP = 1 << 1,
UI_BLOCK_NO_FLIP = 1 << 2,
UI_BLOCK_NUMSELECT = 1 << 3,
UI_BLOCK_NUMSELECT = 1 << 1,
Harley marked this conversation as resolved Outdated

Best update the following flag values, makes it easier to see that there are unused values.

Best update the following flag values, makes it easier to see that there are unused values.

Make sense. I only updated the first section, down to bit 11, because of the 14-17 overlap with uiBut::drawflag

Make sense. I only updated the first section, down to bit 11, because of the 14-17 overlap with uiBut::drawflag
/** Don't apply window clipping. */
UI_BLOCK_NO_WIN_CLIP = 1 << 4,
UI_BLOCK_CLIPBOTTOM = 1 << 5,
UI_BLOCK_CLIPTOP = 1 << 6,
UI_BLOCK_MOVEMOUSE_QUIT = 1 << 7,
UI_BLOCK_KEEP_OPEN = 1 << 8,
UI_BLOCK_POPUP = 1 << 9,
UI_BLOCK_OUT_1 = 1 << 10,
UI_BLOCK_SEARCH_MENU = 1 << 11,
UI_BLOCK_POPUP_MEMORY = 1 << 12,
UI_BLOCK_NO_WIN_CLIP = 1 << 2,
UI_BLOCK_CLIPBOTTOM = 1 << 3,
UI_BLOCK_CLIPTOP = 1 << 4,
UI_BLOCK_MOVEMOUSE_QUIT = 1 << 5,
UI_BLOCK_KEEP_OPEN = 1 << 6,
UI_BLOCK_POPUP = 1 << 7,
UI_BLOCK_OUT_1 = 1 << 8,
UI_BLOCK_SEARCH_MENU = 1 << 9,
UI_BLOCK_POPUP_MEMORY = 1 << 10,
/** Stop handling mouse events. */
UI_BLOCK_CLIP_EVENTS = 1 << 13,
UI_BLOCK_CLIP_EVENTS = 1 << 11,
/* #uiBlock::flags bits 14-17 are identical to #uiBut::drawflag bits. */
@ -874,7 +870,6 @@ void UI_block_direction_set(uiBlock *block, char direction);
/**
* This call escapes if there's alignment flags.
*/
void UI_block_order_flip(uiBlock *block);
void UI_block_flag_enable(uiBlock *block, int flag);
void UI_block_flag_disable(uiBlock *block, int flag);
void UI_block_translate(uiBlock *block, int x, int y);

View File

@ -4315,7 +4315,6 @@ static void ui_def_but_rna__menu(bContext * /*C*/, uiLayout *layout, void *but_p
if (!item->identifier[0]) {
/* inconsistent, but menus with categories do not look good flipped */
if (item->name) {
block->flag |= UI_BLOCK_NO_FLIP;
categories++;
entries_nosepr_count++;
}
@ -4347,8 +4346,8 @@ static void ui_def_but_rna__menu(bContext * /*C*/, uiLayout *layout, void *but_p
const char *title = RNA_property_ui_name(but->rnaprop);
if (title[0] && (categories == 0) && (block->flag & UI_BLOCK_NO_FLIP)) {
/* Title at the top for menus with categories. */
if (title[0] && !but->str[0] && (categories == 0)) {
/* Show title when no categories and calling button has no text. */
uiDefBut(block,
UI_BTYPE_LABEL,
0,
@ -4472,32 +4471,11 @@ static void ui_def_but_rna__menu(bContext * /*C*/, uiLayout *layout, void *but_p
}
}
if (title[0] && (categories == 0) && !(block->flag & UI_BLOCK_NO_FLIP)) {
/* Title at the bottom for menus without categories. */
uiItemS(layout);
uiDefBut(block,
UI_BTYPE_LABEL,
0,
title,
0,
0,
UI_UNIT_X * 5,
UI_UNIT_Y,
nullptr,
0.0,
0.0,
0,
0,
"");
}
UI_block_layout_set_current(block, layout);
if (free) {
MEM_freeN((void *)item_array);
}
BLI_assert((block->flag & UI_BLOCK_IS_FLIP) == 0);
block->flag |= UI_BLOCK_IS_FLIP;
}
static void ui_def_but_rna__panel_type(bContext *C, uiLayout *layout, void *but_p)
@ -5852,39 +5830,6 @@ void UI_block_direction_set(uiBlock *block, char direction)
block->direction = direction;
}
void UI_block_order_flip(uiBlock *block)
{
float centy, miny = 10000, maxy = -10000;
if (U.uiflag & USER_MENUFIXEDORDER) {
return;
}
if (block->flag & UI_BLOCK_NO_FLIP) {
return;
}
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->drawflag & UI_BUT_ALIGN) {
return;
}
if (but->rect.ymin < miny) {
miny = but->rect.ymin;
}
if (but->rect.ymax > maxy) {
maxy = but->rect.ymax;
}
}
/* mirror trick */
centy = (miny + maxy) / 2.0f;
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
but->rect.ymin = centy - (but->rect.ymin - centy);
but->rect.ymax = centy - (but->rect.ymax - centy);
std::swap(but->rect.ymin, but->rect.ymax);
}
block->flag ^= UI_BLOCK_IS_FLIP;
}
void UI_block_flag_enable(uiBlock *block, int flag)
{
block->flag |= flag;

View File

@ -10483,19 +10483,18 @@ static int ui_handle_menu_event(bContext *C,
if (val == KM_PRESS) {
/* Determine scroll operation. */
uiMenuScrollType scrolltype;
const bool ui_block_flipped = (block->flag & UI_BLOCK_IS_FLIP) != 0;
if (ELEM(type, EVT_PAGEUPKEY, EVT_HOMEKEY)) {
scrolltype = ui_block_flipped ? MENU_SCROLL_TOP : MENU_SCROLL_BOTTOM;
scrolltype = MENU_SCROLL_TOP;
}
else if (ELEM(type, EVT_PAGEDOWNKEY, EVT_ENDKEY)) {
scrolltype = ui_block_flipped ? MENU_SCROLL_BOTTOM : MENU_SCROLL_TOP;
scrolltype = MENU_SCROLL_BOTTOM;
}
else if (ELEM(type, EVT_UPARROWKEY, WHEELUPMOUSE)) {
scrolltype = ui_block_flipped ? MENU_SCROLL_UP : MENU_SCROLL_DOWN;
scrolltype = MENU_SCROLL_UP;
}
else {
scrolltype = ui_block_flipped ? MENU_SCROLL_DOWN : MENU_SCROLL_UP;
scrolltype = MENU_SCROLL_DOWN;
}
if (ui_menu_pass_event_to_parent_if_nonactive(

View File

@ -1290,7 +1290,6 @@ static void ui_item_menu_hold(bContext *C, ARegion *butregion, uiBut *but)
UI_popup_menu_but_set(pup, butregion, but);
block->flag |= UI_BLOCK_POPUP_HOLD;
block->flag |= UI_BLOCK_IS_FLIP;
char direction = UI_DIR_DOWN;
if (!but->drawstr[0]) {
@ -1554,9 +1553,6 @@ void uiItemsFullEnumO_items(uiLayout *layout,
if (item->name) {
if (item != item_array && !radial && split != nullptr) {
target = uiLayoutColumn(split, layout->align);
/* inconsistent, but menus with labels do not look good flipped */
block->flag |= UI_BLOCK_NO_FLIP;
}
uiBut *but;
@ -1659,9 +1655,6 @@ void uiItemsFullEnumO(uiLayout *layout,
if (free) {
MEM_freeN((void *)item_array);
}
/* intentionally don't touch UI_BLOCK_IS_FLIP here,
* we don't know the context this is called in */
}
else if (prop && RNA_property_type(prop) != PROP_ENUM) {
RNA_warning("%s.%s, not an enum type", RNA_struct_identifier(ptr.type), propname);
@ -2723,8 +2716,6 @@ void uiItemsEnumR(uiLayout *layout, PointerRNA *ptr, const char *propname)
if (item[i].name) {
if (i != 0) {
column = uiLayoutColumn(split, false);
/* inconsistent, but menus with labels do not look good flipped */
block->flag |= UI_BLOCK_NO_FLIP;
}
uiItemL(column, item[i].name, ICON_NONE);
@ -2742,9 +2733,6 @@ void uiItemsEnumR(uiLayout *layout, PointerRNA *ptr, const char *propname)
if (free) {
MEM_freeN((void *)item);
}
/* intentionally don't touch UI_BLOCK_IS_FLIP here,
* we don't know the context this is called in */
}
/* Pointer RNA button with search */
@ -2955,20 +2943,13 @@ void uiItemPointerR(uiLayout *layout,
void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
{
MenuType *mt = (MenuType *)arg_mt;
UI_menutype_draw(C, mt, layout);
/* Menus are created flipped (from event handling point of view). */
layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
}
void ui_item_paneltype_func(bContext *C, uiLayout *layout, void *arg_pt)
{
PanelType *pt = (PanelType *)arg_pt;
UI_paneltype_draw(C, pt, layout);
/* Panels are created flipped (from event handling POV). */
layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
}
static uiBut *ui_item_menu(uiLayout *layout,
@ -3576,8 +3557,6 @@ static void menu_item_enum_opname_menu(bContext * /*C*/, uiLayout *layout, void
uiLayoutSetOperatorContext(layout, lvl->opcontext);
uiItemsFullEnumO(layout, lvl->opname, lvl->propname, op_props, lvl->opcontext, UI_ITEM_NONE);
layout->root->block->flag |= UI_BLOCK_IS_FLIP;
/* override default, needed since this was assumed pre 2.70 */
UI_block_direction_set(layout->root->block, UI_DIR_DOWN);
}
@ -3668,7 +3647,6 @@ static void menu_item_enum_rna_menu(bContext * /*C*/, uiLayout *layout, void *ar
uiLayoutSetOperatorContext(layout, lvl->opcontext);
uiItemsEnumR(layout, &lvl->rnapoin, lvl->propname);
layout->root->block->flag |= UI_BLOCK_IS_FLIP;
}
void uiItemMenuEnumR_prop(

View File

@ -188,9 +188,7 @@ static void ui_popup_menu_create_block(bContext *C,
const uiStyle *style = UI_style_get_dpi();
pup->block = UI_block_begin(C, nullptr, block_name, UI_EMBOSS_PULLDOWN);
if (!pup->but) {
pup->block->flag |= UI_BLOCK_NO_FLIP;
}
/* A title is only provided when a Menu has a label, this is not always the case, see e.g.
* `VIEW3D_MT_edit_mesh_context_menu` -- this specifies its own label inside the draw function
* depending on vertex/edge/face mode. We still want to flag the uiBlock (but only insert into
@ -360,7 +358,6 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
if (RGN_TYPE_IS_HEADER_ANY(region->regiontype)) {
if (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_BOTTOM) {
UI_block_direction_set(block, UI_DIR_UP);
UI_block_order_flip(block);
}
}
}
@ -408,20 +405,6 @@ static uiPopupBlockHandle *ui_popup_menu_create(
pup->my = window->eventstate->xy[1];
pup->popup = true;
}
/* some enums reversing is strange, currently we have no good way to
* reverse some enum's but not others, so reverse all so the first menu
* items are always close to the mouse cursor */
else {
#if 0
/* if this is an rna button then we can assume its an enum
* flipping enums is generally not good since the order can be
* important #28786. */
if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) {
pup->block->flag |= UI_BLOCK_NO_FLIP;
}
#endif
}
uiPopupBlockHandle *handle = ui_popup_block_create(
C, butregion, but, nullptr, ui_block_func_POPUP, pup, ui_block_free_func_POPUP);
@ -492,8 +475,6 @@ uiPopupMenu *UI_popup_menu_begin_ex(bContext *C,
pup->title = title;
ui_popup_menu_create_block(C, pup, title, block_name);
/* Further buttons will be laid out top to bottom by default. */
pup->block->flag |= UI_BLOCK_IS_FLIP;
/* create in advance so we can let buttons point to retval already */
pup->block->handle = MEM_cnew<uiPopupBlockHandle>(__func__);

View File

@ -107,8 +107,6 @@ static void ui_popover_create_block(bContext *C,
uiLayoutContextCopy(pup->layout, pup->but->context);
}
}
pup->block->flag |= UI_BLOCK_NO_FLIP;
}
static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, void *arg_pup)
@ -415,9 +413,6 @@ void UI_popover_end(bContext *C, uiPopover *pup, wmKeyMap *keymap)
* The begin/end stype of calling popups doesn't allow 'can_refresh' to be set.
* For now close this style of popovers when accessed. */
UI_block_flag_disable(pup->block, UI_BLOCK_KEEP_OPEN);
/* Panels are created flipped (from event handling POV). */
pup->block->flag ^= UI_BLOCK_IS_FLIP;
}
uiLayout *UI_popover_layout(uiPopover *pup)

View File

@ -253,11 +253,6 @@ static void ui_popup_block_position(wmWindow *window,
else {
offset_x = butrct.xmin - block->rect.xmin - center_x;
}
/* changed direction? */
if ((dir1 & block->direction) == 0) {
/* TODO: still do */
UI_block_order_flip(block);
}
}
else if (dir1 == UI_DIR_DOWN) {
offset_y = (butrct.ymin - block->rect.ymax) + offset_overlap;
@ -276,11 +271,6 @@ static void ui_popup_block_position(wmWindow *window,
else {
offset_x = butrct.xmin - block->rect.xmin - center_x;
}
/* changed direction? */
if ((dir1 & block->direction) == 0) {
/* TODO: still do */
UI_block_order_flip(block);
}
}
/* Center over popovers for eg. */

View File

@ -2986,8 +2986,6 @@ static void constraint_ops_extra_draw(bContext *C, uiLayout *layout, void *con_v
uiLayoutSetUnitsX(layout, 4.0f);
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
/* Apply. */
uiItemO(layout,
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"),
@ -3863,7 +3861,7 @@ static uiBlock *ui_icon_view_menu_cb(bContext *C, ARegion *region, void *arg_lit
const int h = UI_UNIT_X * (args.icon_scale + args.show_labels);
uiBlock *block = UI_block_begin(C, region, "_popup", UI_EMBOSS_PULLDOWN);
UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NO_FLIP);
UI_block_flag_enable(block, UI_BLOCK_LOOP);
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
bool free;

View File

@ -2062,8 +2062,6 @@ static void move_to_collection_menu_create(bContext *C, uiLayout *layout, void *
MoveToCollectionData *menu = static_cast<MoveToCollectionData *>(menu_v);
const char *name = BKE_collection_ui_name_get(menu->collection);
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
WM_operator_properties_create_ptr(&menu->ptr, menu->ot);
RNA_int_set(&menu->ptr, "collection_index", menu->index);
RNA_boolean_set(&menu->ptr, "is_new", true);

View File

@ -473,8 +473,6 @@ static void workspace_add_menu(bContext * /*C*/, uiLayout *layout, void *templat
WorkspaceConfigFileData *startup_config = workspace_config_file_read(app_template);
WorkspaceConfigFileData *builtin_config = workspace_system_file_read(app_template);
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
if (startup_config) {
LISTBASE_FOREACH (WorkSpace *, workspace, &startup_config->workspaces) {
uiLayout *row = uiLayoutRow(layout, false);

View File

@ -533,8 +533,6 @@ static void template_texture_user_menu(bContext *C, uiLayout *layout, void * /*a
last_category = user->category;
}
UI_block_flag_enable(block, UI_BLOCK_NO_FLIP);
}
void uiTemplateTextureUser(uiLayout *layout, bContext *C)

View File

@ -651,7 +651,6 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_
bNodeSocket *sock = arg->sock;
bNodeTreeType *ntreetype = arg->ntree->typeinfo;
UI_block_flag_enable(block, UI_BLOCK_NO_FLIP | UI_BLOCK_IS_FLIP);
UI_block_layout_set_current(block, layout);
split = uiLayoutSplit(layout, 0.0f, false);

View File

@ -240,8 +240,6 @@ static void gpencil_modifier_ops_extra_draw(bContext *C, uiLayout *layout, void
uiLayoutSetUnitsX(layout, 4.0f);
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
/* Apply. */
if (!(mti->flags & eGpencilModifierTypeFlag_NoApply)) {
uiItemO(layout,

View File

@ -1197,7 +1197,7 @@ typedef enum eUserpref_UI_Flag {
USER_ZOOM_TO_MOUSEPOS = (1 << 20),
USER_SHOW_FPS = (1 << 21),
USER_REGISTER_ALL_USERS = (1 << 22),
USER_MENUFIXEDORDER = (1 << 23),
USER_UIFLAG_UNUSED_4 = (1 << 23), /* Cleared. */
Harley marked this conversation as resolved Outdated

This needs versioning in blo_do_versions_userdef() to unset the flag for old files. No version bump needed until the flag will be reused.

This needs versioning in `blo_do_versions_userdef()` to unset the flag for old files. No version bump needed until the flag will be reused.

Thanks! Although I did also renamed this to USER_MENUFIXEDORDER_DEPRECATED and marked with comments as such. Let me know if that isn't good.

Thanks! Although I did also renamed this to USER_MENUFIXEDORDER_DEPRECATED and marked with comments as such. Let me know if that isn't good.

Should be named USER_UIFLAG_UNUSED_4, consistent with other deprecated flags (also add the `/* Cleared. */ comment).

Should be named `USER_UIFLAG_UNUSED_4`, consistent with other deprecated flags (also add the `/* Cleared. */ comment).
USER_CONTINUOUS_MOUSE = (1 << 24),
USER_ZOOM_INVERT = (1 << 25),
USER_ZOOM_HORIZ = (1 << 26), /* for CONTINUE and DOLLY zoom */

View File

@ -4980,13 +4980,6 @@ static void rna_def_userdef_view(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, nullptr, "uiflag", USER_PLAINMENUS);
RNA_def_property_ui_text(prop, "Toolbox Column Layout", "Use a column layout for toolbox");
prop = RNA_def_property(srna, "use_directional_menus", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, nullptr, "uiflag", USER_MENUFIXEDORDER);
RNA_def_property_ui_text(prop,
"Contents Follow Opening Direction",
"Otherwise menus, etc will always be top to bottom, left to right, "
"no matter opening direction");
static const EnumPropertyItem header_align_items[] = {
{0, "NONE", 0, "Keep Existing", "Keep existing header alignment"},
{USER_HEADER_FROM_PREF, "TOP", 0, "Top", "Top aligned on load"},

View File

@ -206,8 +206,6 @@ static void modifier_ops_extra_draw(bContext *C, uiLayout *layout, void *md_v)
uiLayoutSetUnitsX(layout, 4.0f);
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
/* Apply. */
uiItemO(layout,
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"),

View File

@ -122,8 +122,6 @@ static void gpencil_shaderfx_ops_extra_draw(bContext *C, uiLayout *layout, void
uiLayoutSetUnitsX(layout, 4.0f);
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
/* Duplicate. */
uiItemO(layout,
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Duplicate"),