Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2014-02-10 05:52:35 +0400
committerCampbell Barton <ideasman42@gmail.com>2014-02-10 06:04:43 +0400
commit35f62bdced41b8960c90ad20a2f90809c4b677e9 (patch)
treed8839ac4babb896ac1b1afa7251cbf93b1660cc2 /source/blender/editors/interface/interface.c
parent21b60ea7e16c825a05eab910d13337dd079b8bbf (diff)
UI: refactor menus to remove menus encoded in strings
On every redraw a single unopened dropdown boxe would translate and convert every EnumPropertyItem into a string, then decode every item, and search those items to find the name of the button to draw. Replace this with a custom menu callback for RNA enums, tooltips for enums now show too.
Diffstat (limited to 'source/blender/editors/interface/interface.c')
-rw-r--r--source/blender/editors/interface/interface.c197
1 files changed, 163 insertions, 34 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index fb0b0351453..4034ad46520 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -48,11 +48,9 @@
#include "BLI_path_util.h"
#include "BLI_rect.h"
-#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
-#include "BKE_library.h"
#include "BKE_unit.h"
#include "BKE_screen.h"
#include "BKE_idprop.h"
@@ -82,6 +80,8 @@
#define UI_BUT_VALUE_UNSET DBL_MAX
#define UI_GET_BUT_VALUE_INIT(_but, _value) if (_value == DBL_MAX) { (_value) = ui_get_but_val(_but); } (void)0
+#define B_NOP -1
+
/*
* a full doc with API notes can be found in bf-blender/trunk/blender/doc/guides/interface_API.txt
*
@@ -670,6 +670,25 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu
ui_but_update_linklines(block, oldbut, but);
+ /* move/copy string from the new button to the old */
+ /* needed for alt+mouse wheel over enums */
+ if (but->str != but->strdata) {
+ if (oldbut->str != oldbut->strdata) {
+ SWAP(char *, but->str, oldbut->str);
+ }
+ else {
+ oldbut->str = but->str;
+ but->str = but->strdata;
+ }
+ }
+ else {
+ if (oldbut->str != oldbut->strdata) {
+ MEM_freeN(oldbut->str);
+ oldbut->str = oldbut->strdata;
+ }
+ BLI_strncpy(oldbut->strdata, but->strdata, sizeof(oldbut->strdata));
+ }
+
BLI_remlink(&block->buttons, but);
ui_free_but(C, but);
@@ -2469,15 +2488,6 @@ void ui_check_but(uiBut *but)
/* name: */
switch (but->type) {
-
- case MENU:
-
- if (BLI_rctf_size_x(&but->rect) > 24.0f) {
- UI_GET_BUT_VALUE_INIT(but, value);
- ui_set_name_menu(but, (int)value);
- }
- break;
-
case NUM:
case NUMSLI:
@@ -2966,6 +2976,127 @@ static void ui_def_but_rna__disable(uiBut *but)
but->lockstr = "";
}
+static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *but_p)
+{
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiPopupBlockHandle *handle = block->handle;
+ uiBut *but = (uiBut *)but_p;
+
+ /* see comment in ui_item_enum_expand, re: uiname */
+ EnumPropertyItem *item, *item_array;
+ bool free;
+
+ uiLayout *split, *column = NULL;
+
+ int totitems = 0;
+ int columns, rows, a, b;
+ int column_start = 0, column_end = 0;
+ int nbr_entries_nosepr = 0;
+
+ uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
+
+ RNA_property_enum_items_gettexted(block->evil_C, &but->rnapoin, but->rnaprop, &item_array, NULL, &free);
+
+
+ /* we dont want nested rows, cols in menus */
+ uiBlockSetCurLayout(block, layout);
+
+ for (item = item_array; item->identifier; item++, totitems++) {
+ if (!item->identifier[0]) {
+ /* inconsistent, but menus with labels do not look good flipped */
+ if (item->name) {
+ block->flag |= UI_BLOCK_NO_FLIP;
+ nbr_entries_nosepr++;
+ }
+ /* We do not want simple separators in nbr_entries_nosepr count */
+ continue;
+ }
+ nbr_entries_nosepr++;
+ }
+
+ /* Columns and row estimation. Ignore simple separators here. */
+ columns = (nbr_entries_nosepr + 20) / 20;
+ if (columns < 1)
+ columns = 1;
+ if (columns > 8)
+ columns = (nbr_entries_nosepr + 25) / 25;
+
+ rows = totitems / columns;
+ if (rows < 1)
+ rows = 1;
+ while (rows * columns < totitems)
+ rows++;
+
+ /* Title */
+ uiDefBut(block, LABEL, 0, RNA_property_ui_name(but->rnaprop),
+ 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiItemS(layout);
+
+ /* note, item_array[...] is reversed on access */
+
+ /* create items */
+ split = uiLayoutSplit(layout, 0.0f, false);
+
+ for (a = 0; a < totitems; a++) {
+ if (a == column_end) {
+ /* start new column, and find out where it ends in advance, so we
+ * can flip the order of items properly per column */
+ column_start = a;
+ column_end = totitems;
+
+ for (b = a + 1; b < totitems; b++) {
+ item = &item_array[ b];
+
+ /* new column on N rows or on separation label */
+ if (((b - a) % rows == 0) || (!item->identifier[0] && item->name)) {
+ column_end = b;
+ break;
+ }
+ }
+
+ column = uiLayoutColumn(split, false);
+ }
+
+ if (block->flag & UI_BLOCK_NO_FLIP) {
+ item = &item_array[a];
+ }
+ else {
+ item = &item_array[(column_start + column_end - 1 - a)];
+ }
+
+ if (!item->identifier[0]) {
+ if (item->name) {
+ if (item->icon) {
+ uiItemL(column, item->name, item->icon);
+ }
+ else {
+ /* Do not use uiItemL here, as our root layout is a menu one, it will add a fake blank icon! */
+ uiDefBut(block, LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ }
+ }
+ else {
+ uiItemS(column);
+ }
+ }
+ else {
+ if (item->icon) {
+ uiDefIconTextButF(block, BUTM, B_NOP, item->icon, item->name, 0, 0,
+ UI_UNIT_X * 5, UI_UNIT_Y, &handle->retvalue, (float) item->value, 0.0, 0, -1, item->description);
+ }
+ else {
+ uiDefButF(block, BUTM, B_NOP, item->name, 0, 0,
+ UI_UNIT_X * 5, UI_UNIT_X, &handle->retvalue, (float) item->value, 0.0, 0, -1, item->description);
+ }
+ }
+ }
+
+ uiBlockSetCurLayout(block, layout);
+
+ if (free) {
+ MEM_freeN(item_array);
+ }
+}
+
/**
* ui_def_but_rna_propname and ui_def_but_rna
* both take the same args except for propname vs prop, this is done so we can
@@ -2982,6 +3113,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
const PropertyType proptype = RNA_property_type(prop);
uiBut *but;
int freestr = 0, icon = 0;
+ uiMenuCreateFunc func = NULL;
if (ELEM3(type, COLOR, HSVCIRCLE, HSVCUBE)) {
BLI_assert(index == -1);
@@ -2991,38 +3123,30 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
if (!str) {
if (type == MENU && proptype == PROP_ENUM) {
EnumPropertyItem *item;
- DynStr *dynstr;
- int i, totitem, value;
+ int totitem, value;
bool free;
+ int i;
- RNA_property_enum_items_gettexted(block->evil_C, ptr, prop, &item, &totitem, &free);
+ RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free);
value = RNA_property_enum_get(ptr, prop);
-
- dynstr = BLI_dynstr_new();
- BLI_dynstr_appendf(dynstr, "%s%%t", RNA_property_ui_name(prop));
- for (i = 0; i < totitem; i++) {
- if (!item[i].identifier[0]) {
- if (item[i].name)
- BLI_dynstr_appendf(dynstr, "|%s%%l", item[i].name);
- else
- BLI_dynstr_append(dynstr, "|%l");
- }
- else if (item[i].icon)
- BLI_dynstr_appendf(dynstr, "|%s %%i%d %%x%d", item[i].name, item[i].icon, item[i].value);
- else
- BLI_dynstr_appendf(dynstr, "|%s %%x%d", item[i].name, item[i].value);
-
- if (value == item[i].value)
- icon = item[i].icon;
+ i = RNA_enum_from_value(item, value);
+ if (i != -1) {
+ str = item[i].name;
+ icon = item[i].icon;
+ }
+ else {
+ str = "";
}
- str = BLI_dynstr_get_cstring(dynstr);
- BLI_dynstr_free(dynstr);
if (free) {
MEM_freeN(item);
}
- freestr = 1;
+#ifdef WITH_INTERNATIONAL
+ str = CTX_IFACE_(RNA_property_translation_context(prop), str);
+#endif
+
+ func = ui_def_but_rna__menu;
}
else if (ELEM(type, ROW, LISTROW) && proptype == PROP_ENUM) {
EnumPropertyItem *item, *item_array = NULL;
@@ -3123,6 +3247,11 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
but->a1 = ui_get_but_step_unit(but, but->a1);
}
+ if (func) {
+ but->menu_create_func = func;
+ but->poin = (char *)but;
+ }
+
if (freestr) {
MEM_freeN((void *)str);
}