2.5: Modifiers & Menus
[blender-staging.git] / source / blender / editors / interface / interface_templates.c
index 12954fe77c0ef5afcfb3b63b3bceaaaed9ee7186..e7c99f10a66c39f2adad55828010e230f1e8dcc1 100644 (file)
  */
 
 #include <stdlib.h>
+#include <string.h>
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+
 #include "BLI_string.h"
 
 #include "BKE_context.h"
+#include "BKE_icons.h"
+#include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_utildefines.h"
 
 #include "ED_screen.h"
+#include "ED_previewrender.h"
 
 #include "RNA_access.h"
 
@@ -41,6 +48,7 @@
 
 #include "UI_interface.h"
 #include "UI_resources.h"
+#include "interface_intern.h"
 
 void ui_template_fix_linking()
 {
@@ -48,70 +56,127 @@ void ui_template_fix_linking()
 
 /********************** Header Template *************************/
 
-void uiTemplateHeader(uiLayout *layout, bContext *C)
+void uiTemplateHeader(uiLayout *layout, bContext *C, int menus)
 {
        uiBlock *block;
        
        block= uiLayoutFreeBlock(layout);
-       ED_area_header_standardbuttons(C, block, 0);
+       if(menus) ED_area_header_standardbuttons(C, block, 0);
+       else ED_area_header_switchbutton(C, block, 0);
 }
 
-/******************* Header ID Template ************************/
+/********************** Search Callbacks *************************/
 
-typedef struct TemplateHeaderID {
+typedef struct TemplateID {
        PointerRNA ptr;
        PropertyRNA *prop;
 
-       int flag;
-       short browse;
+       ListBase *idlb;
+} TemplateID;
+
+/* Search browse menu, assign  */
+static void id_search_call_cb(struct bContext *C, void *arg_template, void *item)
+{
+       TemplateID *template= (TemplateID*)arg_template;
 
-       char newop[256];
-       char openop[256];
-       char unlinkop[256];
-} TemplateHeaderID;
+       /* ID */
+       if(item) {
+               PointerRNA idptr;
 
-static void template_header_id_cb(bContext *C, void *arg_litem, void *arg_event)
+               RNA_id_pointer_create(item, &idptr);
+               RNA_property_pointer_set(&template->ptr, template->prop, idptr);
+               RNA_property_update(C, &template->ptr, template->prop);
+       }
+}
+
+/* ID Search browse menu, do the search */
+static void id_search_cb(const struct bContext *C, void *arg_template, char *str, uiSearchItems *items)
 {
-       TemplateHeaderID *template= (TemplateHeaderID*)arg_litem;
-       PointerRNA idptr= RNA_property_pointer_get(&template->ptr, template->prop);
-       ID *idtest, *id= idptr.data;
-       ListBase *lb= wich_libbase(CTX_data_main(C), ID_TXT);
-       int nr, event= GET_INT_FROM_POINTER(arg_event);
-       
-       if(event == UI_ID_BROWSE && template->browse == 32767)
-               event= UI_ID_ADD_NEW;
-       else if(event == UI_ID_BROWSE && template->browse == 32766)
-               event= UI_ID_OPEN;
+       TemplateID *template= (TemplateID*)arg_template;
+       Scene *scene= CTX_data_scene(C);
+       ListBase *lb= template->idlb;
+       ID *id;
+       int iconid;
 
-       switch(event) {
-               case UI_ID_BROWSE: {
-                       if(template->browse== -2) {
-                               /* XXX implement or find a replacement
-                                * activate_databrowse((ID *)G.buts->lockpoin, GS(id->name), 0, B_MESHBROWSE, &template->browse, do_global_buttons); */
-                               return;
-                       }
-                       if(template->browse < 0)
-                               return;
+       /* ID listbase */
+       for(id= lb->first; id; id= id->next) {
+               if(BLI_strcasestr(id->name+2, str)) {
+                       iconid= ui_id_icon_get(scene, id);
 
-                       for(idtest=lb->first, nr=1; idtest; idtest=idtest->next, nr++) {
-                               if(nr==template->browse) {
-                                       if(id == idtest)
-                                               return;
+                       if(!uiSearchItemAdd(items, id->name+2, id, iconid))
+                               break;
+               }
+       }
+}
 
-                                       id= idtest;
-                                       RNA_id_pointer_create(id, &idptr);
-                                       RNA_property_pointer_set(&template->ptr, template->prop, idptr);
-                                       RNA_property_update(C, &template->ptr, template->prop);
-                                       /* XXX */
+/* ID Search browse menu, open */
+static uiBlock *search_menu(bContext *C, ARegion *ar, void *arg_litem)
+{
+       static char search[256];
+       static TemplateID template;
+       PointerRNA idptr;
+       wmEvent event;
+       wmWindow *win= CTX_wm_window(C);
+       uiBlock *block;
+       uiBut *but;
+       
+       /* clear initial search string, then all items show */
+       search[0]= 0;
+       /* arg_litem is malloced, can be freed by parent button */
+       template= *((TemplateID*)arg_litem);
+       
+       /* get active id for showing first item */
+       idptr= RNA_property_pointer_get(&template.ptr, template.prop);
 
-                                       break;
-                               }
+       block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
+       uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
+       
+       /* fake button, it holds space for search items */
+       uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+       
+       but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, "");
+       uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
+       
+       uiBoundsBlock(block, 6);
+       uiBlockSetDirection(block, UI_DOWN);    
+       uiEndBlock(C, block);
+       
+       event= *(win->eventstate);      /* XXX huh huh? make api call */
+       event.type= EVT_BUT_OPEN;
+       event.val= KM_PRESS;
+       event.customdata= but;
+       event.customdatafree= FALSE;
+       wm_event_add(win, &event);
+       
+       return block;
+}
+
+/************************ ID Template ***************************/
+
+static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
+{
+       TemplateID *template= (TemplateID*)arg_litem;
+       PointerRNA idptr= RNA_property_pointer_get(&template->ptr, template->prop);
+       ID *id= idptr.data;
+       int event= GET_INT_FROM_POINTER(arg_event);
+       
+       switch(event) {
+               case UI_ID_BROWSE:
+               case UI_ID_PIN:
+                       printf("warning, id event %d shouldnt come here\n", event);
+                       break;
+               case UI_ID_OPEN:
+               case UI_ID_ADD_NEW:
+                       if(template->idlb->last) {
+                               RNA_id_pointer_create(template->idlb->last, &idptr);
+                               RNA_property_pointer_set(&template->ptr, template->prop, idptr);
+                               RNA_property_update(C, &template->ptr, template->prop);
                        }
                        break;
-               }
-#if 0
                case UI_ID_DELETE:
-                       id= NULL;
+                       memset(&idptr, 0, sizeof(idptr));
+                       RNA_property_pointer_set(&template->ptr, template->prop, idptr);
+                       RNA_property_update(C, &template->ptr, template->prop);
                        break;
                case UI_ID_FAKE_USER:
                        if(id) {
@@ -120,15 +185,6 @@ static void template_header_id_cb(bContext *C, void *arg_litem, void *arg_event)
                        }
                        else return;
                        break;
-#endif
-               case UI_ID_PIN:
-                       break;
-               case UI_ID_ADD_NEW:
-                       WM_operator_name_call(C, template->newop, WM_OP_INVOKE_REGION_WIN, NULL);
-                       break;
-               case UI_ID_OPEN:
-                       WM_operator_name_call(C, template->openop, WM_OP_INVOKE_REGION_WIN, NULL);
-                       break;
 #if 0
                case UI_ID_ALONE:
                        if(!id || id->us < 1)
@@ -144,94 +200,101 @@ static void template_header_id_cb(bContext *C, void *arg_litem, void *arg_event)
        }
 }
 
-static void template_header_ID(bContext *C, uiBlock *block, TemplateHeaderID *template)
+static void template_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type, int flag, char *newop, char *unlinkop)
 {
        uiBut *but;
-       TemplateHeaderID *duptemplate;
        PointerRNA idptr;
        ListBase *lb;
-       int x= 0, y= 0;
 
        idptr= RNA_property_pointer_get(&template->ptr, template->prop);
-       lb= wich_libbase(CTX_data_main(C), ID_TXT);
+       lb= template->idlb;
 
        uiBlockBeginAlign(block);
-       if(template->flag & UI_ID_BROWSE) {
-               char *extrastr, *str;
-               
-               if((template->flag & UI_ID_ADD_NEW) && (template->flag && UI_ID_OPEN))
-                       extrastr= "OPEN NEW %x 32766 |ADD NEW %x 32767";
-               else if(template->flag & UI_ID_ADD_NEW)
-                       extrastr= "ADD NEW %x 32767";
-               else if(template->flag & UI_ID_OPEN)
-                       extrastr= "OPEN NEW %x 32766";
-               else
-                       extrastr= NULL;
 
-               duptemplate= MEM_dupallocN(template);
-               IDnames_to_pupstring(&str, NULL, extrastr, lb, idptr.data, &duptemplate->browse);
+       if(idptr.type)
+               type= idptr.type;
 
-               but= uiDefButS(block, MENU, 0, str, x, y, UI_UNIT_X, UI_UNIT_Y, &duptemplate->browse, 0, 0, 0, 0, "Browse existing choices, or add new");
-               uiButSetNFunc(but, template_header_id_cb, duptemplate, SET_INT_IN_POINTER(UI_ID_BROWSE));
-               x+= UI_UNIT_X;
-       
-               MEM_freeN(str);
+       if(flag & UI_ID_BROWSE) {
+               but= uiDefBlockButN(block, search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X*1.6, UI_UNIT_Y, "Browse ID data");
+               if(type) {
+                       but->icon= RNA_struct_ui_icon(type);
+                       but->flag|= UI_HAS_ICON;
+                       but->flag|= UI_ICON_LEFT;
+               }
        }
 
        /* text button with name */
        if(idptr.data) {
                char name[64];
 
-               text_idbutton(idptr.data, name);
-               but= uiDefButR(block, TEX, 0, name, x, y, UI_UNIT_X*6, UI_UNIT_Y, &idptr, "name", -1, 0, 0, -1, -1, NULL);
-               uiButSetNFunc(but, template_header_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
-               x += UI_UNIT_X*6;
-
-               /* delete button */
-               if(template->flag & UI_ID_DELETE) {
-                       but= uiDefIconButO(block, BUT, template->unlinkop, WM_OP_EXEC_REGION_WIN, ICON_X, x, y, UI_UNIT_X, UI_UNIT_Y, NULL);
-                       x += UI_UNIT_X;
+               //text_idbutton(idptr.data, name);
+               name[0]= '\0';
+               but= uiDefButR(block, TEX, 0, name, 0, 0, UI_UNIT_X*6, UI_UNIT_Y, &idptr, "name", -1, 0, 0, -1, -1, NULL);
+               uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
+       }
+       
+       if(flag & UI_ID_ADD_NEW) {
+               int w= idptr.data?UI_UNIT_X:UI_UNIT_X*6;
+               
+               if(newop) {
+                       but= uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_REGION_WIN, ICON_ZOOMIN, (idptr.data)? "": "Add New", 0, 0, w, UI_UNIT_Y, NULL);
+                       uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
+               }
+               else {
+                       but= uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (idptr.data)? "": "Add New", 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+                       uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
                }
        }
+       
+       /* delete button */
+       if(idptr.data && (flag & UI_ID_DELETE)) {
+               if(unlinkop) {
+                       but= uiDefIconButO(block, BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
+               }
+               else {
+                       but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+                       uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE));
+               }
+       }
+       
        uiBlockEndAlign(block);
 }
 
-void uiTemplateHeaderID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop)
+void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *unlinkop)
 {
-       TemplateHeaderID *template;
+       TemplateID *template;
        uiBlock *block;
        PropertyRNA *prop;
+       StructRNA *type;
+       int flag;
 
        if(!ptr->data)
                return;
 
        prop= RNA_struct_find_property(ptr, propname);
 
-       if(!prop) {
-               printf("uiTemplateHeaderID: property not found: %s\n", propname);
+       if(!prop || RNA_property_type(prop) != PROP_POINTER) {
+               printf("uiTemplateID: pointer property not found: %s\n", propname);
                return;
        }
 
-       template= MEM_callocN(sizeof(TemplateHeaderID), "TemplateHeaderID");
+       template= MEM_callocN(sizeof(TemplateID), "TemplateID");
        template->ptr= *ptr;
        template->prop= prop;
-       template->flag= UI_ID_BROWSE|UI_ID_RENAME;
 
-       if(newop) {
-               template->flag |= UI_ID_ADD_NEW;
-               BLI_strncpy(template->newop, newop, sizeof(template->newop));
-       }
-       if(openop) {
-               template->flag |= UI_ID_OPEN;
-               BLI_strncpy(template->openop, openop, sizeof(template->openop));
-       }
-       if(unlinkop) {
-               template->flag |= UI_ID_DELETE;
-               BLI_strncpy(template->unlinkop, unlinkop, sizeof(template->unlinkop));
-       }
+       flag= UI_ID_BROWSE|UI_ID_RENAME|UI_ID_DELETE;
 
-       block= uiLayoutFreeBlock(layout);
-       template_header_ID(C, block, template);
+       if(newop)
+               flag |= UI_ID_ADD_NEW;
+
+       type= RNA_property_pointer_type(ptr, prop);
+       template->idlb= wich_libbase(CTX_data_main(C), RNA_type_to_ID_code(type));
+
+       if(template->idlb) {
+               uiLayoutRow(layout, 1);
+               block= uiLayoutGetBlock(layout);
+               template_ID(C, block, template, type, flag, newop, unlinkop);
+       }
 
        MEM_freeN(template);
 }
@@ -263,125 +326,6 @@ void uiTemplateHeaderID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
 
 #include "ED_object.h"
 
-static void modifiers_del(bContext *C, void *ob_v, void *md_v)
-{
-       Scene *scene= CTX_data_scene(C);
-       Object *ob= ob_v;
-       ReportList reports;
-
-       BKE_reports_init(&reports, RPT_STORE);
-
-       if(ED_object_modifier_delete(&reports, ob_v, md_v)) {
-               WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
-               DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
-
-               ED_undo_push(C, "Delete modifier");
-       }
-       else
-               uiPupMenuReports(C, &reports);
-
-       BKE_reports_clear(&reports);
-}
-
-static void modifiers_moveUp(bContext *C, void *ob_v, void *md_v)
-{
-       Scene *scene= CTX_data_scene(C);
-       Object *ob= ob_v;
-       ReportList reports;
-
-       BKE_reports_init(&reports, RPT_STORE);
-
-       if(ED_object_modifier_move_up(&reports, ob_v, md_v)) {
-               WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
-               DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
-
-               ED_undo_push(C, "Move modifier");
-       }
-       else
-               uiPupMenuReports(C, &reports);
-
-       BKE_reports_clear(&reports);
-}
-
-static void modifiers_moveDown(bContext *C, void *ob_v, void *md_v)
-{
-       Scene *scene= CTX_data_scene(C);
-       Object *ob= ob_v;
-       ReportList reports;
-
-       BKE_reports_init(&reports, RPT_STORE);
-
-       if(ED_object_modifier_move_down(&reports, ob_v, md_v)) {
-               WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
-               DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
-
-               ED_undo_push(C, "Move modifier");
-       }
-       else
-               uiPupMenuReports(C, &reports);
-
-       BKE_reports_clear(&reports);
-}
-
-static void modifiers_convertParticles(bContext *C, void *obv, void *mdv)
-{
-       Scene *scene= CTX_data_scene(C);
-       Object *ob= obv;
-       ReportList reports;
-
-       BKE_reports_init(&reports, RPT_STORE);
-
-       if(ED_object_modifier_convert(&reports, scene, obv, mdv)) {
-               WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
-               DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
-
-               ED_undo_push(C, "Convert particles to mesh object(s).");
-       }
-       else
-               uiPupMenuReports(C, &reports);
-
-       BKE_reports_clear(&reports);
-}
-
-static void modifiers_applyModifier(bContext *C, void *obv, void *mdv)
-{
-       Scene *scene= CTX_data_scene(C);
-       Object *ob= obv;
-       ReportList reports;
-
-       BKE_reports_init(&reports, RPT_STORE);
-
-       if(ED_object_modifier_apply(&reports, scene, obv, mdv)) {
-               WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
-               DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
-
-               ED_undo_push(C, "Apply modifier");
-       }
-       else
-               uiPupMenuReports(C, &reports);
-
-       BKE_reports_clear(&reports);
-}
-
-static void modifiers_copyModifier(bContext *C, void *ob_v, void *md_v)
-{
-       Scene *scene= CTX_data_scene(C);
-       Object *ob= ob_v;
-       ReportList reports;
-
-       BKE_reports_init(&reports, RPT_STORE);
-
-       if(ED_object_modifier_copy(&reports, ob_v, md_v)) {
-               WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
-               DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
-               ED_undo_push(C, "Copy modifier");
-       }
-       else
-               uiPupMenuReports(C, &reports);
-
-       BKE_reports_clear(&reports);
-}
-
 static void modifiers_setOnCage(bContext *C, void *ob_v, void *md_v)
 {
        Scene *scene= CTX_data_scene(C);
@@ -424,15 +368,7 @@ static void modifiers_convertToReal(bContext *C, void *ob_v, void *md_v)
 
 static int modifier_can_delete(ModifierData *md)
 {
-       // deletion over the deflection panel
        // fluid particle modifier can't be deleted here
-
-       if(md->type==eModifierType_Fluidsim)
-               return 0;
-       if(md->type==eModifierType_Collision)
-               return 0;
-       if(md->type==eModifierType_Surface)
-               return 0;
        if(md->type == eModifierType_ParticleSystem)
                if(((ParticleSystemModifierData *)md)->psys->part->type == PART_FLUID)
                        return 0;
@@ -446,12 +382,12 @@ static uiLayout *draw_modifier(uiLayout *layout, Object *ob, ModifierData *md, i
        PointerRNA ptr;
        uiBut *but;
        uiBlock *block;
-       uiLayout *column, *row, *subrow, *result= NULL;
-       int isVirtual = md->mode&eModifierMode_Virtual;
+       uiLayout *column, *row, *result= NULL;
+       int isVirtual = md->mode & eModifierMode_Virtual;
        // XXX short color = md->error?TH_REDALERT:TH_BUT_NEUTRAL;
-       short width = 295, buttonWidth = width-120-10;
        char str[128];
 
+       /* create RNA pointer */
        RNA_pointer_create(&ob->id, &RNA_Modifier, md, &ptr);
 
        column= uiLayoutColumn(layout, 1);
@@ -462,126 +398,111 @@ static uiLayout *draw_modifier(uiLayout *layout, Object *ob, ModifierData *md, i
                /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
 
        row= uiLayoutRow(uiLayoutBox(column), 0);
-       block= uiLayoutGetBlock(row);
+       uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_EXPAND);
 
-       subrow= uiLayoutRow(row, 0);
-       uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_LEFT);
+       block= uiLayoutGetBlock(row);
 
        //uiDefBut(block, ROUNDBOX, 0, "", x-10, y-4, width, 25, NULL, 7.0, 0.0, 
-       //               (!isVirtual && (md->mode&eModifierMode_Expanded))?3:15, 20, ""); 
+       //               (!isVirtual && (md->mode & eModifierMode_Expanded))?3:15, 20, ""); 
        /* XXX uiBlockSetCol(block, TH_AUTO); */
        
        /* open/close icon */
-       if (!isVirtual) {
+       if(!isVirtual) {
                uiBlockSetEmboss(block, UI_EMBOSSN);
                uiDefIconButBitI(block, ICONTOG, eModifierMode_Expanded, 0, ICON_TRIA_RIGHT, 0, 0, UI_UNIT_X, UI_UNIT_Y, &md->mode, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Modifier");
        }
-
+       
+       /* modifier-type icon */
+       uiItemL(row, "", RNA_struct_ui_icon(ptr.type));
+       
        uiBlockSetEmboss(block, UI_EMBOSS);
        
-       if (isVirtual) {
+       if(isVirtual) {
+               /* virtual modifier */
                sprintf(str, "%s parent deform", md->name);
                uiDefBut(block, LABEL, 0, str, 0, 0, 185, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Modifier name"); 
 
                but = uiDefBut(block, BUT, 0, "Make Real", 0, 0, 80, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Convert virtual modifier to a real modifier");
                uiButSetFunc(but, modifiers_convertToReal, ob, md);
-       } else {
+       }
+       else {
+               /* real modifier */
                uiBlockBeginAlign(block);
-               uiDefBut(block, TEX, 0, "", 0, 0, buttonWidth-60, UI_UNIT_Y, md->name, 0.0, sizeof(md->name)-1, 0.0, 0.0, "Modifier name"); 
+               uiItemR(row, "", 0, &ptr, "name", 0, 0, 0);
 
                /* Softbody not allowed in this situation, enforce! */
-               if (((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) && (md->type!=eModifierType_Surface)) {
-                       uiDefIconButBitI(block, TOG, eModifierMode_Render, 0, ICON_SCENE, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
-                       but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, 0, ICON_VIEW3D, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
-                       if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
-                               uiDefIconButBitI(block, TOG, eModifierMode_Editmode, 0, ICON_EDITMODE_HLT, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode (only if enabled for display)");
-                       }
+               if(((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) && (md->type!=eModifierType_Surface)) {
+                       uiItemR(row, "", ICON_SCENE, &ptr, "render", 0, 0, 0);
+                       uiItemR(row, "", ICON_RESTRICT_VIEW_OFF, &ptr, "realtime", 0, 0, 0);
+
+                       if(mti->flags & eModifierTypeFlag_SupportsEditmode)
+                               uiItemR(row, "", ICON_EDITMODE_HLT, &ptr, "editmode", 0, 0, 0);
                }
-               uiBlockEndAlign(block);
+               
 
                /* XXX uiBlockSetEmboss(block, UI_EMBOSSR); */
 
-               if (ob->type==OB_MESH && modifier_couldBeCage(md) && index<=lastCageIndex) {
-                       int icon; //, color;
-
-                       if (index==cageIndex) {
-                               // XXX color = TH_BUT_SETTING;
-                               icon = VICON_EDITMODE_HLT;
-                       } else if (index<cageIndex) {
-                               // XXX color = TH_BUT_NEUTRAL;
-                               icon = VICON_EDITMODE_DEHLT;
-                       } else {
-                               // XXX color = TH_BUT_NEUTRAL;
-                               icon = ICON_BLANK1;
-                       }
+               if(ob->type==OB_MESH && modifier_couldBeCage(md) && index<=lastCageIndex) {
+
                        /* XXX uiBlockSetCol(block, color); */
-                       but = uiDefIconBut(block, BUT, 0, icon, 0, 0, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Apply modifier to editing cage during Editmode");
+                       but = uiDefIconBut(block, BUT, 0, ICON_MESH_DATA, 0, 0, 16, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Apply modifier to editing cage during Editmode");
                        uiButSetFunc(but, modifiers_setOnCage, ob, md);
+                       uiBlockEndAlign(block);
                        /* XXX uiBlockSetCol(block, TH_AUTO); */
                }
        }
 
-       subrow= uiLayoutRow(row, 0);
-       uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_RIGHT);
-
+       /* up/down/delete */
        if(!isVirtual) {
                /* XXX uiBlockSetCol(block, TH_BUT_ACTION); */
-
-               but = uiDefIconBut(block, BUT, 0, VICON_MOVE_UP, 0, 0, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Move modifier up in stack");
-               uiButSetFunc(but, modifiers_moveUp, ob, md);
-
-               but = uiDefIconBut(block, BUT, 0, VICON_MOVE_DOWN, 0, 0, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Move modifier down in stack");
-               uiButSetFunc(but, modifiers_moveDown, ob, md);
+               uiBlockBeginAlign(block);
+               uiItemO(row, "", VICON_MOVE_UP, "OBJECT_OT_modifier_move_up");
+               uiItemO(row, "", VICON_MOVE_DOWN, "OBJECT_OT_modifier_move_down");
+               uiBlockEndAlign(block);
                
                uiBlockSetEmboss(block, UI_EMBOSSN);
-               
-               if(modifier_can_delete(md)) {
-                       but = uiDefIconBut(block, BUT, 0, VICON_X, 0, 0, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Delete modifier");
-                       uiButSetFunc(but, modifiers_del, ob, md);
-               }
+
+               if(modifier_can_delete(md))
+                       uiItemO(row, "", VICON_X, "OBJECT_OT_modifier_remove");
+
                /* XXX uiBlockSetCol(block, TH_AUTO); */
        }
 
        uiBlockSetEmboss(block, UI_EMBOSS);
 
-       if(!isVirtual && (md->mode&eModifierMode_Expanded)) {
+       if(!isVirtual && (md->mode & eModifierMode_Expanded)) {
+               /* apply/convert/copy */
                uiLayout *box;
 
                box= uiLayoutBox(column);
                row= uiLayoutRow(box, 1);
 
-               if (!isVirtual && (md->type!=eModifierType_Collision) && (md->type!=eModifierType_Surface)) {
-                       uiBlockSetButLock(block, object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); /* only here obdata, the rest of modifiers is ob level */
+               if(!isVirtual && (md->type!=eModifierType_Collision) && (md->type!=eModifierType_Surface)) {
+                       /* only here obdata, the rest of modifiers is ob level */
+                       uiBlockSetButLock(block, object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
 
-                                               if (md->type==eModifierType_ParticleSystem) {
+                       if(md->type==eModifierType_ParticleSystem) {
                        ParticleSystem *psys= ((ParticleSystemModifierData *)md)->psys;
 
-                       if(!(G.f & G_PARTICLEEDIT)) {
-                                       if(ELEM3(psys->part->draw_as, PART_DRAW_PATH, PART_DRAW_GR, PART_DRAW_OB) && psys->pathcache) {
-                                               but = uiDefBut(block, BUT, 0, "Convert",        0,0,60,19, 0, 0, 0, 0, 0, "Convert the current particles to a mesh object");
-                                               uiButSetFunc(but, modifiers_convertParticles, ob, md);
-                                       }
-                               }
-                       }
-                       else{
-                               but = uiDefBut(block, BUT, 0, "Apply",  0,0,60,19, 0, 0, 0, 0, 0, "Apply the current modifier and remove from the stack");
-                               uiButSetFunc(but, modifiers_applyModifier, ob, md);
+                       if(!(ob->mode & OB_MODE_PARTICLE_EDIT))
+                                       if(ELEM3(psys->part->ren_as, PART_DRAW_PATH, PART_DRAW_GR, PART_DRAW_OB) && psys->pathcache)
+                                               uiItemO(row, "Convert", 0, "OBJECT_OT_modifier_convert");
                        }
+                       else
+                               uiItemO(row, "Apply", 0, "OBJECT_OT_modifier_apply");
                        
                        uiBlockClearButLock(block);
                        uiBlockSetButLock(block, ob && ob->id.lib, ERROR_LIBDATA_MESSAGE);
 
-                       if (md->type!=eModifierType_Fluidsim && md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem && (md->type!=eModifierType_Cloth)) {
-                               but = uiDefBut(block, BUT, 0, "Copy",   0,0,60,19, 0, 0, 0, 0, 0, "Duplicate the current modifier at the same position in the stack");
-                               uiButSetFunc(but, modifiers_copyModifier, ob, md);
-                       }
+                       if(!ELEM4(md->type, eModifierType_Fluidsim, eModifierType_Softbody, eModifierType_ParticleSystem, eModifierType_Cloth))
+                               uiItemO(row, "Copy", 0, "OBJECT_OT_modifier_copy");
                }
 
                result= uiLayoutColumn(box, 0);
                block= uiLayoutFreeBlock(box);
        }
 
-       if (md->error) {
+       if(md->error) {
                row = uiLayoutRow(uiLayoutBox(column), 0);
 
                /* XXX uiBlockSetCol(block, color); */
@@ -623,7 +544,7 @@ uiLayout *uiTemplateModifier(uiLayout *layout, PointerRNA *ptr)
        for(i=0; vmd; i++, vmd=vmd->next) {
                if(md == vmd)
                        return draw_modifier(layout, ob, md, i, cageIndex, lastCageIndex);
-               else if(vmd->mode&eModifierMode_Virtual)
+               else if(vmd->mode & eModifierMode_Virtual)
                        i--;
        }
 
@@ -689,12 +610,6 @@ static void constraint_active_func(bContext *C, void *ob_v, void *con_v)
        ED_object_constraint_set_active(ob_v, con_v);
 }
 
-static void del_constraint_func (bContext *C, void *ob_v, void *con_v)
-{
-       if(ED_object_constraint_delete(NULL, ob_v, con_v))
-               ED_undo_push(C, "Delete Constraint");
-}
-
 static void verify_constraint_name_func (bContext *C, void *con_v, void *name_v)
 {
        Object *ob= CTX_data_active_object(C);
@@ -712,21 +627,9 @@ static void verify_constraint_name_func (bContext *C, void *con_v, void *name_v)
        // XXX allqueue(REDRAWACTION, 0); 
 }
 
-static void constraint_moveUp(bContext *C, void *ob_v, void *con_v)
-{
-       if(ED_object_constraint_move_up(NULL, ob_v, con_v))
-               ED_undo_push(C, "Move Constraint");
-}
-
-static void constraint_moveDown(bContext *C, void *ob_v, void *con_v)
-{
-       if(ED_object_constraint_move_down(NULL, ob_v, con_v))
-               ED_undo_push(C, "Move Constraint");
-}
-
 /* some commonly used macros in the constraints drawing code */
 #define is_armature_target(target) (target && target->type==OB_ARMATURE)
-#define is_armature_owner(ob) ((ob->type == OB_ARMATURE) && (ob->flag & OB_POSEMODE))
+#define is_armature_owner(ob) ((ob->type == OB_ARMATURE) && (ob->mode & OB_MODE_POSE))
 #define is_geom_target(target) (target && (ELEM(target->type, OB_MESH, OB_LATTICE)) )
 
 /* Helper function for draw constraint - draws constraint space stuff 
@@ -830,7 +733,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
        box= uiLayoutBox(col);
        row= uiLayoutRow(box, 0);
 
-       block= uiLayoutFreeBlock(box);
+       block= uiLayoutGetBlock(box);
 
        subrow= uiLayoutRow(row, 0);
        uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_LEFT);
@@ -845,27 +748,19 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
        uiDefIconButBitS(block, ICONTOG, CONSTRAINT_EXPAND, B_CONSTRAINT_TEST, ICON_TRIA_RIGHT, xco-10, yco, 20, 20, &con->flag, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Constraint");
        
        /* name */      
-       if ((con->flag & CONSTRAINT_EXPAND) && (proxy_protected==0)) {
-               /* XXX if (con->flag & CONSTRAINT_DISABLE)
-                       uiBlockSetCol(block, TH_REDALERT);*/
-               
-               uiBlockSetEmboss(block, UI_EMBOSS);
-               
-               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, xco+10, yco, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
-               
+       uiBlockSetEmboss(block, UI_EMBOSS);
+       
+       /* XXX if (con->flag & CONSTRAINT_DISABLE)
+               uiBlockSetCol(block, TH_REDALERT);*/
+       
+       uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, xco+10, yco, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
+       
+       if(proxy_protected == 0) {
                but = uiDefBut(block, TEX, B_CONSTRAINT_TEST, "", xco+120, yco, 85, 18, con->name, 0.0, 29.0, 0.0, 0.0, "Constraint name"); 
-               uiButSetFunc(but, verify_constraint_name_func, con, NULL);
-       }       
-       else {
-               uiBlockSetEmboss(block, UI_EMBOSSN);
-               
-               /* XXX if (con->flag & CONSTRAINT_DISABLE)
-                       uiBlockSetCol(block, TH_REDALERT);*/
-               
-               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, xco+10, yco, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
-               
-               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, con->name, xco+120, yco-1, 135, 19, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
+               uiButSetFunc(but, verify_constraint_name_func, con, con->name);
        }
+       else
+               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, con->name, xco+120, yco-1, 135, 19, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
        // XXX uiBlockSetCol(block, TH_AUTO);   
 
@@ -909,25 +804,18 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
                        uiBlockBeginAlign(block);
                                uiBlockSetEmboss(block, UI_EMBOSS);
                                
-                               if (show_upbut) {
-                                       but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_UP, xco+width-50, yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint up in constraint stack");
-                                       uiButSetFunc(but, constraint_moveUp, ob, con);
-                               }
+                               if (show_upbut)
+                                       uiDefIconButO(block, BUT, "CONSTRAINT_OT_move_up", WM_OP_INVOKE_DEFAULT, VICON_MOVE_UP, xco+width-50, yco, 16, 18, "Move constraint up in constraint stack");
                                
-                               if (show_downbut) {
-                                       but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, xco+width-50+18, yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint down in constraint stack");
-                                       uiButSetFunc(but, constraint_moveDown, ob, con);
-                               }
+                               if (show_downbut)
+                                       uiDefIconButO(block, BUT, "CONSTRAINT_OT_move_down", WM_OP_INVOKE_DEFAULT, VICON_MOVE_DOWN, xco+width-50+18, yco, 16, 18, "Move constraint down in constraint stack");
                        uiBlockEndAlign(block);
                }
                
                
                /* Close 'button' - emboss calls here disable drawing of 'button' behind X */
                uiBlockSetEmboss(block, UI_EMBOSSN);
-               
-               but = uiDefIconBut(block, BUT, B_CONSTRAINT_CHANGETARGET, ICON_X, xco+262, yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete constraint");
-               uiButSetFunc(but, del_constraint_func, ob, con);
-               
+                       uiDefIconButO(block, BUT, "CONSTRAINT_OT_delete", WM_OP_INVOKE_DEFAULT, ICON_X, xco+262, yco, 19, 19, "Delete constraint");
                uiBlockSetEmboss(block, UI_EMBOSS);
        }
        
@@ -1024,95 +912,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
                                draw_constraint_spaceselect(block, con, xco, yco-(73+theight), is_armature_owner(ob), -1);
                        }
                        break;
-#endif /* DISABLE_PYTHON */
-               /*case CONSTRAINT_TYPE_CHILDOF:
-                       {
-                               // Inverse options 
-                               uiBlockBeginAlign(block);
-                                       but=uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Set Offset", xco, yco-151, (width/2),18, NULL, 0, 24, 0, 0, "Calculate current Parent-Inverse Matrix (i.e. restore offset from parent)");
-                                       // XXX uiButSetFunc(but, childof_const_setinv, con, NULL);
-                                       
-                                       but=uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Clear Offset", xco+((width/2)+10), yco-151, (width/2),18, NULL, 0, 24, 0, 0, "Clear Parent-Inverse Matrix (i.e. clear offset from parent)");
-                                       // XXX uiButSetFunc(but, childof_const_clearinv, con, NULL);
-                               uiBlockEndAlign(block);
-                       }
-                       break; 
-               */
-               
-               /*case CONSTRAINT_TYPE_RIGIDBODYJOINT:
-                       {
-                               if (data->type==CONSTRAINT_RB_GENERIC6DOF) {
-                                       // Draw Pairs of LimitToggle+LimitValue 
-                                       uiBlockBeginAlign(block); 
-                                               uiDefButBitS(block, TOG, 1, B_CONSTRAINT_TEST, "LinMinX", xco, yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x limit"); 
-                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", xco+togButWidth, yco-offsetY, (textButWidth-5), 18, &(data->minLimit[0]), -extremeLin, extremeLin, 0.1,0.5,"min x limit"); 
-                                       uiBlockEndAlign(block);
-                                       
-                                       uiBlockBeginAlign(block); 
-                                               uiDefButBitS(block, TOG, 1, B_CONSTRAINT_TEST, "LinMaxX", xco+(width-(textButWidth-5)-togButWidth), yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum x limit"); 
-                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", xco+(width-textButWidth-5), yco-offsetY, (textButWidth), 18, &(data->maxLimit[0]), -extremeLin, extremeLin, 0.1,0.5,"max x limit"); 
-                                       uiBlockEndAlign(block);
-                                       
-                                       offsetY += 20;
-                                       uiBlockBeginAlign(block); 
-                                               uiDefButBitS(block, TOG, 2, B_CONSTRAINT_TEST, "LinMinY", xco, yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y limit"); 
-                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", xco+togButWidth, yco-offsetY, (textButWidth-5), 18, &(data->minLimit[1]), -extremeLin, extremeLin, 0.1,0.5,"min y limit"); 
-                                       uiBlockEndAlign(block);
-                                       
-                                       uiBlockBeginAlign(block); 
-                                               uiDefButBitS(block, TOG, 2, B_CONSTRAINT_TEST, "LinMaxY", xco+(width-(textButWidth-5)-togButWidth), yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum y limit"); 
-                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", xco+(width-textButWidth-5), yco-offsetY, (textButWidth), 18, &(data->maxLimit[1]), -extremeLin, extremeLin, 0.1,0.5,"max y limit"); 
-                                       uiBlockEndAlign(block);
-                                       
-                                       offsetY += 20;
-                                       uiBlockBeginAlign(block); 
-                                               uiDefButBitS(block, TOG, 4, B_CONSTRAINT_TEST, "LinMinZ", xco, yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z limit"); 
-                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", xco+togButWidth, yco-offsetY, (textButWidth-5), 18, &(data->minLimit[2]), -extremeLin, extremeLin, 0.1,0.5,"min z limit"); 
-                                       uiBlockEndAlign(block);
-                                       
-                                       uiBlockBeginAlign(block); 
-                                               uiDefButBitS(block, TOG, 4, B_CONSTRAINT_TEST, "LinMaxZ", xco+(width-(textButWidth-5)-togButWidth), yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum z limit"); 
-                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", xco+(width-textButWidth-5), yco-offsetY, (textButWidth), 18, &(data->maxLimit[2]), -extremeLin, extremeLin, 0.1,0.5,"max z limit"); 
-                                       uiBlockEndAlign(block);
-                                       offsetY += 20;
-                               }
-                               if ((data->type==CONSTRAINT_RB_GENERIC6DOF) || (data->type==CONSTRAINT_RB_CONETWIST)) {
-                                       // Draw Pairs of LimitToggle+LimitValue /
-                                       uiBlockBeginAlign(block); 
-                                               uiDefButBitS(block, TOG, 8, B_CONSTRAINT_TEST, "AngMinX", xco, yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x limit"); 
-                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", xco+togButWidth, yco-offsetY, (textButWidth-5), 18, &(data->minLimit[3]), -extremeAngX, extremeAngX, 0.1,0.5,"min x limit"); 
-                                       uiBlockEndAlign(block);
-                                       uiBlockBeginAlign(block); 
-                                               uiDefButBitS(block, TOG, 8, B_CONSTRAINT_TEST, "AngMaxX", xco+(width-(textButWidth-5)-togButWidth), yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum x limit"); 
-                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", xco+(width-textButWidth-5), yco-offsetY, (textButWidth), 18, &(data->maxLimit[3]), -extremeAngX, extremeAngX, 0.1,0.5,"max x limit"); 
-                                       uiBlockEndAlign(block);
-                                       
-                                       offsetY += 20;
-                                       uiBlockBeginAlign(block); 
-                                               uiDefButBitS(block, TOG, 16, B_CONSTRAINT_TEST, "AngMinY", xco, yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y limit"); 
-                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", xco+togButWidth, yco-offsetY, (textButWidth-5), 18, &(data->minLimit[4]), -extremeAngY, extremeAngY, 0.1,0.5,"min y limit"); 
-                                       uiBlockEndAlign(block);
-                                       
-                                       uiBlockBeginAlign(block); 
-                                               uiDefButBitS(block, TOG, 16, B_CONSTRAINT_TEST, "AngMaxY", xco+(width-(textButWidth-5)-togButWidth), yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum y limit"); 
-                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", xco+(width-textButWidth-5), yco-offsetY, (textButWidth), 18, &(data->maxLimit[4]), -extremeAngY, extremeAngY, 0.1,0.5,"max y limit"); 
-                                       uiBlockEndAlign(block);
-                                       
-                                       offsetY += 20;
-                                       uiBlockBeginAlign(block); 
-                                               uiDefButBitS(block, TOG, 32, B_CONSTRAINT_TEST, "AngMinZ", xco, yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z limit"); 
-                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", xco+togButWidth, yco-offsetY, (textButWidth-5), 18, &(data->minLimit[5]), -extremeAngZ, extremeAngZ, 0.1,0.5,"min z limit"); 
-                                       uiBlockEndAlign(block);
-                                       
-                                       uiBlockBeginAlign(block); 
-                                               uiDefButBitS(block, TOG, 32, B_CONSTRAINT_TEST, "AngMaxZ", xco+(width-(textButWidth-5)-togButWidth), yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum z limit"); 
-                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", xco+(width-textButWidth-5), yco-offsetY, (textButWidth), 18, &(data->maxLimit[5]), -extremeAngZ, extremeAngZ, 0.1,0.5,"max z limit"); 
-                                       uiBlockEndAlign(block);
-                               }
-                               
-                       }
-                       break;
-                       */
+#endif 
 
                case CONSTRAINT_TYPE_NULL:
                        {
@@ -1273,42 +1073,94 @@ uiLayout *uiTemplateGroup(uiLayout *layout, Object *ob, Group *group)
 
 /************************* Preview Template ***************************/
 
+#include "DNA_lamp_types.h"
 #include "DNA_material_types.h"
+#include "DNA_world_types.h"
 
 #define B_MATPRV 1
 
-void uiTemplatePreview(uiLayout *layout, ID *id)
+static void do_preview_buttons(bContext *C, void *arg, int event)
+{
+       switch(event) {
+               case B_MATPRV:
+                       WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING, arg);
+                       break;
+       }
+}
+
+void uiTemplatePreview(uiLayout *layout, ID *id, ID *parent, MTex *slot)
 {
        uiLayout *row, *col;
        uiBlock *block;
-       Material *ma;
+       Material *ma= NULL;
+       ID *pid, *pparent;
+       short *pr_texture= NULL;
 
-       if(!id || !ELEM3(GS(id->name), ID_MA, ID_TE, ID_WO)) {
-               printf("uiTemplatePreview: expected ID of type material, texture or world.\n");
+       if(id && !ELEM4(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA)) {
+               printf("uiTemplatePreview: expected ID of type material, texture, lamp or world.\n");
                return;
        }
 
-       block= uiLayoutGetBlock(layout);
+       /* decide what to render */
+       pid= id;
+       pparent= NULL;
+
+       if(id && (GS(id->name) == ID_TE)) {
+               if(parent && (GS(parent->name) == ID_MA))
+                       pr_texture= &((Material*)parent)->pr_texture;
+               else if(parent && (GS(parent->name) == ID_WO))
+                       pr_texture= &((World*)parent)->pr_texture;
+               else if(parent && (GS(parent->name) == ID_LA))
+                       pr_texture= &((Lamp*)parent)->pr_texture;
+
+               if(pr_texture) {
+                       if(*pr_texture == TEX_PR_OTHER)
+                               pid= parent;
+                       else if(*pr_texture == TEX_PR_BOTH)
+                               pparent= parent;
+               }
+       }
 
+       /* layout */
+       block= uiLayoutGetBlock(layout);
        row= uiLayoutRow(layout, 0);
-
        col= uiLayoutColumn(row, 0);
        uiLayoutSetKeepAspect(col, 1);
-       uiDefBut(block, ROUNDBOX, 0, "", 0, 0, UI_UNIT_X*6, UI_UNIT_Y*6, NULL, 0.0, 0.0, 0, 0, "");
-
-       if(GS(id->name) == ID_MA) {
-               ma= (Material*)id;
-
-               uiLayoutColumn(row, 1);
+       
+       /* add preview */
+       uiDefBut(block, BUT_EXTRA, 0, "", 0, 0, UI_UNIT_X*6, UI_UNIT_Y*6, pid, 0.0, 0.0, 0, 0, "");
+       uiBlockSetDrawExtraFunc(block, ED_preview_draw, pparent, slot);
+       uiBlockSetHandleFunc(block, do_preview_buttons, NULL);
+       
+       /* add buttons */
+       if(pid) {
+               if(GS(pid->name) == ID_MA || (pparent && GS(pparent->name) == ID_MA)) {
+                       if(GS(pid->name) == ID_MA) ma= (Material*)pid;
+                       else ma= (Material*)pparent;
+
+                       uiLayoutColumn(row, 1);
+
+                       uiDefIconButC(block, ROW, B_MATPRV, ICON_MATPLANE,  0, 0,UI_UNIT_X*1.5,UI_UNIT_Y, &(ma->pr_type), 10, MA_FLAT, 0, 0, "Preview type: Flat XY plane");
+                       uiDefIconButC(block, ROW, B_MATPRV, ICON_MATSPHERE, 0, 0,UI_UNIT_X*1.5,UI_UNIT_Y, &(ma->pr_type), 10, MA_SPHERE, 0, 0, "Preview type: Sphere");
+                       uiDefIconButC(block, ROW, B_MATPRV, ICON_MATCUBE,   0, 0,UI_UNIT_X*1.5,UI_UNIT_Y, &(ma->pr_type), 10, MA_CUBE, 0, 0, "Preview type: Cube");
+                       uiDefIconButC(block, ROW, B_MATPRV, ICON_MONKEY,    0, 0,UI_UNIT_X*1.5,UI_UNIT_Y, &(ma->pr_type), 10, MA_MONKEY, 0, 0, "Preview type: Monkey");
+                       uiDefIconButC(block, ROW, B_MATPRV, ICON_HAIR,      0, 0,UI_UNIT_X*1.5,UI_UNIT_Y, &(ma->pr_type), 10, MA_HAIR, 0, 0, "Preview type: Hair strands");
+                       uiDefIconButC(block, ROW, B_MATPRV, ICON_MAT_SPHERE_SKY, 0, 0,UI_UNIT_X*1.5,UI_UNIT_Y, &(ma->pr_type), 10, MA_SPHERE_A, 0, 0, "Preview type: Large sphere with sky");
+               }
 
-               uiDefIconButC(block, ROW, B_MATPRV, ICON_MATPLANE,  0, 0,UI_UNIT_X,UI_UNIT_Y, &(ma->pr_type), 10, MA_FLAT, 0, 0, "Preview type: Flat XY plane");
-               uiDefIconButC(block, ROW, B_MATPRV, ICON_MATSPHERE, 0, 0,UI_UNIT_X,UI_UNIT_Y, &(ma->pr_type), 10, MA_SPHERE, 0, 0, "Preview type: Sphere");
-               uiDefIconButC(block, ROW, B_MATPRV, ICON_MATCUBE,   0, 0,UI_UNIT_X,UI_UNIT_Y, &(ma->pr_type), 10, MA_CUBE, 0, 0, "Preview type: Cube");
-               uiDefIconButC(block, ROW, B_MATPRV, ICON_MONKEY,    0, 0,UI_UNIT_X,UI_UNIT_Y, &(ma->pr_type), 10, MA_MONKEY, 0, 0, "Preview type: Monkey");
-               uiDefIconButC(block, ROW, B_MATPRV, ICON_HAIR,      0, 0,UI_UNIT_X,UI_UNIT_Y, &(ma->pr_type), 10, MA_HAIR, 0, 0, "Preview type: Hair strands");
-               uiDefIconButC(block, ROW, B_MATPRV, ICON_MATSPHERE, 0, 0,UI_UNIT_X,UI_UNIT_Y, &(ma->pr_type), 10, MA_SPHERE_A, 0, 0, "Preview type: Large sphere with sky");
+               if(pr_texture) {
+                       uiLayoutRow(layout, 1);
+
+                       uiDefButS(block, ROW, B_MATPRV, "Texture",  0, 0,UI_UNIT_X*10,UI_UNIT_Y, pr_texture, 10, TEX_PR_TEXTURE, 0, 0, "");
+                       if(GS(parent->name) == ID_MA)
+                               uiDefButS(block, ROW, B_MATPRV, "Material",  0, 0,UI_UNIT_X*10,UI_UNIT_Y, pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
+                       else if(GS(parent->name) == ID_LA)
+                               uiDefButS(block, ROW, B_MATPRV, "Lamp",  0, 0,UI_UNIT_X*10,UI_UNIT_Y, pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
+                       else if(GS(parent->name) == ID_WO)
+                               uiDefButS(block, ROW, B_MATPRV, "World",  0, 0,UI_UNIT_X*10,UI_UNIT_Y, pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
+                       uiDefButS(block, ROW, B_MATPRV, "Both",  0, 0,UI_UNIT_X*10,UI_UNIT_Y, pr_texture, 10, TEX_PR_BOTH, 0, 0, "");
+               }
        }
-
 }
 
 /********************** ColorRamp Template **************************/
@@ -1331,17 +1183,440 @@ void uiTemplateColorRamp(uiLayout *layout, ColorBand *coba, int expand)
 
 #include "DNA_color_types.h"
 
-void uiTemplateCurveMapping(uiLayout *layout, CurveMapping *cumap, int type)
+void uiTemplateCurveMapping(uiLayout *layout, CurveMapping *cumap, int type, int compact)
 {
-       uiBlock *block;
        rctf rect;
 
        if(cumap) {
-               rect.xmin= 0; rect.xmax= 200;
-               rect.ymin= 0; rect.ymax= 190;
+               if(compact) {
+                       rect.xmin= 0; rect.xmax= 150;
+                       rect.ymin= 0; rect.ymax= 140;
+               }
+               else {
+                       rect.xmin= 0; rect.xmax= 200;
+                       rect.ymin= 0; rect.ymax= 190;
+               }
                
+               curvemap_layout(layout, cumap, type, 0, 0, &rect);
+       }
+}
+
+/********************* TriColor (ThemeWireColorSet) Template ************************/
+
+void uiTemplateTriColorSet(uiLayout *layout, PointerRNA *ptr, char *propname)
+{
+       uiLayout *row;
+       PropertyRNA *prop;
+       PointerRNA csPtr;
+       
+       if (!ptr->data)
+               return;
+       
+       prop= RNA_struct_find_property(ptr, propname);
+       if (!prop) {
+               printf("uiTemplateTriColorSet: property not found: %s\n", propname);
+               return;
+       }
+       
+       /* we lay out the data in a row as 3 color swatches */
+       row= uiLayoutRow(layout, 1);
+       
+       /* nselected, selected, active color swatches */
+       csPtr= RNA_property_pointer_get(ptr, prop);
+       
+       uiItemR(row, "", 0, &csPtr, "normal", 0, 0, 0);
+       uiItemR(row, "", 0, &csPtr, "selected", 0, 0, 0);
+       uiItemR(row, "", 0, &csPtr, "active", 0, 0, 0);
+}
+
+/********************* Layer Buttons Template ************************/
+
+// TODO:
+//     - option for showing extra info like whether layer has contents?
+//     - for now, grouping of layers is determined by dividing up the length of 
+//       the array of layer bitflags
+
+void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, char *propname)
+{
+       uiLayout *uRow, *uSplit, *uCol;
+       PropertyRNA *prop;
+       int groups, cols, layers;
+       int group, col, layer, row;
+       
+       if (!ptr->data)
+               return;
+       
+       prop= RNA_struct_find_property(ptr, propname);
+       if (!prop) {
+               printf("uiTemplateLayer: layers property not found: %s\n", propname);
+               return;
+       }
+       
+       /* the number of layers determines the way we group them 
+        *      - we want 2 rows only (for now)
+        *      - the number of columns (cols) is the total number of buttons per row
+        *        the 'remainder' is added to this, as it will be ok to have first row slightly wider if need be
+        *      - for now, only split into groups if if group will have at least 5 items
+        */
+       layers= RNA_property_array_length(prop);
+       cols= (layers / 2) + (layers % 2);
+       groups= ((cols / 2) < 5) ? (1) : (cols / 2);
+       
+       /* layers are laid out going across rows, with the columns being divided into groups */
+       if (groups > 1)
+               uSplit= uiLayoutSplit(layout, (1.0f/(float)groups));
+       else    
+               uSplit= layout;
+       
+       for (group= 0; group < groups; group++) {
+               uCol= uiLayoutColumn(uSplit, 1);
+               
+               for (row= 0; row < 2; row++) {
+                       uRow= uiLayoutRow(uCol, 1);
+                       layer= groups*cols*row + cols*group;
+                       
+                       /* add layers as toggle buts */
+                       for (col= 0; (col < cols) && (layer < layers); col++, layer++) {
+                               int icon=0; // XXX - add some way of setting this...
+                               uiItemFullR(uRow, "", icon, ptr, prop, layer, 0, 0, 0, 1);
+                       }
+               }
+       }
+}
+
+
+/************************* List Template **************************/
+
+#if 0
+static void list_item_add(ListBase *lb, ListBase *itemlb, uiLayout *layout, PointerRNA *data)
+{
+       CollectionPointerLink *link;
+       uiListItem *item;
+
+       /* add to list to store in box */
+       item= MEM_callocN(sizeof(uiListItem), "uiListItem");
+       item->layout= layout;
+       item->data= *data;
+       BLI_addtail(itemlb, item);
+
+       /* add to list to return from function */
+       link= MEM_callocN(sizeof(CollectionPointerLink), "uiTemplateList return");
+       RNA_pointer_create(NULL, &RNA_UIListItem, item, &link->ptr);
+       BLI_addtail(lb, link);
+}
+#endif
+
+ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, PointerRNA *activeptr, char *activepropname, int rows, int listtype)
+{
+       //Scene *scene= CTX_data_scene(C);
+       PropertyRNA *prop= NULL, *activeprop;
+       PropertyType type, activetype;
+       StructRNA *ptype;
+       uiLayout *box, *row, *col, *subrow;
+       uiBlock *block;
+       uiBut *but;
+       Panel *pa;
+       ListBase lb, *itemlb;
+       char *name, str[32];
+       int icon=0, i= 0, activei= 0, len, items, found, min, max;
+
+       lb.first= lb.last= NULL;
+       
+       /* validate arguments */
+       block= uiLayoutGetBlock(layout);
+       pa= block->panel;
+
+       if(!pa) {
+               printf("uiTemplateList: only works inside a panel.\n");
+               return lb;
+       }
+
+       if(!activeptr->data)
+               return lb;
+       
+       if(ptr->data) {
+               prop= RNA_struct_find_property(ptr, propname);
+               if(!prop) {
+                       printf("uiTemplateList: property not found: %s\n", propname);
+                       return lb;
+               }
+       }
+
+       activeprop= RNA_struct_find_property(activeptr, activepropname);
+       if(!activeprop) {
+               printf("uiTemplateList: property not found: %s\n", activepropname);
+               return lb;
+       }
+
+       if(prop) {
+               type= RNA_property_type(prop);
+               if(type != PROP_COLLECTION) {
+                       printf("uiTemplateList: expected collection property.\n");
+                       return lb;
+               }
+       }
+
+       activetype= RNA_property_type(activeprop);
+       if(activetype != PROP_INT) {
+               printf("uiTemplateList: expected integer property.\n");
+               return lb;
+       }
+
+       /* get icon */
+       if(ptr->data && prop) {
+               ptype= RNA_property_pointer_type(ptr, prop);
+               icon= RNA_struct_ui_icon(ptype);
+       }
+
+       /* get active data */
+       activei= RNA_property_int_get(activeptr, activeprop);
+
+       if(listtype == 'i') {
+               box= uiLayoutListBox(layout);
+               col= uiLayoutColumn(box, 1);
+               row= uiLayoutRow(col, 0);
+
+               itemlb= uiLayoutBoxGetList(box);
+
+               if(ptr->data && prop) {
+                       /* create list items */
+                       RNA_PROP_BEGIN(ptr, itemptr, prop) {
+                               /* create button */
+                               if(i == 9)
+                                       row= uiLayoutRow(col, 0);
+
+                               if(RNA_struct_is_a(itemptr.type, &RNA_TextureSlot)) {
+#if 0
+                                       MTex *mtex= itemptr.data;
+
+                                       if(mtex && mtex->tex)
+                                               icon= ui_id_icon_get(scene, &mtex->tex->id);
+#endif
+                               }
+
+                               uiDefIconButR(block, LISTROW, 0, icon, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
+
+                               //list_item_add(&lb, itemlb, uiLayoutRow(row, 1), &itemptr);
+
+                               i++;
+                       }
+                       RNA_PROP_END;
+               }
+       }
+       else if(listtype == 'c') {
+               /* compact layout */
+               found= 0;
+
+               row= uiLayoutRow(layout, 1);
+
+               if(ptr->data && prop) {
+                       /* create list items */
+                       RNA_PROP_BEGIN(ptr, itemptr, prop) {
+                               found= (activei == i);
+
+                               if(found) {
+                                       /* create button */
+                                       name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+                                       uiItemL(row, (name)? name: "", icon);
+
+                                       if(name)
+                                               MEM_freeN(name);
+
+                                       /* add to list to return */
+                                       //list_item_add(&lb, itemlb, uiLayoutRow(row, 1), &itemptr);
+                               }
+
+                               i++;
+                       }
+                       RNA_PROP_END;
+               }
+
+               /* if not found, add in dummy button */
+               if(i == 0)
+                       uiItemL(row, "", 0);
+
+               /* next/prev button */
+               sprintf(str, "%d :", i);
+               but= uiDefIconTextButR(block, NUM, 0, 0, str, 0,0,UI_UNIT_X*5,UI_UNIT_Y, activeptr, activepropname, 0, 0, 0, 0, 0, "");
+               if(i == 0)
+                       uiButSetFlag(but, UI_BUT_DISABLED);
+       }
+       else {
+               /* default rows */
+               if(rows == 0)
+                       rows= 5;
+
+               /* layout */
+               box= uiLayoutListBox(layout);
+               row= uiLayoutRow(box, 0);
+               col = uiLayoutColumn(row, 1);
+
+               /* init numbers */
+               RNA_property_int_range(activeptr, activeprop, &min, &max);
+
+               if(prop)
+                       len= RNA_property_collection_length(ptr, prop);
+               items= CLAMPIS(len, rows, 5);
+
+               pa->list_scroll= MIN2(pa->list_scroll, len-items);
+               pa->list_scroll= MAX2(pa->list_scroll, 0);
+
+               itemlb= uiLayoutBoxGetList(box);
+
+               if(ptr->data && prop) {
+                       /* create list items */
+                       RNA_PROP_BEGIN(ptr, itemptr, prop) {
+                               if(i >= pa->list_scroll && i<pa->list_scroll+items) {
+                                       name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+
+                                       subrow= uiLayoutRow(col, 0);
+
+                                       /* create button */
+                                       if(!icon || icon == ICON_DOT)
+                                               but= uiDefButR(block, LISTROW, 0, (name)? name: "", 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
+                                       else
+                                               but= uiDefIconTextButR(block, LISTROW, 0, icon, (name)? name: "", 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
+                                       uiButSetFlag(but, UI_ICON_LEFT|UI_TEXT_LEFT);
+
+                                       /* XXX hardcoded */
+                                       if(itemptr.type == &RNA_MeshTextureFaceLayer || itemptr.type == &RNA_MeshColorLayer) {
+                                               uiBlockSetEmboss(block, UI_EMBOSSN);
+                                               uiDefIconButR(block, TOG, 0, ICON_SCENE, 0, 0, UI_UNIT_X, UI_UNIT_Y, &itemptr, "active_render", 0, 0, 0, 0, 0, NULL);
+                                               uiBlockSetEmboss(block, UI_EMBOSS);
+                                       }
+
+                                       if(name)
+                                               MEM_freeN(name);
+
+                                       /* add to list to return */
+                                       //list_item_add(&lb, itemlb, subrow, &itemptr);
+                               }
+
+                               i++;
+                       }
+                       RNA_PROP_END;
+               }
+
+               /* add dummy buttons to fill space */
+               while(i < pa->list_scroll+items) {
+                       if(i >= pa->list_scroll)
+                               uiItemL(col, "", 0);
+                       i++;
+               }
+
+               /* add scrollbar */
+               if(len > items) {
+                       col= uiLayoutColumn(row, 0);
+                       uiDefButI(block, SCROLL, 0, "", 0,0,UI_UNIT_X*0.75,UI_UNIT_Y*items, &pa->list_scroll, 0, len-items, items, 0, "");
+               }
+       }
+
+       /* return items in list */
+       return lb;
+}
+
+/************************* Operator Search Template **************************/
+
+static void operator_call_cb(struct bContext *C, void *arg1, void *arg2)
+{
+       wmOperatorType *ot= arg2;
+       
+       if(ot)
+               WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, NULL);
+}
+
+static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items)
+{
+       wmOperatorType *ot = WM_operatortype_first();
+       
+       for(; ot; ot= ot->next) {
+               
+               if(BLI_strcasestr(ot->name, str)) {
+                       if(ot->poll==NULL || ot->poll((bContext *)C)) {
+                               char name[256];
+                               int len= strlen(ot->name);
+                               
+                               /* display name for menu, can hold hotkey */
+                               BLI_strncpy(name, ot->name, 256);
+                               
+                               /* check for hotkey */
+                               if(len < 256-6) {
+                                       if(WM_key_event_operator_string(C, ot->idname, WM_OP_EXEC_DEFAULT, NULL, &name[len+1], 256-len-1))
+                                               name[len]= '|';
+                               }
+                               
+                               if(0==uiSearchItemAdd(items, name, ot, 0))
+                                       break;
+                       }
+               }
+       }
+}
+
+void uiTemplateOperatorSearch(uiLayout *layout)
+{
+       uiBlock *block;
+       uiBut *but;
+       static char search[256]= "";
+               
+       block= uiLayoutGetBlock(layout);
+       uiBlockSetCurLayout(block, layout);
+
+       but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 0, 0, UI_UNIT_X*6, UI_UNIT_Y, "");
+       uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL);
+}
+
+/************************* Running Jobs Template **************************/
+
+#define B_STOPRENDER   1
+#define B_STOPCAST             2
+#define B_STOPANIM             3
+
+static void do_running_jobs(bContext *C, void *arg, int event)
+{
+       switch(event) {
+               case B_STOPRENDER:
+                       G.afbreek= 1;
+                       break;
+               case B_STOPCAST:
+                       WM_jobs_stop(CTX_wm_manager(C), CTX_wm_screen(C));
+                       break;
+               case B_STOPANIM:
+                       WM_operator_name_call(C, "SCREEN_OT_animation_play", WM_OP_INVOKE_SCREEN, NULL);
+                       break;
+       }
+}
+
+void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
+{
+       bScreen *screen= CTX_wm_screen(C);
+       Scene *scene= CTX_data_scene(C);
+       wmWindowManager *wm= CTX_wm_manager(C);
+       uiBlock *block;
+
+       block= uiLayoutGetBlock(layout);
+       uiBlockSetCurLayout(block, layout);
+
+       uiBlockSetHandleFunc(block, do_running_jobs, NULL);
+
+       if(WM_jobs_test(wm, scene))
+               uiDefIconTextBut(block, BUT, B_STOPRENDER, ICON_REC, "Render", 0,0,75,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop rendering");
+       if(WM_jobs_test(wm, screen))
+               uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_REC, "Capture", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop screencast");
+       if(screen->animtimer)
+               uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_REC, "Anim Player", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback");
+}
+
+/************************* Image Template **************************/
+
+#include "ED_image.h"
+
+void uiTemplateTextureImage(uiLayout *layout, bContext *C, Tex *tex)
+{
+       uiBlock *block;
+
+       if(tex) {
                block= uiLayoutFreeBlock(layout);
-               curvemap_buttons(block, cumap, type, 0, 0, &rect);
+               ED_image_uiblock_panel(C, block, &tex->ima, &tex->iuser, 0, 0);
        }
 }