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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-02-04 14:52:16 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-02-04 14:52:16 +0300
commitdf7e7660325611847721768fb7d082e7d5f2736c (patch)
treea13434a5824a3f55c46f6d876275f864647c0f95 /source/blender/editors/interface
parent0341e762b28f732dd2913ebec48405f7718a4617 (diff)
UI
* Changed uiPupMenuOperator usage to uiPupMenuBegin/End (simpler, no need to build a string). Also made transform orientation and subdiv type enums instead of ints for this. * Added an icon argument to many of the uiMenu calls, and added a uiMenuItemIntO. * Move auto rna button creation out of outliner code, now is uiDefAutoButR for individual buttons and uiDefAutoButsRNA for a whole block. * Implemented uiPupBlock(O). Pressing F6 gives a menu with the properties of the last operator to test. I tried to make a redo last operator out of this but couldn't get the context correct for the operator to repeat in. Further the popup block also has some issues getting closed while editing buttons. * Fix uiAfterFunc memory leak on Ctrl+Q quit. * Fix handling of RNA number button dragging and sliding for RNA buttons with range -inf/inf.
Diffstat (limited to 'source/blender/editors/interface')
-rw-r--r--source/blender/editors/interface/interface.c36
-rw-r--r--source/blender/editors/interface/interface_handlers.c107
-rw-r--r--source/blender/editors/interface/interface_intern.h9
-rw-r--r--source/blender/editors/interface/interface_regions.c113
-rw-r--r--source/blender/editors/interface/interface_utils.c393
5 files changed, 547 insertions, 111 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index ce842699ce2..032aa952c5e 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -304,23 +304,28 @@ void ui_bounds_block(uiBlock *block)
block->safety.ymax= block->maxy+xof;
}
-static void ui_popup_bounds_block(const bContext *C, uiBlock *block)
+static void ui_popup_bounds_block(const bContext *C, uiBlock *block, int menu)
{
+ wmWindow *window= CTX_wm_window(C);
int startx, starty, endx, endy, width, height;
int oldbounds, mx, my, xmax, ymax;
oldbounds= block->bounds;
- /* compute bounds */
+ /* compute mouse position with user defined offset */
ui_bounds_block(block);
- mx= block->minx;
- my= block->miny;
+ mx= window->eventstate->x + block->minx + block->mx;
+ my= window->eventstate->y + block->miny + block->my;
- wm_window_get_size(CTX_wm_window(C), &xmax, &ymax);
+ wm_window_get_size(window, &xmax, &ymax);
/* first we ensure wide enough text bounds */
- block->bounds= 50;
- ui_text_bounds_block(block, block->minx);
+ if(menu) {
+ if(block->flag & UI_BLOCK_LOOP) {
+ block->bounds= 50;
+ ui_text_bounds_block(block, block->minx);
+ }
+ }
/* next we recompute bounds */
block->bounds= oldbounds;
@@ -373,11 +378,22 @@ void uiTextBoundsBlock(uiBlock *block, int addval)
block->dobounds= 2;
}
-/* used for menu popups */
-void uiPopupBoundsBlock(uiBlock *block, int addval)
+/* used for block popups */
+void uiPopupBoundsBlock(uiBlock *block, int addval, int mx, int my)
{
block->bounds= addval;
block->dobounds= 3;
+ block->mx= mx;
+ block->my= my;
+}
+
+/* used for menu popups */
+void uiMenuPopupBoundsBlock(uiBlock *block, int addval, int mx, int my)
+{
+ block->bounds= addval;
+ block->dobounds= 4;
+ block->mx= mx;
+ block->my= my;
}
void ui_autofill(uiBlock *block)
@@ -594,7 +610,7 @@ void uiEndBlock(const bContext *C, uiBlock *block)
/* after keymaps! */
if(block->dobounds == 1) ui_bounds_block(block);
else if(block->dobounds == 2) ui_text_bounds_block(block, 0.0f);
- else if(block->dobounds == 3) ui_popup_bounds_block(C, block);
+ else if(block->dobounds) ui_popup_bounds_block(C, block, (block->dobounds == 4));
if(block->autofill) ui_autofill(block);
if(block->minx==0.0 && block->maxx==0.0) uiBoundsBlock(block, 0);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index f2275a18db4..ac5e64c80a5 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -23,6 +23,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include <float.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
@@ -250,34 +251,35 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
static void ui_apply_but_funcs_after(bContext *C)
{
- uiAfterFunc *after;
+ uiAfterFunc *afterf, after;
ListBase funcs;
/* copy to avoid recursive calls */
funcs= UIAfterFuncs;
UIAfterFuncs.first= UIAfterFuncs.last= NULL;
- for(after=funcs.first; after; after=after->next) {
- if(after->func)
- after->func(C, after->func_arg1, after->func_arg2);
+ for(afterf=funcs.first; afterf; afterf=after.next) {
+ after= *afterf; /* copy to avoid memleak on exit() */
+ BLI_freelinkN(&funcs, afterf);
+
+ if(after.func)
+ after.func(C, after.func_arg1, after.func_arg2);
- if(after->handle_func)
- after->handle_func(C, after->handle_func_arg, after->retval);
- if(after->butm_func)
- after->butm_func(C, after->butm_func_arg, after->a2);
+ if(after.handle_func)
+ after.handle_func(C, after.handle_func_arg, after.retval);
+ if(after.butm_func)
+ after.butm_func(C, after.butm_func_arg, after.a2);
- if(after->opname)
- WM_operator_name_call(C, after->opname, after->opcontext, after->opptr);
- if(after->opptr) {
- WM_operator_properties_free(after->opptr);
- MEM_freeN(after->opptr);
+ if(after.opname)
+ WM_operator_name_call(C, after.opname, after.opcontext, after.opptr);
+ if(after.opptr) {
+ WM_operator_properties_free(after.opptr);
+ MEM_freeN(after.opptr);
}
- if(after->rnapoin.data)
- RNA_property_update(C, &after->rnapoin, after->rnaprop);
+ if(after.rnapoin.data)
+ RNA_property_update(C, &after.rnapoin, after.rnaprop);
}
-
- BLI_freelistN(&funcs);
}
static void ui_apply_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data)
@@ -1373,9 +1375,18 @@ static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, u
/* ************* number editing for various types ************* */
+static void but_clamped_range(uiBut *but, float *butmin, float *butmax, float *butrange)
+{
+ /* clamp button range to something reasonable in case
+ * we get -inf/inf from RNA properties */
+ *butmin= MAX2(but->min, -1e4f);
+ *butmax= MIN2(but->max, 1e4f);
+ *butrange= *butmax - *butmin;
+}
+
static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
{
- float butrange;
+ float butrange, butmin, butmax;
if(but->type == BUT_CURVE) {
data->cumap= (CurveMapping*)but->poin;
@@ -1395,8 +1406,9 @@ static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
data->value= data->origvalue;
but->editval= &data->value;
- butrange= (but->max - but->min);
- data->dragfstart= (butrange == 0.0)? 0.0f: (data->value - but->min)/butrange;
+ but_clamped_range(but, &butmin, &butmax, &butrange);
+
+ data->dragfstart= (butrange == 0.0)? 0.0f: (data->value - butmin)/butrange;
data->dragf= data->dragfstart;
}
@@ -1603,7 +1615,7 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, wmE
static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, int snap, int mx)
{
- float deler, tempf;
+ float deler, tempf, butmin, butmax, butrange;
int lvalue, temp, changed= 0;
if(mx == data->draglastx)
@@ -1619,28 +1631,30 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
data->dragstartx= mx; /* ignore mouse movement within drag-lock */
}
+ but_clamped_range(but, &butmin, &butmax, &butrange);
+
deler= 500;
if(!ui_is_but_float(but)) {
- if((but->max-but->min)<100) deler= 200.0;
- if((but->max-but->min)<25) deler= 50.0;
+ if((butrange)<100) deler= 200.0;
+ if((butrange)<25) deler= 50.0;
}
deler /= fac;
- if(ui_is_but_float(but) && but->max-but->min > 11) {
+ if(ui_is_but_float(but) && butrange > 11) {
/* non linear change in mouse input- good for high precicsion */
data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.002);
- } else if (!ui_is_but_float(but) && but->max-but->min > 129) { /* only scale large int buttons */
+ } else if (!ui_is_but_float(but) && butrange > 129) { /* only scale large int buttons */
/* non linear change in mouse input- good for high precicsionm ints need less fine tuning */
data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.004);
} else {
/*no scaling */
data->dragf+= ((float)(mx-data->draglastx))/deler ;
}
-
+
if(data->dragf>1.0) data->dragf= 1.0;
if(data->dragf<0.0) data->dragf= 0.0;
data->draglastx= mx;
- tempf= ( but->min + data->dragf*(but->max-but->min));
+ tempf= (butmin + data->dragf*butrange);
if(!ui_is_but_float(but)) {
@@ -1667,14 +1681,14 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
if(snap) {
if(snap == 2) {
if(tempf==but->min || tempf==but->max);
- else if(but->max-but->min < 2.10) tempf= 0.01*floor(100.0*tempf);
- else if(but->max-but->min < 21.0) tempf= 0.1*floor(10.0*tempf);
+ else if(butrange < 2.10) tempf= 0.01*floor(100.0*tempf);
+ else if(butrange < 21.0) tempf= 0.1*floor(10.0*tempf);
else tempf= floor(tempf);
}
else {
if(tempf==but->min || tempf==but->max);
- else if(but->max-but->min < 2.10) tempf= 0.1*floor(10*tempf);
- else if(but->max-but->min < 21.0) tempf= floor(tempf);
+ else if(butrange < 2.10) tempf= 0.1*floor(10*tempf);
+ else if(butrange < 21.0) tempf= floor(tempf);
else tempf= 10.0*floor(tempf/10.0);
}
}
@@ -1818,9 +1832,11 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, int shift, int ctrl, int mx)
{
- float deler, f, tempf;
+ float deler, f, tempf, butmin, butmax, butrange;
int temp, lvalue, changed= 0;
+ but_clamped_range(but, &butmin, &butmax, &butrange);
+
if(but->type==NUMSLI) deler= ((but->x2-but->x1)/2 - 5.0*but->aspect);
else if(but->type==HSVSLI) deler= ((but->x2-but->x1)/2 - 5.0*but->aspect);
else deler= (but->x2-but->x1- 5.0*but->aspect);
@@ -1831,7 +1847,7 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, int shift, i
f= (f-data->dragfstart)/10.0 + data->dragfstart;
CLAMP(f, 0.0, 1.0);
- tempf= but->min+f*(but->max-but->min);
+ tempf= butmin + f*butrange;
temp= floor(tempf+.5);
if(ctrl) {
@@ -1927,11 +1943,13 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
if(click) {
float f, h;
- float tempf;
+ float tempf, butmin, butmax, butrange;
int temp;
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ but_clamped_range(but, &butmin, &butmax, &butrange);
+
tempf= data->value;
temp= (int)data->value;
@@ -1940,7 +1958,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
if(but->type==SLI) f= (float)(mx-but->x1)/(but->x2-but->x1-h);
else f= (float)(mx- (but->x1+but->x2)/2)/((but->x2-but->x1)/2 - h);
- f= but->min+f*(but->max-but->min);
+ f= butmin + f*butrange;
if(!ui_is_but_float(but)) {
if(f<temp) temp--;
@@ -2848,7 +2866,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
button_tooltip_timer_reset(but);
/* automatic open pulldown block timer */
- if(ELEM5(but->type, BLOCK, MENU, PULLDOWN, HMENU, ICONTEXTROW)) {
+ if(ELEM4(but->type, BLOCK, PULLDOWN, HMENU, ICONTEXTROW)) {
if(!data->autoopentimer) {
int time;
@@ -3709,19 +3727,11 @@ static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata)
WM_event_remove_ui_handler(&CTX_wm_window(C)->handlers, ui_handler_popup, ui_handler_remove_popup, menu);
if(temp.menuretval == UI_RETURN_OK) {
- if(temp.popup_func) {
- temp.popup_func(C, temp.op_arg, temp.retvalue);
- }
- else if(temp.op_arg) {
- if(temp.propname)
- RNA_enum_set(temp.op_arg->ptr, temp.propname, temp.retvalue);
- WM_operator_call(C, temp.op_arg);
- }
+ if(temp.popup_func)
+ temp.popup_func(C, temp.popup_arg, temp.retvalue);
+ if(temp.opname)
+ WM_operator_name_call(C, temp.opname, temp.opcontext, NULL);
}
- /* always free operator */
- else if(temp.op_arg)
- WM_operator_free(temp.op_arg);
-
}
else {
/* re-enable tooltips */
@@ -3757,3 +3767,4 @@ void UI_add_popup_handlers(ListBase *handlers, uiPopupBlockHandle *menu)
{
WM_event_add_ui_handler(NULL, handlers, ui_handler_popup, ui_handler_remove_popup, menu);
}
+
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index d66c6e4129e..ce641076554 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -218,7 +218,7 @@ struct uiBlock {
char *lockstr;
float xofs, yofs; // offset to parent button
- int bounds, dobounds; // for doing delayed
+ int bounds, dobounds, mx, my; // for doing delayed
int endblock; // uiEndBlock done?
rctf safety; // pulldowns, to detect outside, can differ per case how it is created
@@ -277,9 +277,10 @@ struct uiPopupBlockHandle {
int popup;
void (*popup_func)(struct bContext *C, void *arg, int event);
void *popup_arg;
- /* for operator menus */
- struct wmOperator *op_arg;
- const char *propname;
+
+ /* for operator popups */
+ const char *opname;
+ int opcontext;
/* return values */
int butretval;
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 09bbbb9ea60..ffd742098de 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -1657,13 +1657,14 @@ static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiPopupBlockHandle *handle,
#define MENU_ITEM_OPNAME 2
#define MENU_ITEM_OPNAME_BOOL 3
#define MENU_ITEM_OPNAME_ENUM 4
-#define MENU_ITEM_OPNAME_FLOAT 5
-#define MENU_ITEM_RNA_BOOL 6
-#define MENU_ITEM_RNA_ENUM 7
-#define MENU_ITEM_LEVEL 8
-#define MENU_ITEM_LEVEL_OPNAME_ENUM 9
-#define MENU_ITEM_LEVEL_RNA_ENUM 10
-#define MENU_ITEM_SEPARATOR 11
+#define MENU_ITEM_OPNAME_INT 5
+#define MENU_ITEM_OPNAME_FLOAT 6
+#define MENU_ITEM_RNA_BOOL 7
+#define MENU_ITEM_RNA_ENUM 8
+#define MENU_ITEM_LEVEL 9
+#define MENU_ITEM_LEVEL_OPNAME_ENUM 10
+#define MENU_ITEM_LEVEL_RNA_ENUM 11
+#define MENU_ITEM_SEPARATOR 12
struct uiMenuItem {
struct uiMenuItem *next, *prev;
@@ -1675,7 +1676,7 @@ struct uiMenuItem {
char *opname; /* static string */
char *propname; /* static string */
- int retval, enumval, boolval;
+ int retval, enumval, boolval, intval;
float fltval;
int opcontext;
uiMenuHandleFunc eventfunc;
@@ -1762,15 +1763,15 @@ static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiPopupBlockHandle *handle,
block->themecol= TH_MENU_ITEM;
block->direction= UI_DOWN;
- width= 50; // fixed with, uiPopupBoundsBlock will compute actual width
+ width= 50; // fixed with, uiMenuPopupBoundsBlock will compute actual width
for(item= head->items.first; item; item= item->next) {
if(0) height+= PUP_LABELH; // XXX sepr line
else height+= MENU_BUTTON_HEIGHT;
}
- startx= info->mx;
- starty= info->my-height+MENU_BUTTON_HEIGHT/2;
+ startx= 0;
+ starty= 0;
/* here we go! */
if(head->name[0]) {
@@ -1836,6 +1837,12 @@ static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiPopupBlockHandle *handle,
y1 -= MENU_BUTTON_HEIGHT;
}
+ else if(item->type==MENU_ITEM_OPNAME_INT) {
+ but= uiDefIconTextButO(block, BUTM, item->opname, head->opcontext, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, "");
+ RNA_int_set(uiButGetOperatorPtrRNA(but), item->propname, item->intval);
+
+ y1 -= MENU_BUTTON_HEIGHT;
+ }
else if(item->type==MENU_ITEM_OPNAME_FLOAT) {
but= uiDefIconTextButO(block, BUTM, item->opname, item->opcontext, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, "");
RNA_float_set(uiButGetOperatorPtrRNA(but), item->propname, item->fltval);
@@ -1890,7 +1897,8 @@ static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiPopupBlockHandle *handle,
uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_RET_1);
uiBlockSetDirection(block, UI_DOWN);
- uiPopupBoundsBlock(block, 1);
+ /* here we set an offset for the mouse position */
+ uiMenuPopupBoundsBlock(block, 1, 0, -height+MENU_BUTTON_HEIGHT/2);
}
else {
/* for a header menu we set the direction automatic */
@@ -1985,18 +1993,18 @@ void uiMenuItemVal(uiMenuItem *head, const char *name, int icon, int argval)
}
/* regular operator item */
-void uiMenuItemO(uiMenuItem *head, char *name, int icon)
+void uiMenuItemO(uiMenuItem *head, int icon, char *opname)
{
- uiMenuItem *item= ui_menu_add_item(head, name, icon, 0);
+ uiMenuItem *item= ui_menu_add_item(head, "", icon, 0);
- item->opname= name; // static!
+ item->opname= opname; // static!
item->type = MENU_ITEM_OPNAME;
}
/* single operator item with property */
-void uiMenuItemEnumO(uiMenuItem *head, char *opname, char *propname, int value)
+void uiMenuItemEnumO(uiMenuItem *head, int icon, char *opname, char *propname, int value)
{
- uiMenuItem *item= ui_menu_add_item(head, "", 0, 0);
+ uiMenuItem *item= ui_menu_add_item(head, "", icon, 0);
item->opname= opname; // static!
item->propname= propname; // static!
@@ -2005,9 +2013,20 @@ void uiMenuItemEnumO(uiMenuItem *head, char *opname, char *propname, int value)
}
/* single operator item with property */
-void uiMenuItemFloatO(uiMenuItem *head, const char *name, char *opname, char *propname, float value)
+void uiMenuItemIntO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, int value)
{
- uiMenuItem *item= ui_menu_add_item(head, name, 0, 0);
+ uiMenuItem *item= ui_menu_add_item(head, name, icon, 0);
+
+ item->opname= opname; // static!
+ item->propname= propname; // static!
+ item->intval= value;
+ item->type = MENU_ITEM_OPNAME_INT;
+}
+
+/* single operator item with property */
+void uiMenuItemFloatO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, float value)
+{
+ uiMenuItem *item= ui_menu_add_item(head, name, icon, 0);
item->opname= opname; // static!
item->propname= propname; // static!
@@ -2016,9 +2035,9 @@ void uiMenuItemFloatO(uiMenuItem *head, const char *name, char *opname, char *pr
}
/* single operator item with property */
-void uiMenuItemBooleanO(uiMenuItem *head, char *opname, char *propname, int value)
+void uiMenuItemBooleanO(uiMenuItem *head, int icon, char *opname, char *propname, int value)
{
- uiMenuItem *item= ui_menu_add_item(head, "", 0, 0);
+ uiMenuItem *item= ui_menu_add_item(head, "", icon, 0);
item->opname= opname; // static!
item->propname= propname; // static!
@@ -2046,7 +2065,7 @@ void uiMenuItemsEnumO(uiMenuItem *head, char *opname, char *propname)
RNA_property_enum_items(&ptr, prop, &item, &totitem);
for (i=0; i<totitem; i++)
- uiMenuItemEnumO(head, opname, propname, item[i].value);
+ uiMenuItemEnumO(head, 0, opname, propname, item[i].value);
}
}
@@ -2142,12 +2161,13 @@ void uiMenuSeparator(uiMenuItem *head)
/*************************** Popup Menu API **************************/
/* only return handler, and set optional title */
-uiMenuItem *uiPupMenuBegin(const char *title)
+uiMenuItem *uiPupMenuBegin(const char *title, int icon)
{
uiMenuItem *item= MEM_callocN(sizeof(uiMenuItem), "menu start");
item->type = MENU_ITEM_TITLE;
item->opcontext= WM_OP_EXEC_REGION_WIN;
+ item->icon= icon;
/* NULL is no title */
if(title)
@@ -2179,32 +2199,6 @@ void uiPupMenuEnd(bContext *C, uiMenuItem *head)
MEM_freeN(head);
}
-/* This one will set enum propname, call operator and register it, and free the operator itself,
- call it in op->invoke with returning OPERATOR_RUNNING_MODAL */
-/* Note: propname has to be static */
-void uiPupMenuOperator(bContext *C, int maxrow, wmOperator *op, const char *propname, char *str)
-{
- wmWindow *window= CTX_wm_window(C);
- uiPupMenuInfo info;
- uiPopupBlockHandle *menu;
-
- memset(&info, 0, sizeof(info));
- info.mx= window->eventstate->x;
- info.my= window->eventstate->y;
- info.maxrow= maxrow;
- info.instr= str;
-
- menu= ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_PUPMENU, &info);
- menu->popup= 1;
-
- UI_add_popup_handlers(&window->handlers, menu);
- WM_event_add_mousemove(C);
-
- menu->op_arg= op;
- menu->propname= propname;
-}
-
-
/* this one only to be called with operatortype name option */
void uiPupMenu(bContext *C, int maxrow, uiMenuHandleFunc func, void *arg, char *str, ...)
{
@@ -2339,3 +2333,24 @@ void uiPupMenuReports(bContext *C, ReportList *reports)
BLI_dynstr_free(ds);
}
+/*************************** Popup Block API **************************/
+
+void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, char *opname, int opcontext)
+{
+ wmWindow *window= CTX_wm_window(C);
+ uiPopupBlockHandle *handle;
+
+ handle= ui_popup_block_create(C, NULL, NULL, func, NULL, arg);
+ handle->popup= 1;
+ handle->opname= opname;
+ handle->opcontext= opcontext;
+
+ UI_add_popup_handlers(&window->handlers, handle);
+ WM_event_add_mousemove(C);
+}
+
+void uiPupBlock(bContext *C, uiBlockCreateFunc func, void *arg)
+{
+ uiPupBlockO(C, func, arg, NULL, 0);
+}
+
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
new file mode 100644
index 00000000000..3ccd88f0cc2
--- /dev/null
+++ b/source/blender/editors/interface/interface_utils.c
@@ -0,0 +1,393 @@
+/**
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BKE_context.h"
+#include "BKE_idprop.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "ED_util.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/*************************** RNA Utilities ******************************/
+
+int UI_GetIconRNA(PointerRNA *ptr)
+{
+ StructRNA *rnatype= ptr->type;
+
+ if(rnatype == &RNA_Scene)
+ return ICON_SCENE_DEHLT;
+ else if(rnatype == &RNA_World)
+ return ICON_WORLD;
+ else if(rnatype == &RNA_Object)
+ return ICON_OBJECT;
+ else if(rnatype == &RNA_Mesh)
+ return ICON_MESH;
+ else if(rnatype == &RNA_MeshVertex)
+ return ICON_VERTEXSEL;
+ else if(rnatype == &RNA_MeshEdge)
+ return ICON_EDGESEL;
+ else if(rnatype == &RNA_MeshFace)
+ return ICON_FACESEL;
+ else if(rnatype == &RNA_MeshTextureFace)
+ return ICON_FACESEL_HLT;
+ else if(rnatype == &RNA_VertexGroup)
+ return ICON_VGROUP;
+ else if(rnatype == &RNA_VertexGroupElement)
+ return ICON_VGROUP;
+ else if(rnatype == &RNA_Curve)
+ return ICON_CURVE;
+ else if(rnatype == &RNA_MetaBall)
+ return ICON_MBALL;
+ else if(rnatype == &RNA_MetaElement)
+ return ICON_OUTLINER_DATA_META;
+ else if(rnatype == &RNA_Lattice)
+ return ICON_LATTICE;
+ else if(rnatype == &RNA_Armature)
+ return ICON_ARMATURE;
+ else if(rnatype == &RNA_Bone)
+ return ICON_BONE_DEHLT;
+ else if(rnatype == &RNA_Camera)
+ return ICON_CAMERA;
+ else if(rnatype == &RNA_LocalLamp)
+ return ICON_LAMP;
+ else if(rnatype == &RNA_AreaLamp)
+ return ICON_LAMP;
+ else if(rnatype == &RNA_SpotLamp)
+ return ICON_LAMP;
+ else if(rnatype == &RNA_SunLamp)
+ return ICON_LAMP;
+ else if(rnatype == &RNA_HemiLamp)
+ return ICON_LAMP;
+ else if(rnatype == &RNA_Lamp)
+ return ICON_LAMP;
+ else if(rnatype == &RNA_Group)
+ return ICON_GROUP;
+ else if(rnatype == &RNA_ParticleSystem)
+ return ICON_PARTICLES;
+ else if(rnatype == &RNA_ParticleSettings)
+ return ICON_PARTICLES;
+ else if(rnatype == &RNA_Material)
+ return ICON_MATERIAL;
+ else if(rnatype == &RNA_Texture)
+ return ICON_TEXTURE;
+ else if(rnatype == &RNA_TextureSlot)
+ return ICON_TEXTURE;
+ else if(rnatype == &RNA_WorldTextureSlot)
+ return ICON_TEXTURE;
+ else if(rnatype == &RNA_MaterialTextureSlot)
+ return ICON_TEXTURE;
+ else if(rnatype == &RNA_Image)
+ return ICON_TEXTURE;
+ else if(rnatype == &RNA_Screen)
+ return ICON_SPLITSCREEN;
+ else if(rnatype == &RNA_NodeTree)
+ return ICON_NODE;
+ else if(rnatype == &RNA_Text)
+ return ICON_TEXT;
+ else if(rnatype == &RNA_Sound)
+ return ICON_SOUND;
+ else if(rnatype == &RNA_Brush)
+ return ICON_TPAINT_HLT;
+ else if(rnatype == &RNA_Library)
+ return ICON_LIBRARY_DEHLT;
+ else if(rnatype == &RNA_Action)
+ return ICON_ACTION;
+ else if(rnatype == &RNA_FCurve)
+ return ICON_IPO_DEHLT;
+ //else if(rnatype == &RNA_Ipo)
+ // return ICON_IPO_DEHLT;
+ else if(rnatype == &RNA_Key)
+ return ICON_SHAPEKEY;
+ else if(rnatype == &RNA_Main)
+ return ICON_BLENDER;
+ else if(rnatype == &RNA_Struct)
+ return ICON_RNA;
+ else if(rnatype == &RNA_Property)
+ return ICON_RNA;
+ else if(rnatype == &RNA_BooleanProperty)
+ return ICON_RNA;
+ else if(rnatype == &RNA_IntProperty)
+ return ICON_RNA;
+ else if(rnatype == &RNA_FloatProperty)
+ return ICON_RNA;
+ else if(rnatype == &RNA_StringProperty)
+ return ICON_RNA;
+ else if(rnatype == &RNA_EnumProperty)
+ return ICON_RNA;
+ else if(rnatype == &RNA_EnumPropertyItem)
+ return ICON_RNA;
+ else if(rnatype == &RNA_PointerProperty)
+ return ICON_RNA;
+ else if(rnatype == &RNA_CollectionProperty)
+ return ICON_RNA;
+ else if(rnatype == &RNA_GameObjectSettings)
+ return ICON_GAME;
+ else if(rnatype == &RNA_ScriptLink)
+ return ICON_PYTHON;
+
+ /* modifiers */
+ else if(rnatype == &RNA_SubsurfModifier)
+ return ICON_MOD_SUBSURF;
+ else if(rnatype == &RNA_ArmatureModifier)
+ return ICON_ARMATURE;
+ else if(rnatype == &RNA_LatticeModifier)
+ return ICON_LATTICE;
+ else if(rnatype == &RNA_CurveModifier)
+ return ICON_CURVE;
+ else if(rnatype == &RNA_BuildModifier)
+ return ICON_MOD_BUILD;
+ else if(rnatype == &RNA_MirrorModifier)
+ return ICON_MOD_MIRROR;
+ else if(rnatype == &RNA_DecimateModifier)
+ return ICON_MOD_DECIM;
+ else if(rnatype == &RNA_WaveModifier)
+ return ICON_MOD_WAVE;
+ else if(rnatype == &RNA_HookModifier)
+ return ICON_HOOK;
+ else if(rnatype == &RNA_SoftbodyModifier)
+ return ICON_MOD_SOFT;
+ else if(rnatype == &RNA_BooleanModifier)
+ return ICON_MOD_BOOLEAN;
+ else if(rnatype == &RNA_ParticleInstanceModifier)
+ return ICON_MOD_PARTICLEINSTANCE;
+ else if(rnatype == &RNA_ParticleSystemModifier)
+ return ICON_MOD_PARTICLES;
+ else if(rnatype == &RNA_EdgeSplitModifier)
+ return ICON_MOD_EDGESPLIT;
+ else if(rnatype == &RNA_ArrayModifier)
+ return ICON_MOD_ARRAY;
+ else if(rnatype == &RNA_UVProjectModifier)
+ return ICON_MOD_UVPROJECT;
+ else if(rnatype == &RNA_DisplaceModifier)
+ return ICON_MOD_DISPLACE;
+ else
+ return ICON_DOT;
+}
+
+uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, char *name, int x1, int y1, int x2, int y2)
+{
+ uiBut *but=NULL;
+ const char *propname= RNA_property_identifier(ptr, prop);
+ int arraylen= RNA_property_array_length(ptr, prop);
+
+ switch(RNA_property_type(ptr, prop)) {
+ case PROP_BOOLEAN: {
+ int value, length;
+
+ if(arraylen && index == -1)
+ return NULL;
+
+ length= RNA_property_array_length(ptr, prop);
+
+ if(length)
+ value= RNA_property_boolean_get_index(ptr, prop, index);
+ else
+ value= RNA_property_boolean_get(ptr, prop);
+
+ if(name && strcmp(name, "") == 0)
+ name= (value)? "Enabled": "Disabled";
+
+ but= uiDefButR(block, TOG, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ break;
+ }
+ case PROP_INT:
+ case PROP_FLOAT:
+ if(arraylen && index == -1) {
+ if(RNA_property_subtype(ptr, prop) == PROP_COLOR)
+ but= uiDefButR(block, COL, 0, name, x1, y1, x2, y2, ptr, propname, 0, 0, 0, -1, -1, NULL);
+ }
+ else
+ but= uiDefButR(block, NUM, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ break;
+ case PROP_ENUM:
+ but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ break;
+ case PROP_STRING:
+ but= uiDefButR(block, TEX, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ break;
+ case PROP_POINTER: {
+ PointerRNA pptr;
+ PropertyRNA *nameprop;
+ char *text, *descr, textbuf[256];
+ int icon;
+
+ pptr= RNA_property_pointer_get(ptr, prop);
+
+ if(!pptr.data)
+ return NULL;
+
+ icon= UI_GetIconRNA(&pptr);
+ nameprop= RNA_struct_name_property(&pptr);
+
+ if(nameprop) {
+ text= RNA_property_string_get_alloc(&pptr, nameprop, textbuf, sizeof(textbuf));
+ descr= (char*)RNA_property_ui_description(&pptr, prop);
+ but= uiDefIconTextBut(block, LABEL, 0, icon, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, descr);
+ if(text != textbuf)
+ MEM_freeN(text);
+ }
+ else {
+ text= (char*)RNA_struct_ui_name(&pptr);
+ descr= (char*)RNA_property_ui_description(&pptr, prop);
+ but= uiDefIconTextBut(block, LABEL, 0, icon, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, descr);
+ }
+ break;
+ }
+ case PROP_COLLECTION: {
+ char text[256];
+ sprintf(text, "%d items", RNA_property_collection_length(ptr, prop));
+ but= uiDefBut(block, LABEL, 0, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, NULL);
+ uiButSetFlag(but, UI_BUT_DISABLED);
+ break;
+ }
+ default:
+ but= NULL;
+ break;
+ }
+
+ return but;
+}
+
+#define RNA_BUT_WIDTH 150
+#define RNA_BUT_HEIGHT 20
+
+int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
+{
+ CollectionPropertyIterator iter;
+ PropertyRNA *iterprop, *prop;
+ PropertySubType subtype;
+ char *name, namebuf[128];
+ int a, length, x= 0, y= 0;
+
+ x= 0;
+ y= 0;
+
+ /* create buttons */
+ uiSetCurFont(block, UI_HELVB);
+ uiDefBut(block, LABEL, 0, (char*)RNA_struct_ui_name(ptr), x, y, RNA_BUT_WIDTH, RNA_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
+ y -= RNA_BUT_HEIGHT;
+ uiSetCurFont(block, UI_HELV);
+
+ iterprop= RNA_struct_iterator_property(ptr);
+ RNA_property_collection_begin(ptr, iterprop, &iter);
+
+ for(; iter.valid; RNA_property_collection_next(&iter)) {
+ prop= iter.ptr.data;
+
+ if(strcmp(RNA_property_identifier(ptr, prop), "rna_type") == 0)
+ continue;
+
+ if((length= RNA_property_array_length(ptr, prop))) {
+ name= (char*)RNA_property_ui_name(ptr, prop);
+ uiDefBut(block, LABEL, 0, name, x, y, RNA_BUT_WIDTH, RNA_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
+ }
+ else
+ length= 1;
+
+ subtype= RNA_property_subtype(ptr, prop);
+
+ name= (char*)RNA_property_ui_name(ptr, prop);
+ uiDefBut(block, LABEL, 0, name, x, y, RNA_BUT_WIDTH, RNA_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
+
+ uiBlockBeginAlign(block);
+
+ if(length <= 16 && subtype == PROP_MATRIX) {
+ /* matrix layout */
+ int size, row, col, butwidth;
+
+ size= ceil(sqrt(length));
+ butwidth= RNA_BUT_WIDTH*2/size;
+ y -= RNA_BUT_HEIGHT;
+
+ for(a=0; a<length; a++) {
+ col= a%size;
+ row= a/size;
+
+ uiDefAutoButR(block, ptr, prop, a, "", x+butwidth*col, y-row*RNA_BUT_HEIGHT, butwidth, RNA_BUT_HEIGHT-1);
+ }
+
+ y -= RNA_BUT_HEIGHT*(length/size);
+ }
+ else if(length <= 4 && ELEM3(subtype, PROP_ROTATION, PROP_VECTOR, PROP_COLOR)) {
+ static char *vectoritem[4]= {"X:", "Y:", "Z:", "W:"};
+ static char *quatitem[4]= {"W:", "X:", "Y:", "Z:"};
+ static char *coloritem[4]= {"R:", "G:", "B:", "A:"};
+ int butwidth;
+
+ butwidth= RNA_BUT_WIDTH*2/length;
+ y -= RNA_BUT_HEIGHT;
+
+ for(a=0; a<length; a++) {
+ if(length == 4 && subtype == PROP_ROTATION)
+ name= quatitem[a];
+ else if(subtype == PROP_VECTOR || subtype == PROP_ROTATION)
+ name= vectoritem[a];
+ else
+ name= coloritem[a];
+
+ uiDefAutoButR(block, ptr, prop, a, name, x+butwidth*a, y, butwidth, RNA_BUT_HEIGHT-1);
+ }
+ y -= RNA_BUT_HEIGHT;
+ }
+ else {
+ if(RNA_property_array_length(ptr, prop)) {
+ sprintf(namebuf, "%d:", a+1);
+ name= namebuf;
+ }
+ else
+ name= "";
+
+ uiDefAutoButR(block, ptr, prop, a, name, x+RNA_BUT_WIDTH, y, RNA_BUT_WIDTH, RNA_BUT_HEIGHT-1);
+ y -= RNA_BUT_HEIGHT;
+ }
+
+ uiBlockEndAlign(block);
+ }
+
+ RNA_property_collection_end(&iter);
+
+ return -y;
+}
+
+#if 0
+#endif
+