[Bf-blender-cvs] [3a7a7ed03b7] blender2.8: Merge branch 'master' into blender2.8

Campbell Barton noreply at git.blender.org
Fri Nov 3 11:15:52 CET 2017


Commit: 3a7a7ed03b7611a29de0e2a27e358035aee83dce
Author: Campbell Barton
Date:   Fri Nov 3 21:22:27 2017 +1100
Branches: blender2.8
https://developer.blender.org/rB3a7a7ed03b7611a29de0e2a27e358035aee83dce

Merge branch 'master' into blender2.8

===================================================================



===================================================================

diff --cc source/blender/editors/interface/interface_region_menu_popup.c
index 00000000000,aa3e2464237..a0aecb12b84
mode 000000,100644..100644
--- a/source/blender/editors/interface/interface_region_menu_popup.c
+++ b/source/blender/editors/interface/interface_region_menu_popup.c
@@@ -1,0 -1,617 +1,619 @@@
+ /*
+  * ***** BEGIN GPL LICENSE BLOCK *****
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+  * as published by the Free Software Foundation; either version 2
+  * of the License, or (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software Foundation,
+  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+  *
+  * The Original Code is Copyright (C) 2008 Blender Foundation.
+  * All rights reserved.
+  *
+  * Contributor(s): Blender Foundation
+  *
+  * ***** END GPL LICENSE BLOCK *****
+  */
+ 
+ /** \file blender/editors/interface/interface_region_menu_popup.c
+  *  \ingroup edinterface
+  *
+  * PopUp Menu Region
+  */
+ 
+ #include <stdarg.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <assert.h>
+ 
+ #include "MEM_guardedalloc.h"
+ 
+ #include "DNA_userdef_types.h"
+ 
+ #include "BLI_math.h"
+ #include "BLI_listbase.h"
+ 
+ #include "BLI_string.h"
+ #include "BLI_rect.h"
+ #include "BLI_utildefines.h"
+ #include "BLI_ghash.h"
+ 
+ #include "BKE_context.h"
+ #include "BKE_screen.h"
+ #include "BKE_report.h"
+ 
+ #include "WM_api.h"
+ #include "WM_types.h"
+ 
+ #include "RNA_access.h"
+ 
+ #include "UI_interface.h"
+ 
+ #include "BLT_translation.h"
+ 
+ #include "ED_screen.h"
+ 
+ #include "interface_intern.h"
+ #include "interface_regions_intern.h"
+ 
+ /* -------------------------------------------------------------------- */
+ /** \name Utility Functions
+  * \{ */
+ 
+ bool ui_but_menu_step_poll(const uiBut *but)
+ {
+ 	BLI_assert(but->type == UI_BTYPE_MENU);
+ 
+ 	/* currently only RNA buttons */
+ 	return ((but->menu_step_func != NULL) ||
+ 	        (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM));
+ }
+ 
+ int ui_but_menu_step(uiBut *but, int direction)
+ {
+ 	if (ui_but_menu_step_poll(but)) {
+ 		if (but->menu_step_func) {
+ 			return but->menu_step_func(but->block->evil_C, direction, but->poin);
+ 		}
+ 		else {
+ 			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);
+ 		}
+ 	}
+ 
+ 	printf("%s: cannot cycle button '%s'\n", __func__, but->str);
+ 	return 0;
+ }
+ 
+ static uint ui_popup_string_hash(const char *str)
+ {
+ 	/* sometimes button contains hotkey, sometimes not, strip for proper compare */
+ 	int hash;
+ 	const char *delimit = strrchr(str, UI_SEP_CHAR);
+ 
+ 	if (delimit) {
+ 		hash = BLI_ghashutil_strhash_n(str, delimit - str);
+ 	}
+ 	else {
+ 		hash = BLI_ghashutil_strhash(str);
+ 	}
+ 
+ 	return hash;
+ }
+ 
+ uint ui_popup_menu_hash(const char *str)
+ {
+ 	return BLI_ghashutil_strhash(str);
+ }
+ 
+ /* but == NULL read, otherwise set */
+ static uiBut *ui_popup_menu_memory__internal(uiBlock *block, uiBut *but)
+ {
+ 	static uint mem[256];
+ 	static bool first = true;
+ 
+ 	const uint hash = block->puphash;
+ 	const uint hash_mod = hash & 255;
+ 
+ 	if (first) {
+ 		/* init */
+ 		memset(mem, -1, sizeof(mem));
+ 		first = 0;
+ 	}
+ 
+ 	if (but) {
+ 		/* set */
+ 		mem[hash_mod] = ui_popup_string_hash(but->str);
+ 		return NULL;
+ 	}
+ 	else {
+ 		/* get */
+ 		for (but = block->buttons.first; but; but = but->next)
+ 			if (ui_popup_string_hash(but->str) == mem[hash_mod])
+ 				return but;
+ 
+ 		return NULL;
+ 	}
+ }
+ 
+ uiBut *ui_popup_menu_memory_get(uiBlock *block)
+ {
+ 	return ui_popup_menu_memory__internal(block, NULL);
+ }
+ 
+ void ui_popup_menu_memory_set(uiBlock *block, uiBut *but)
+ {
+ 	ui_popup_menu_memory__internal(block, but);
+ }
+ 
+ /** \} */
+ 
+ /* -------------------------------------------------------------------- */
+ /** \name Popup Menu with Callback or String
+  * \{ */
+ 
+ struct uiPopupMenu {
+ 	uiBlock *block;
+ 	uiLayout *layout;
+ 	uiBut *but;
+ 	ARegion *butregion;
+ 
+ 	int mx, my;
+ 	bool popup, slideout;
+ 
+ 	uiMenuCreateFunc menu_func;
+ 	void *menu_arg;
+ };
+ 
+ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, void *arg_pup)
+ {
+ 	uiBlock *block;
+ 	uiBut *bt;
+ 	uiPopupMenu *pup = arg_pup;
+ 	int offset[2], minwidth, width, height;
+ 	char direction;
+ 	bool flip;
+ 
+ 	if (pup->menu_func) {
+ 		pup->block->handle = handle;
+ 		pup->menu_func(C, pup->layout, pup->menu_arg);
+ 		pup->block->handle = NULL;
+ 	}
+ 
+ 	if (pup->but) {
+ 		/* minimum width to enforece */
+ 		minwidth = BLI_rctf_size_x(&pup->but->rect);
+ 
+ 		/* settings (typically rna-enum-popups) show above the button,
+ 		 * menu's like file-menu, show below */
+ 		if (pup->block->direction != 0) {
+ 			/* allow overriding the direction from menu_func */
+ 			direction = pup->block->direction;
+ 		}
+ 		else if ((pup->but->type == UI_BTYPE_PULLDOWN) ||
+ 		         (UI_but_menutype_get(pup->but) != NULL))
+ 		{
+ 			direction = UI_DIR_DOWN;
+ 		}
+ 		else {
+ 			direction = UI_DIR_UP;
+ 		}
+ 	}
+ 	else {
+ 		minwidth = 50;
+ 		direction = UI_DIR_DOWN;
+ 	}
+ 
+ 	flip = (direction == UI_DIR_DOWN);
+ 
+ 	block = pup->block;
+ 
+ 	/* in some cases we create the block before the region,
+ 	 * so we set it delayed here if necessary */
+ 	if (BLI_findindex(&handle->region->uiblocks, block) == -1)
+ 		UI_block_region_set(block, handle->region);
+ 
+ 	block->direction = direction;
+ 
+ 	UI_block_layout_resolve(block, &width, &height);
+ 
+ 	UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
+ 
+ 	if (pup->popup) {
+ 		uiBut *but_activate = NULL;
+ 		UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NUMSELECT);
+ 		UI_block_direction_set(block, direction);
+ 
+ 		/* offset the mouse position, possibly based on earlier selection */
+ 		if ((block->flag & UI_BLOCK_POPUP_MEMORY) &&
+ 		    (bt = ui_popup_menu_memory_get(block)))
+ 		{
+ 			/* position mouse on last clicked item, at 0.8*width of the
+ 			 * button, so it doesn't overlap the text too much, also note
+ 			 * the offset is negative because we are inverse moving the
+ 			 * block to be under the mouse */
+ 			offset[0] = -(bt->rect.xmin + 0.8f * BLI_rctf_size_x(&bt->rect));
+ 			offset[1] = -(bt->rect.ymin + 0.5f * UI_UNIT_Y);
+ 
+ 			if (ui_but_is_editable(bt)) {
+ 				but_activate = bt;
+ 			}
+ 		}
+ 		else {
+ 			/* position mouse at 0.8*width of the button and below the tile
+ 			 * on the first item */
+ 			offset[0] = 0;
+ 			for (bt = block->buttons.first; bt; bt = bt->next)
+ 				offset[0] = min_ii(offset[0], -(bt->rect.xmin + 0.8f * BLI_rctf_size_x(&bt->rect)));
+ 
+ 			offset[1] = 2.1 * UI_UNIT_Y;
+ 
+ 			for (bt = block->buttons.first; bt; bt = bt->next) {
+ 				if (ui_but_is_editable(bt)) {
+ 					but_activate = bt;
+ 					break;
+ 				}
+ 			}
+ 		}
+ 
+ 		/* in rare cases this is needed since moving the popup
+ 		 * to be within the window bounds may move it away from the mouse,
+ 		 * This ensures we set an item to be active. */
+ 		if (but_activate) {
+ 			ui_but_activate_over(C, handle->region, but_activate);
+ 		}
+ 
+ 		block->minbounds = minwidth;
+ 		UI_block_bounds_set_menu(block, 1, offset[0], offset[1]);
+ 	}
+ 	else {
+ 		/* for a header menu we set the direction automatic */
+ 		if (!pup->slideout && flip) {
+ 			ScrArea *sa = CTX_wm_area(C);
+ 			if (sa && sa->headertype == HEADERDOWN) {
+ 				ARegion *ar = CTX_wm_region(C);
+ 				if (ar && ar->regiontype == RGN_TYPE_HEADER) {
+ 					UI_block_direction_set(block, UI_DIR_UP);
+ 					UI_block_order_flip(block);
+ 				}
+ 			}
+ 		}
+ 
+ 		block->minbounds = minwidth;
+ 		UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X);
+ 	}
+ 
+ 	/* if menu slides out of other menu, override direction */
+ 	if (pup->slideout)
+ 		UI_block_direction_set(block, UI_DIR_RIGHT);
+ 
+ 	return pup->block;
+ }
+ 
+ uiPopupBlockHandle *ui_popup_menu_create(
+         bContext *C, ARegion *butregion, uiBut *but,
+         uiMenuCreateFunc menu_func, void *arg)
+ {
+ 	wmWindow *window = CTX_wm_window(C);
+ 	uiStyle *style = UI_style_get_dpi();
+ 	uiPopupBlockHandle *handle;
+ 	uiPopupMenu *pup;
+ 
+ 	pup = MEM_callocN(sizeof(uiPopupMenu), __func__);
+ 	pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS_PULLDOWN);
+ 	pup->block->flag |= UI_BLOCK_NUMSELECT;  /* default menus to numselect */
+ 	pup->layout = UI_block_layout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, MENU_PADDING, style);
+ 	pup->slideout = but ? ui_block_is_menu(but->block) : false;
+ 	pup->but = but;
+ 	uiLayoutSetOperatorContext(pup->layout, WM_OP_INVOKE_REGION_WIN);
+ 
+ 	if (!but) {
+ 		/* no button to start from, means we are a popup */
+ 		pup->mx = window->eventstate->x;
+ 		pup->my = window->eventstate->y;
+ 		pup->popup = true;
+ 		pup->block->flag |= UI_BLOCK_NO_FLIP;
+ 	}
+ 	/* 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
+ 		if (but->context)
+ 			uiLayoutContextCopy(pup->layout, but->context);
+ 	}
+ 
+ 	/* menu is created from a callback */
+ 	pup->menu_func = menu_func;
+ 	pup->menu_arg = arg;
+ 
+ 	handle = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup);
+ 
+ 	if (!but) {
+ 		handle->popup = true;
+ 
+ 		UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
+ 		WM_ev

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list