Changes to Brush texture workflow
authorMatt Ebb <matt@mke3.net>
Sun, 3 Jan 2010 08:37:18 +0000 (08:37 +0000)
committerMatt Ebb <matt@mke3.net>
Sun, 3 Jan 2010 08:37:18 +0000 (08:37 +0000)
This changes how textures are accessed from Brushes, with the intention of simplifying
the workflow, and reducing the amount of clicking. Rather than the previous texture slots
(which didn't work as a stack anyway), brushes now have a single texture linked. Rather
than taking time having to set up your slots in advance, you can now select and change
textures directly as you sculpt/paint on the fly. For complex brushes, node textures can
be used, or for fast access, it's easy to make a duplicate of your brush with the texture
you like and assign a hotkey.

Brush textures can now be chosen from a new Textures panel in the brush tool
properties - click on the thumbnail to open a texture selector. This is done using a new
variation on the ID template - the number of rows and columns to display in the popup
can be customised in the UI scripts.

25 files changed:
release/scripts/ui/properties_texture.py
release/scripts/ui/space_view3d_toolbar.py
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/texture.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/include/UI_interface.h
source/blender/editors/include/UI_interface_icons.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_icons.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/space_buttons/buttons_context.c
source/blender/editors/space_buttons/space_buttons.c
source/blender/editors/space_outliner/outliner.c
source/blender/editors/space_view3d/view3d_toolbar.c
source/blender/makesdna/DNA_brush_types.h
source/blender/makesrna/intern/rna_brush.c
source/blender/makesrna/intern/rna_ui_api.c
source/blender/windowmanager/intern/wm_operators.c

index 4471f6f..711ba4f 100644 (file)
@@ -87,13 +87,15 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel):
     def draw(self, context):
         layout = self.layout
 
+        space = context.space_data
         tex = context.texture
         wide_ui = context.region.width > narrowui
         idblock = context_tex_datablock(context)
+        tex_collection = space.pin_id == None and type(idblock) != bpy.types.Brush
 
-        space = context.space_data
+        
 
-        if idblock:
+        if tex_collection:
             row = layout.row()
 
             row.template_list(idblock, "textures", idblock, "active_texture_index", rows=2)
@@ -101,24 +103,31 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel):
             col = row.column(align=True)
             col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
             col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN'
-
-
+        
         if wide_ui:
             split = layout.split(percentage=0.65)
-            if idblock:
-                split.template_ID(idblock, "active_texture", new="texture.new")
-            elif tex:
-                split.template_ID(space, "pin_id")
+            col = split.column()
         else:
-            layout.template_ID(idblock, "active_texture", new="texture.new")
-
+            col = layout.column()
+            
+        if tex_collection:
+            col.template_ID(idblock, "active_texture", new="texture.new")
+        elif idblock:
+            col.template_ID(idblock, "texture", new="texture.new")
+        
+        if space.pin_id:
+            col.template_ID(space, "pin_id")
+        
+        if wide_ui:
+            col = split.column()
+        
         if (not space.pin_id) and (
             context.sculpt_object or
             context.vertex_paint_object or
             context.weight_paint_object or
             context.texture_paint_object):
 
-            split.prop(space, "brush_texture", text="Brush", toggle=True)
+            col.prop(space, "brush_texture", text="Brush", toggle=True)
 
         if tex:
             layout.prop(tex, "use_nodes")
@@ -268,6 +277,10 @@ class TEXTURE_PT_influence(TextureSlotPanel):
     bl_label = "Influence"
 
     def poll(self, context):
+        idblock = context_tex_datablock(context)
+        if type(idblock) == bpy.types.Brush:
+            return False
+    
         return context.texture_slot
 
     def draw(self, context):
index b2c8c39..3e745bb 100644 (file)
@@ -624,6 +624,29 @@ class VIEW3D_PT_tools_brush(PaintPanel):
             #row.prop(brush, "jitter", slider=True)
             #row.prop(brush, "use_jitter_pressure", toggle=True, text="")
 
+
+class VIEW3D_PT_tools_brush_texture(PaintPanel):
+    bl_label = "Texture"
+    bl_default_closed = True
+
+    def poll(self, context):
+        settings = self.paint_settings(context)
+        return (settings and settings.brush and (context.sculpt_object or
+                             context.texture_paint_object))
+
+    def draw(self, context):
+        layout = self.layout
+
+        settings = self.paint_settings(context)
+        brush = settings.brush
+        tex_slot = brush.texture_slot
+        
+        col = layout.column()
+        
+        col.template_ID_preview(brush, "texture", new="texture.new", rows=2, cols=4)
+        
+        col.row().prop(tex_slot, "map_mode", expand=True)
+        
 class VIEW3D_PT_tools_brush_tool(PaintPanel):
     bl_label = "Tool"
     bl_default_closed = True
@@ -975,6 +998,7 @@ bpy.types.register(VIEW3D_PT_tools_latticeedit)
 bpy.types.register(VIEW3D_PT_tools_posemode)
 bpy.types.register(VIEW3D_PT_tools_posemode_options)
 bpy.types.register(VIEW3D_PT_tools_brush)
+bpy.types.register(VIEW3D_PT_tools_brush_texture)
 bpy.types.register(VIEW3D_PT_tools_brush_tool)
 bpy.types.register(VIEW3D_PT_tools_brush_stroke)
 bpy.types.register(VIEW3D_PT_tools_brush_curve)
index 667b0d5..444c6d2 100644 (file)
@@ -100,19 +100,11 @@ Brush *add_brush(const char *name)
 Brush *copy_brush(Brush *brush)
 {
        Brush *brushn;
-       MTex *mtex;
-       int a;
        
        brushn= copy_libblock(brush);
 
-       for(a=0; a<MAX_MTEX; a++) {
-               mtex= brush->mtex[a];
-               if(mtex) {
-                       brushn->mtex[a]= MEM_dupallocN(mtex);
-                       if(mtex->tex) id_us_plus((ID*)mtex->tex);
-               }
-       }
-
+       if(brush->mtex.tex) id_us_plus((ID*)brush->mtex.tex);
+       
        brushn->curve= curvemapping_copy(brush->curve);
 
        /* enable fake user by default */
@@ -127,17 +119,8 @@ Brush *copy_brush(Brush *brush)
 /* not brush itself */
 void free_brush(Brush *brush)
 {
-       MTex *mtex;
-       int a;
-
-       for(a=0; a<MAX_MTEX; a++) {
-               mtex= brush->mtex[a];
-               if(mtex) {
-                       if(mtex->tex) mtex->tex->id.us--;
-                       MEM_freeN(mtex);
-               }
-       }
-
+       if(brush->mtex.tex) brush->mtex.tex->id.us--;
+       
        curvemapping_free(brush->curve);
 }
 
@@ -295,8 +278,8 @@ void brush_curve_preset(Brush *b, BrushCurvePreset preset)
 
 static MTex *brush_active_texture(Brush *brush)
 {
-       if(brush && brush->texact >= 0)
-               return brush->mtex[brush->texact];
+       if(brush)
+               return &brush->mtex;
        return NULL;
 }
 
@@ -304,8 +287,7 @@ int brush_texture_set_nr(Brush *brush, int nr)
 {
        ID *idtest, *id=NULL;
 
-       if(brush->mtex[brush->texact])
-               id= (ID *)brush->mtex[brush->texact]->tex;
+       id= (ID *)brush->mtex.tex;
 
        idtest= (ID*)BLI_findlink(&G.main->tex, nr-1);
        if(idtest==0) { /* new tex */
@@ -316,13 +298,7 @@ int brush_texture_set_nr(Brush *brush, int nr)
        if(idtest!=id) {
                brush_texture_delete(brush);
 
-               if(brush->mtex[brush->texact]==NULL) {
-                       brush->mtex[brush->texact]= add_mtex();
-                       brush->mtex[brush->texact]->r = 1.0f;
-                       brush->mtex[brush->texact]->g = 1.0f;
-                       brush->mtex[brush->texact]->b = 1.0f;
-               }
-               brush->mtex[brush->texact]->tex= (Tex*)idtest;
+               brush->mtex.tex= (Tex*)idtest;
                id_us_plus(idtest);
 
                return 1;
@@ -333,16 +309,10 @@ int brush_texture_set_nr(Brush *brush, int nr)
 
 int brush_texture_delete(Brush *brush)
 {
-       if(brush->mtex[brush->texact]) {
-               if(brush->mtex[brush->texact]->tex)
-                       brush->mtex[brush->texact]->tex->id.us--;
-               MEM_freeN(brush->mtex[brush->texact]);
-               brush->mtex[brush->texact]= NULL;
-
-               return 1;
-       }
+       if(brush->mtex.tex)
+               brush->mtex.tex->id.us--;
 
-       return 0;
+       return 1;
 }
 
 int brush_clone_image_set_nr(Brush *brush, int nr)
@@ -383,7 +353,7 @@ void brush_check_exists(Brush **brush, const char *name)
 /* Brush Sampling */
 void brush_sample_tex(Brush *brush, float *xy, float *rgba)
 {
-       MTex *mtex= brush->mtex[brush->texact];
+       MTex *mtex= &brush->mtex;
 
        if (mtex && mtex->tex) {
                float co[3], tin, tr, tg, tb, ta;
@@ -741,7 +711,7 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos)
 {
        Brush *brush= painter->brush;
        BrushPainterCache *cache= &painter->cache;
-       MTex *mtex= brush->mtex[brush->texact];
+       MTex *mtex= &brush->mtex;
        int size;
        short flt;
 
@@ -976,7 +946,7 @@ float brush_curve_strength(Brush *br, float p, const float len)
 unsigned int *brush_gen_texture_cache(Brush *br, int half_side)
 {
        unsigned int *texcache = NULL;
-       MTex *mtex = br->mtex[br->texact];
+       MTex *mtex = &br->mtex;
        TexResult texres;
        int hasrgb, ix, iy;
        int side = half_side * 2;
index 818e619..c60001d 100644 (file)
@@ -703,11 +703,9 @@ void make_local_texture(Tex *tex)
        }
        br= G.main->brush.first;
        while(br) {
-               for(a=0; a<MAX_MTEX; a++) {
-                       if(br->mtex[a] && br->mtex[a]->tex==tex) {
-                               if(br->id.lib) lib= 1;
-                               else local= 1;
-                       }
+               if(br->mtex.tex==tex) {
+                       if(br->id.lib) lib= 1;
+                       else local= 1;
                }
                br= br->id.next;
        }
@@ -762,13 +760,11 @@ void make_local_texture(Tex *tex)
                }
                br= G.main->brush.first;
                while(br) {
-                       for(a=0; a<MAX_MTEX; a++) {
-                               if(br->mtex[a] && br->mtex[a]->tex==tex) {
-                                       if(br->id.lib==0) {
-                                               br->mtex[a]->tex= texn;
-                                               texn->id.us++;
-                                               tex->id.us--;
-                                       }
+                       if(br->mtex.tex==tex) {
+                               if(br->id.lib==0) {
+                                       br->mtex.tex= texn;
+                                       texn->id.us++;
+                                       tex->id.us--;
                                }
                        }
                        br= br->id.next;
@@ -904,10 +900,6 @@ int give_active_mtex(ID *id, MTex ***mtex_ar, short *act)
                *mtex_ar=               ((Lamp *)id)->mtex;
                if(act) *act=   (((Lamp *)id)->texact);
                break;
-       case ID_BR:
-               *mtex_ar=               ((Brush *)id)->mtex;
-               if(act) *act=   (((Brush *)id)->texact);
-               break;
        default:
                *mtex_ar = NULL;
                if(act) *act=   0;
@@ -932,9 +924,6 @@ void set_active_mtex(ID *id, short act)
        case ID_LA:
                ((Lamp *)id)->texact= act;
                break;
-       case ID_BR:
-               ((Brush *)id)->texact= act;
-               break;
        }
 }
 
@@ -1016,35 +1005,18 @@ void set_current_world_texture(World *wo, Tex *newtex)
 
 Tex *give_current_brush_texture(Brush *br)
 {
-       MTex *mtex= NULL;
-       Tex *tex= NULL;
-
-       if(br) {
-               mtex= br->mtex[(int)(br->texact)];
-               if(mtex) tex= mtex->tex;
-       }
-
-       return tex;
+       return br->mtex.tex;
 }
 
 void set_current_brush_texture(Brush *br, Tex *newtex)
 {
-       int act= br->texact;
-
-       if(br->mtex[act] && br->mtex[act]->tex)
-               id_us_min(&br->mtex[act]->tex->id);
+       if(br->mtex.tex)
+               id_us_min(&br->mtex.tex->id);
 
        if(newtex) {
-               if(!br->mtex[act])
-                       br->mtex[act]= add_mtex();
-               
-               br->mtex[act]->tex= newtex;
+               br->mtex.tex= newtex;
                id_us_plus(&newtex->id);
        }
-       else if(br->mtex[act]) {
-               MEM_freeN(br->mtex[act]);
-               br->mtex[act]= NULL;
-       }
 }
 
 /* ------------------------------------------------------------------------- */
index de9841e..18fc7b8 100644 (file)
@@ -1532,22 +1532,13 @@ static void direct_link_curvemapping(FileData *fd, CurveMapping *cumap)
 static void lib_link_brush(FileData *fd, Main *main)
 {
        Brush *brush;
-       MTex *mtex;
-       int a;
        
        /* only link ID pointers */
        for(brush= main->brush.first; brush; brush= brush->id.next) {
                if(brush->id.flag & LIB_NEEDLINK) {
                        brush->id.flag -= LIB_NEEDLINK;
 
-                       brush->clone.image= newlibadr_us(fd, brush->id.lib, brush->clone.image);
-                       
-                       for(a=0; a<MAX_MTEX; a++) {
-                               mtex= brush->mtex[a];
-                               if(mtex)
-                                       mtex->tex= newlibadr_us(fd, brush->id.lib, mtex->tex);
-                       }
-
+                       brush->mtex.tex= newlibadr_us(fd, brush->id.lib, brush->mtex.tex);
                        brush->clone.image= newlibadr_us(fd, brush->id.lib, brush->clone.image);
                }
        }
@@ -1556,10 +1547,6 @@ static void lib_link_brush(FileData *fd, Main *main)
 static void direct_link_brush(FileData *fd, Brush *brush)
 {
        /* brush itself has been read */
-       int a;
-
-       for(a=0; a<MAX_MTEX; a++)
-               brush->mtex[a]= newdataadr(fd, brush->mtex[a]);
 
        /* fallof curve */
        brush->curve= newdataadr(fd, brush->curve);
@@ -10336,6 +10323,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        if (1) {
                Scene *sce;
                Object *ob;
+               Brush *brush;
                
                /* game engine changes */
                for(sce = main->scene.first; sce; sce = sce->id.next) {
@@ -10393,6 +10381,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                avs->path_step= arm->pathsize;
                        }
                }
+               
+               /* brush texture changes */
+               for (brush= main->brush.first; brush; brush= brush->id.next) {
+                       default_mtex(&brush->mtex);
+               }
        }
 
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
@@ -10891,11 +10884,7 @@ static void expand_texture(FileData *fd, Main *mainvar, Tex *tex)
 
 static void expand_brush(FileData *fd, Main *mainvar, Brush *brush)
 {
-       int a;
-
-       for(a=0; a<MAX_MTEX; a++)
-               if(brush->mtex[a])
-                       expand_doit(fd, mainvar, brush->mtex[a]->tex);
+       expand_doit(fd, mainvar, brush->mtex.tex);
        expand_doit(fd, mainvar, brush->clone.image);
 }
 
index 3373cc1..98d3dc5 100644 (file)
@@ -2317,16 +2317,12 @@ static void write_nodetrees(WriteData *wd, ListBase *idbase)
 static void write_brushes(WriteData *wd, ListBase *idbase)
 {
        Brush *brush;
-       int a;
        
        for(brush=idbase->first; brush; brush= brush->id.next) {
                if(brush->id.us>0 || wd->current) {
                        writestruct(wd, ID_BR, "Brush", 1, brush);
                        if (brush->id.properties) IDP_WriteProperty(brush->id.properties, wd);
-                       for(a=0; a<MAX_MTEX; a++)
-                               if(brush->mtex[a])
-                                       writestruct(wd, DATA, "MTex", 1, brush->mtex[a]);
-
+                       
                        if(brush->curve)
                                write_curvemapping(wd, brush->curve);
                }
index 77a8ea8..1cca811 100644 (file)
@@ -126,11 +126,12 @@ typedef struct uiLayout uiLayout;
 #define UI_TEXT_LEFT   64
 #define UI_ICON_LEFT   128
 #define UI_ICON_SUBMENU        256
+#define UI_ICON_PREVIEW        512
        /* control for button type block */
-#define UI_MAKE_TOP            512
-#define UI_MAKE_DOWN   1024
-#define UI_MAKE_LEFT   2048
-#define UI_MAKE_RIGHT  4096
+#define UI_MAKE_TOP            1024
+#define UI_MAKE_DOWN   2048
+#define UI_MAKE_LEFT   4096
+#define UI_MAKE_RIGHT  8192
 
        /* button align flag, for drawing groups together */
 #define UI_BUT_ALIGN           (15<<14)
@@ -427,6 +428,7 @@ struct PointerRNA *uiButGetOperatorPtrRNA(uiBut *but);
 #define UI_ID_FAKE_USER                256
 #define UI_ID_PIN                      512
 #define UI_ID_BROWSE_RENDER    1024
+#define UI_ID_PREVIEWS         2048
 #define UI_ID_FULL                     (UI_ID_RENAME|UI_ID_BROWSE|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_ALONE|UI_ID_DELETE|UI_ID_LOCAL)
 
 typedef void (*uiIDPoinFuncFP)(struct bContext *C, char *str, struct ID **idpp);
@@ -451,7 +453,7 @@ uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg,
 uiBut *uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *spoin, char *tip);
 uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *keypoin, short *modkeypoin, char *tip);
 
-uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, short x1, short y1, short x2, short y2, char *tip);
+uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, short x1, short y1, short x2, short y2, float a1, float a2, char *tip);
 
 void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval);
 void uiBlockColorbandButtons(struct uiBlock *block, struct ColorBand *coba, struct rctf *butr, int event);
@@ -641,6 +643,8 @@ void uiTemplateHeader(uiLayout *layout, struct bContext *C, int menus);
 void uiTemplateDopeSheetFilter(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr);
 void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
        char *newop, char *openop, char *unlinkop);
+void uiTemplateIDPreview(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
+       char *newop, char *openop, char *unlinkop, int rows, int cols);
 void uiTemplateAnyID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, 
        char *proptypename, char *text);
 void uiTemplatePathBuilder(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, 
index afe6a2b..69e75d0 100644 (file)
@@ -55,7 +55,9 @@ int UI_icon_get_width(int icon_id);
 int UI_icon_get_height(int icon_id);
 
 void UI_icon_draw(float x, float y, int icon_id);
-void UI_icon_draw_preview(float x, float y, int icon_id, int nocreate);
+void UI_icon_draw_preview(float x, float y, int icon_id);
+void UI_icon_draw_preview_aspect(float x, float y, int icon_id, float aspect);
+void UI_icon_draw_preview_aspect_size(float x, float y, int icon_id, float aspect, int size);
 
 void UI_icon_draw_aspect(float x, float y, int icon_id, float aspect, float alpha);
 void UI_icon_draw_aspect_color(float x, float y, int icon_id, float aspect, float *rgb);
index 88b9c78..5615738 100644 (file)
@@ -3171,9 +3171,10 @@ uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, char *str, short x1, short
 
 
 /* arg is pointer to string/name, use uiButSetSearchFunc() below to make this work */
-uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, short x1, short y1, short x2, short y2, char *tip)
+/* here a1 and a2, if set, control thumbnail preview rows/cols */
+uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, short x1, short y1, short x2, short y2, float a1, float a2, char *tip)
 {
-       uiBut *but= ui_def_but(block, SEARCH_MENU, retval, "", x1, y1, x2, y2, arg, 0.0, maxlen, 0.0, 0.0, tip);
+       uiBut *but= ui_def_but(block, SEARCH_MENU, retval, "", x1, y1, x2, y2, arg, 0.0, maxlen, a1, a2, tip);
        
        but->icon= (BIFIconID) icon;
        but->flag|= UI_HAS_ICON;
index e219198..43c8b0b 100644 (file)
@@ -940,7 +940,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
        }
 }
 
-void ui_id_icon_render(bContext *C, ID *id)
+void ui_id_icon_render(bContext *C, ID *id, int preview)
 {
        PreviewImage *pi = BKE_previewimg_get(id); 
                
@@ -948,13 +948,17 @@ void ui_id_icon_render(bContext *C, ID *id)
                if ((pi->changed[0] ||!pi->rect[0])) /* changed only ever set by dynamic icons */
                {
                        /* create the preview rect if necessary */                              
-                       icon_set_image(C, id, pi, 0);
+                       
+                       icon_set_image(C, id, pi, 0);           /* icon size */
+                       if (preview)
+                               icon_set_image(C, id, pi, 1);   /* preview size */
+                       
                        pi->changed[0] = 0;
                }
        }
 }
 
-int ui_id_icon_get(bContext *C, ID *id)
+int ui_id_icon_get(bContext *C, ID *id, int preview)
 {
        int iconid= 0;
        
@@ -968,7 +972,7 @@ int ui_id_icon_get(bContext *C, ID *id)
                case ID_LA: /* fall through */
                        iconid= BKE_icon_getid(id);
                        /* checks if not exists, or changed */
-                       ui_id_icon_render(C, id);
+                       ui_id_icon_render(C, id, preview);
                        break;
                default:
                        break;
@@ -1004,8 +1008,18 @@ void UI_icon_draw_size(float x, float y, int size, int icon_id, float alpha)
        icon_draw_size(x, y, icon_id, 1.0f, alpha, NULL, 0, size, 1);
 }
 
-void UI_icon_draw_preview(float x, float y, int icon_id, int nocreate)
+void UI_icon_draw_preview(float x, float y, int icon_id)
+{
+       icon_draw_mipmap(x, y, icon_id, 1.0f, 1.0f, PREVIEW_MIPMAP_LARGE, 0);
+}
+
+void UI_icon_draw_preview_aspect(float x, float y, int icon_id, float aspect)
+{
+       icon_draw_mipmap(x, y, icon_id, aspect, 1.0f, PREVIEW_MIPMAP_LARGE, 0);
+}
+
+void UI_icon_draw_preview_aspect_size(float x, float y, int icon_id, float aspect, int size)
 {
-       icon_draw_mipmap(x, y, icon_id, 1.0f, 1.0f, PREVIEW_MIPMAP_LARGE, nocreate);
+       icon_draw_size(x, y, icon_id, aspect, 1.0f, NULL, PREVIEW_MIPMAP_LARGE, size, 0);
 }
 
index 02808f9..72fa949 100644 (file)
@@ -450,13 +450,14 @@ struct ThemeUI;
 void ui_widget_color_init(struct ThemeUI *tui);
 
 void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, char *name, int iconid, int state);
+void ui_draw_preview_item(struct uiFontStyle *fstyle, rcti *rect, char *name, int iconid, int state);
 
 /* interface_style.c */
 void uiStyleInit(void);
 
 /* interface_icons.c */
-void ui_id_icon_render(struct bContext *C, struct ID *id);
-int ui_id_icon_get(struct bContext *C, struct ID *id);
+void ui_id_icon_render(struct bContext *C, struct ID *id, int preview);
+int ui_id_icon_get(struct bContext *C, struct ID *id, int preview);
 
 /* resources.c */
 void init_userdef_do_versions(void);
index e512c1f..c2af415 100644 (file)
@@ -1115,7 +1115,7 @@ static void rna_search_cb(const struct bContext *C, void *arg_but, char *str, ui
                                continue;
                
                if(RNA_struct_is_ID(itemptr.type))
-                       iconid= ui_id_icon_get((bContext*)C, itemptr.data);
+                       iconid= ui_id_icon_get((bContext*)C, itemptr.data, 0);
                
                name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
                
index 8ebfed2..b6956f8 100644 (file)
@@ -547,6 +547,8 @@ typedef struct uiSearchboxData {
        uiSearchItems items;
        int active;             /* index in items array */
        int noback;             /* when menu opened with enough space for this */
+       int preview;    /* draw thumbnail previews, rather than list */
+       int prv_rows, prv_cols;
 } uiSearchboxData;
 
 #define SEARCH_ITEMS   10
@@ -628,14 +630,34 @@ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step)
 
 static void ui_searchbox_butrect(rcti *rect, uiSearchboxData *data, int itemnr)
 {
-       int buth= (data->bbox.ymax-data->bbox.ymin - 2*MENU_TOP)/SEARCH_ITEMS;
-       
-       *rect= data->bbox;
-       rect->xmin= data->bbox.xmin + 3.0f;
-       rect->xmax= data->bbox.xmax - 3.0f;
-       
-       rect->ymax= data->bbox.ymax - MENU_TOP - itemnr*buth;
-       rect->ymin= rect->ymax - buth;
+       /* thumbnail preview */
+       if (data->preview) {
+               int buth = (data->bbox.ymax - data->bbox.ymin - 2*MENU_TOP) / data->prv_rows;
+               int butw = (data->bbox.xmax - data->bbox.xmin) / data->prv_cols;
+               int row, col;
+               
+               *rect= data->bbox;
+               
+               col = itemnr % data->prv_cols;
+               row = itemnr / data->prv_cols;
+               
+               rect->xmin += col * butw;
+               rect->xmax = rect->xmin + butw;
+               
+               rect->ymax = data->bbox.ymax - (row * buth);
+               rect->ymin = rect->ymax - buth;
+       }
+       /* list view */
+       else {
+               int buth= (data->bbox.ymax-data->bbox.ymin - 2*MENU_TOP)/SEARCH_ITEMS;
+               
+               *rect= data->bbox;
+               rect->xmin= data->bbox.xmin + 3.0f;
+               rect->xmax= data->bbox.xmax - 3.0f;
+               
+               rect->ymax= data->bbox.ymax - MENU_TOP - itemnr*buth;
+               rect->ymin= rect->ymax - buth;
+       }
        
 }
 
@@ -799,27 +821,55 @@ static void ui_searchbox_region_draw(const bContext *C, ARegion *ar)
        if(data->items.totitem) {
                rcti rect;
                int a;
+               
+               if (data->preview) {
+                       /* draw items */
+                       for(a=0; a<data->items.totitem; a++) {
+                               ui_searchbox_butrect(&rect, data, a);
                                
-               /* draw items */
-               for(a=0; a<data->items.totitem; a++) {
-                       ui_searchbox_butrect(&rect, data, a);
+                               /* widget itself */
+                               if (data->preview)
+                                       ui_draw_preview_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a+1)==data->active?UI_ACTIVE:0);
+                               else 
+                                       ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a+1)==data->active?UI_ACTIVE:0);
+                       }
                        
-                       /* widget itself */
-                       ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a+1)==data->active?UI_ACTIVE:0);
+                       /* indicate more */
+                       if(data->items.more) {
+                               ui_searchbox_butrect(&rect, data, data->items.maxitem-1);
+                               glEnable(GL_BLEND);
+                               UI_icon_draw(rect.xmax-18, rect.ymin-7, ICON_TRIA_DOWN);
+                               glDisable(GL_BLEND);
+                       }
+                       if(data->items.offset) {
+                               ui_searchbox_butrect(&rect, data, 0);
+                               glEnable(GL_BLEND);
+                               UI_icon_draw(rect.xmin, rect.ymax-9, ICON_TRIA_UP);
+                               glDisable(GL_BLEND);
+                       }
                        
-               }
-               /* indicate more */
-               if(data->items.more) {
-                       ui_searchbox_butrect(&rect, data, data->items.maxitem-1);
-                       glEnable(GL_BLEND);
-                       UI_icon_draw((rect.xmax-rect.xmin)/2, rect.ymin-9, ICON_TRIA_DOWN);
-                       glDisable(GL_BLEND);
-               }
-               if(data->items.offset) {
-                       ui_searchbox_butrect(&rect, data, 0);
-                       glEnable(GL_BLEND);
-                       UI_icon_draw((rect.xmax-rect.xmin)/2, rect.ymax-7, ICON_TRIA_UP);
-                       glDisable(GL_BLEND);
+               } else {
+                       /* draw items */
+                       for(a=0; a<data->items.totitem; a++) {
+                               ui_searchbox_butrect(&rect, data, a);
+                               
+                               /* widget itself */
+                               ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a+1)==data->active?UI_ACTIVE:0);
+                               
+                       }
+                       /* indicate more */
+                       if(data->items.more) {
+                               ui_searchbox_butrect(&rect, data, data->items.maxitem-1);
+                               glEnable(GL_BLEND);
+                               UI_icon_draw((rect.xmax-rect.xmin)/2, rect.ymin-9, ICON_TRIA_DOWN);
+                               glDisable(GL_BLEND);
+                       }
+                       if(data->items.offset) {
+                               ui_searchbox_butrect(&rect, data, 0);
+                               glEnable(GL_BLEND);
+                               UI_icon_draw((rect.xmax-rect.xmin)/2, rect.ymax-7, ICON_TRIA_UP);
+                               glDisable(GL_BLEND);
+                       }
                }
        }
 }
@@ -830,7 +880,7 @@ static void ui_searchbox_region_free(ARegion *ar)
        int a;
 
        /* free search data */
-       for(a=0; a<SEARCH_ITEMS; a++)
+       for(a=0; a<data->items.maxitem; a++)
                MEM_freeN(data->items.names[a]);
        MEM_freeN(data->items.names);
        MEM_freeN(data->items.pointers);
@@ -876,8 +926,13 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
        if(but->block->flag & UI_BLOCK_LOOP)
                data->noback= 1;
        
-       /* compute position */
+       if (but->a1 > 0 && but->a2 > 0) {
+               data->preview = 1;
+               data->prv_rows = but->a1;
+               data->prv_cols = but->a2;
+       }
        
+       /* compute position */
        if(but->block->flag & UI_BLOCK_LOOP) {
                /* this case is search menu inside other menu */
                /* we copy region size */
@@ -972,13 +1027,17 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
        ED_region_tag_redraw(ar);
        
        /* prepare search data */
-       data->items.maxitem= SEARCH_ITEMS;
+       if (data->preview) {
+               data->items.maxitem= data->prv_rows * data->prv_cols;
+       } else {
+               data->items.maxitem= SEARCH_ITEMS;
+       }
        data->items.maxstrlen= but->hardmax;
        data->items.totitem= 0;
-       data->items.names= MEM_callocN(SEARCH_ITEMS*sizeof(void *), "search names");
-       data->items.pointers= MEM_callocN(SEARCH_ITEMS*sizeof(void *), "search pointers");
-       data->items.icons= MEM_callocN(SEARCH_ITEMS*sizeof(int), "search icons");
-       for(x1=0; x1<SEARCH_ITEMS; x1++)
+       data->items.names= MEM_callocN(data->items.maxitem*sizeof(void *), "search names");
+       data->items.pointers= MEM_callocN(data->items.maxitem*sizeof(void *), "search pointers");
+       data->items.icons= MEM_callocN(data->items.maxitem*sizeof(int), "search icons");
+       for(x1=0; x1<data->items.maxitem; x1++)
                data->items.names[x1]= MEM_callocN(but->hardmax+1, "search pointers");
        
        return ar;
index a2b9260..3c2387c 100644 (file)
@@ -122,6 +122,7 @@ typedef struct TemplateID {
        PropertyRNA *prop;
 
        ListBase *idlb;
+       int prv_rows, prv_cols;
 } TemplateID;
 
 /* Search browse menu, assign  */
@@ -150,7 +151,7 @@ static void id_search_cb(const bContext *C, void *arg_template, char *str, uiSea
        /* ID listbase */
        for(id= lb->first; id; id= id->next) {
                if(BLI_strcasestr(id->name+2, str)) {
-                       iconid= ui_id_icon_get((bContext*)C, id);
+                       iconid= ui_id_icon_get((bContext*)C, id, 0);
 
                        if(!uiSearchItemAdd(items, id->name+2, id, iconid))
                                break;
@@ -180,11 +181,26 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
        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);
+       /* preview thumbnails */
+       if (template.prv_rows > 0 && template.prv_cols > 0) {
+               int w = 96 * template.prv_cols;
+               int h = 96 * template.prv_rows + 20;
+               
+               /* fake button, it holds space for search items */
+               uiDefBut(block, LABEL, 0, "", 10, 15, w, h, NULL, 0, 0, 0, 0, NULL);
+               
+               but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, w, 19, template.prv_rows, template.prv_cols, "");
+               uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
+       }
+       /* list view */
+       else {
+               /* 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, 0, 0, "");
+               uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
+       }
+               
        
        uiBoundsBlock(block, 6);
        uiBlockSetDirection(block, UI_DOWN);    
@@ -293,9 +309,10 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
        }
 }
 
-static void template_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type, int flag, char *newop, char *openop, char *unlinkop)
+static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, int flag, char *newop, char *openop, char *unlinkop)
 {
        uiBut *but;
+       uiBlock *block;
        PointerRNA idptr;
        ListBase *lb;
        ID *id, *idfrom;
@@ -305,11 +322,27 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc
        idfrom= template->ptr.id.data;
        lb= template->idlb;
 
+       block= uiLayoutGetBlock(layout);
        uiBlockBeginAlign(block);
 
        if(idptr.type)
                type= idptr.type;
 
+       if(flag & UI_ID_PREVIEWS) {
+
+               but= uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X*6, UI_UNIT_Y*6, "Browse ID data");
+               if(type) {
+                       but->icon= RNA_struct_ui_icon(type);
+                       if (id) but->icon = ui_id_icon_get(C, id, 1);
+                       uiButSetFlag(but, UI_HAS_ICON|UI_ICON_PREVIEW);
+               }
+               if((idfrom && idfrom->lib))
+                       uiButSetFlag(but, UI_BUT_DISABLED);
+               
+               
+               uiLayoutRow(layout, 1);
+       } else 
+               
        if(flag & UI_ID_BROWSE) {
                but= uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X*1.6, UI_UNIT_Y, "Browse ID data");
                if(type) {
@@ -412,10 +445,9 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc
        uiBlockEndAlign(block);
 }
 
-void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop)
+static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop, int previews, int prv_rows, int prv_cols)
 {
        TemplateID *template;
-       uiBlock *block;
        PropertyRNA *prop;
        StructRNA *type;
        int flag;
@@ -430,14 +462,18 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname
        template= MEM_callocN(sizeof(TemplateID), "TemplateID");
        template->ptr= *ptr;
        template->prop= prop;
-
+       template->prv_rows = prv_rows;
+       template->prv_cols = prv_cols;
+       
        flag= UI_ID_BROWSE|UI_ID_RENAME|UI_ID_DELETE;
 
        if(newop)
                flag |= UI_ID_ADD_NEW;
        if(openop)
                flag |= UI_ID_OPEN;
-
+       if(previews)
+               flag |= UI_ID_PREVIEWS;
+       
        type= RNA_property_pointer_type(ptr, prop);
        template->idlb= wich_libbase(CTX_data_main(C), RNA_type_to_ID_code(type));
        
@@ -446,11 +482,21 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname
         */
        if(template->idlb) {
                uiLayoutRow(layout, 1);
-               block= uiLayoutGetBlock(layout);
-               template_ID(C, block, template, type, flag, newop, openop, unlinkop);
+               template_ID(C, layout, template, type, flag, newop, openop, unlinkop);
        }
 
        MEM_freeN(template);
+       
+}
+
+void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop)
+{
+       ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, 0, 0, 0);
+}
+
+void uiTemplateIDPreview(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop, int rows, int cols)
+{
+       ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, 1, rows, cols);
 }
 
 /************************ ID Chooser Template ***************************/
@@ -1944,7 +1990,7 @@ static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon)
 
        /* get icon from ID */
        if(id) {
-               icon= ui_id_icon_get(C, id);
+               icon= ui_id_icon_get(C, id, 1);
 
                if(icon)
                        return icon;
@@ -2245,7 +2291,7 @@ void uiTemplateOperatorSearch(uiLayout *layout)
        block= uiLayoutGetBlock(layout);
        uiBlockSetCurLayout(block, layout);
 
-       but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 0, 0, UI_UNIT_X*6, UI_UNIT_Y, "");
+       but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 0, 0, UI_UNIT_X*6, UI_UNIT_Y, 0, 0, "");
        uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL);
 }
 
index 4c96989..9e23530 100644 (file)
@@ -695,6 +695,27 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
 
 /* *********************** text/icon ************************************** */
 
+#define PREVIEW_PAD    4
+
+static void widget_draw_preview(BIFIconID icon, float aspect, float alpha, rcti *rect)
+{
+       int w, h, x, y, size;
+       
+       /* only display previews for actual preview images .. ? */
+       if (icon < BIFICONID_LAST)
+               return;
+       
+       w = rect->xmax - rect->xmin;
+       h = rect->ymax - rect->ymin;
+       size = MIN2(w, h);
+       size -= PREVIEW_PAD*2;  /* padding */
+       
+       x = rect->xmin + w/2 - size/2;
+       y = rect->ymin + h/2 - size/2;
+       
+       UI_icon_draw_preview_aspect_size(x, y, icon, aspect, size);
+}
+
 
 /* icons have been standardized... and this call draws in untransformed coordinates */
 #define ICON_HEIGHT            16.0f
@@ -704,6 +725,11 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect
        int xs=0, ys=0;
        float aspect, height;
        
+       if (but->flag & UI_ICON_PREVIEW) {
+               widget_draw_preview(icon, but->block->aspect, alpha, rect);
+               return;
+       }
+       
        /* this icon doesn't need draw... */
        if(icon==ICON_BLANK1 && (but->flag & UI_ICON_SUBMENU)==0) return;
        
@@ -2692,3 +2718,25 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int iconid,
        }
 }
 
+void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, char *name, int iconid, int state)
+{
+       rcti trect = *rect;
+       
+       uiWidgetType *wt= widget_type(UI_WTYPE_MENU_ITEM);
+       
+       wt->state(wt, state);
+       wt->draw(&wt->wcol, rect, 0, 0);
+       
+       widget_draw_preview(iconid, 1.f, 1.f, rect);
+       
+       if (state == UI_ACTIVE)
+               glColor3ubv((unsigned char*)wt->wcol.text);
+       else
+               glColor3ubv((unsigned char*)wt->wcol.text_sel);
+       
+       trect.xmin += 0;
+       trect.xmax = trect.xmin + BLF_width(name) + 10;
+       trect.ymin += 10;
+       trect.ymax = trect.ymin + BLF_height(name);
+       uiStyleFontDraw(fstyle, &trect, name);
+}
index 526eb2d..4c903f6 100644 (file)
@@ -2890,7 +2890,7 @@ static void project_paint_begin(ProjPaintState *ps)
        
        ps->is_airbrush = (ps->brush->flag & BRUSH_AIRBRUSH) ? 1 : 0;
        
-       ps->is_texbrush = (ps->brush->mtex[ps->brush->texact] && ps->brush->mtex[ps->brush->texact]->tex) ? 1 : 0;
+       ps->is_texbrush = (ps->brush->mtex.tex) ? 1 : 0;
 
        
        /* calculate vert screen coords
index 09b99f4..75cc927 100644 (file)
@@ -614,12 +614,9 @@ static float get_texcache_pixel_bilinear(const SculptSession *ss, float u, float
 /* Return a multiplier for brush strength on a particular vertex. */
 static float tex_strength(SculptSession *ss, Brush *br, float *point, const float len)
 {
-       MTex *tex = NULL;
+       MTex *tex = &br->mtex;
        float avg= 1;
 
-       if(br->texact >= 0)
-               tex = br->mtex[br->texact];
-
        if(!tex) {
                avg= 1;
        }
index 18ba149..c4bdd3a 100644 (file)
@@ -626,7 +626,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
                        Brush *br= ptr->data;
 
                        if(br)
-                               CTX_data_pointer_set(result, &br->id, &RNA_BrushTextureSlot, br->mtex[(int)br->texact]);
+                               CTX_data_pointer_set(result, &br->id, &RNA_BrushTextureSlot, &br->mtex);
                }
 
                return 1;
index 7e51ee2..6677a06 100644 (file)
@@ -335,6 +335,10 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
                        buttons_area_redraw(sa, BCONTEXT_DATA);
                        sbuts->preview= 1;
                        break;
+               case NC_BRUSH:
+                       buttons_area_redraw(sa, BCONTEXT_TEXTURE);
+                       sbuts->preview= 1;
+                       break;
                case NC_TEXTURE:
                        ED_area_tag_redraw(sa);
                        sbuts->preview= 1;
index f348532..1303168 100644 (file)
@@ -5029,7 +5029,7 @@ static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi)
        /* 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, "");
+       but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, 0, 0, "");
        uiButSetSearchFunc(but, operator_search_cb, arg_kmi, operator_call_cb, ot);
        
        uiBoundsBlock(block, 6);
index 0384a23..b05043c 100644 (file)
@@ -239,7 +239,7 @@ static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
        /* 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, OP_MAX_TYPENAME, 10, 0, 150, 19, "");
+       but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, OP_MAX_TYPENAME, 10, 0, 150, 19, 0, 0, "");
        uiButSetSearchFunc(but, operator_search_cb, arg_listbase, operator_call_cb, NULL);
        
        uiBoundsBlock(block, 6);
index c8fc14c..4738b0d 100644 (file)
@@ -31,6 +31,7 @@
 #define DNA_BRUSH_TYPES_H
 
 #include "DNA_ID.h"
+#include "DNA_texture_types.h"
 
 #ifndef MAX_MTEX
 #define MAX_MTEX       18
@@ -50,9 +51,8 @@ typedef struct Brush {
        ID id;
 
        struct BrushClone clone;
-
        struct CurveMapping *curve;     /* falloff curve */
-       struct MTex *mtex[18];          /* MAX_MTEX */
+       struct MTex mtex;
        
        short flag, blend;                      /* general purpose flag, blend mode */
        int size;                                       /* brush diameter */
@@ -65,10 +65,8 @@ typedef struct Brush {
        float rgb[3];                           /* color */
        float alpha;                            /* opacity */
 
-       short texact;                           /* active texture */
        char sculpt_tool;                       /* active tool */
-       
-       char pad[1];
+       char pad2[3];
 } Brush;
 
 /* Brush.flag */
index 7f7126c..8f8dd46 100644 (file)
@@ -33,6 +33,7 @@
 #include "DNA_texture_types.h"
 
 #include "IMB_imbuf.h"
+#include "WM_types.h"
 
 EnumPropertyItem brush_sculpt_tool_items[] = {
        {SCULPT_TOOL_DRAW, "DRAW", 0, "Draw", ""},
@@ -52,29 +53,6 @@ EnumPropertyItem brush_sculpt_tool_items[] = {
 #include "BKE_texture.h"
 
 #include "WM_api.h"
-#include "WM_types.h"
-
-static void rna_Brush_mtex_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
-{
-       Brush *brush= (Brush*)ptr->data;
-       rna_iterator_array_begin(iter, (void*)brush->mtex, sizeof(MTex*), MAX_MTEX, 0, NULL);
-}
-
-static PointerRNA rna_Brush_active_texture_get(PointerRNA *ptr)
-{
-       Brush *br= (Brush*)ptr->data;
-       Tex *tex;
-
-       tex= give_current_brush_texture(br);
-       return rna_pointer_inherit_refine(ptr, &RNA_Texture, tex);
-}
-
-static void rna_Brush_active_texture_set(PointerRNA *ptr, PointerRNA value)
-{
-       Brush *br= (Brush*)ptr->data;
-
-       set_current_brush_texture(br, value.data);
-}
 
 static void rna_Brush_update(Main *bmain, Scene *scene, PointerRNA *ptr)
 {
@@ -291,8 +269,17 @@ static void rna_def_brush(BlenderRNA *brna)
        RNA_def_property_update(prop, 0, "rna_Brush_update");
 
        /* texture */
-       rna_def_mtex_common(srna, "rna_Brush_mtex_begin", "rna_Brush_active_texture_get",
-               "rna_Brush_active_texture_set", "BrushTextureSlot", "rna_Brush_update");
+       prop= RNA_def_property(srna, "texture_slot", PROP_POINTER, PROP_NONE);
+       RNA_def_property_struct_type(prop, "BrushTextureSlot");
+       RNA_def_property_pointer_sdna(prop, NULL, "mtex");
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Texture Slot", "");
+       
+       prop= RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "mtex.tex");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Texture", "");
+       RNA_def_property_update(prop, NC_TEXTURE, "rna_Brush_update");
 
        /* clone tool */
        prop= RNA_def_property(srna, "clone_image", PROP_POINTER, PROP_NONE);
index 9c4cc64..37917bb 100644 (file)
@@ -269,6 +269,15 @@ void RNA_api_ui_layout(StructRNA *srna)
        RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a file for creating a new ID block.");
        RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block.");
        
+       func= RNA_def_function(srna, "template_ID_preview", "uiTemplateIDPreview");
+       RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+       api_ui_item_rna_common(func);
+       RNA_def_string(func, "new", "", 0, "", "Operator identifier to create a new ID block.");
+       RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a file for creating a new ID block.");
+       RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block.");
+       RNA_def_int(func, "rows", 0, 0, INT_MAX, "Number of thumbnail preview rows to display", "", 0, INT_MAX);
+       RNA_def_int(func, "cols", 0, 0, INT_MAX, "Number of thumbnail preview columns to display", "", 0, INT_MAX);
+       
        func= RNA_def_function(srna, "template_any_ID", "uiTemplateAnyID");
        RNA_def_function_flag(func, FUNC_USE_CONTEXT);
        parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property.");
index 1264639..ca53b0d 100644 (file)
@@ -1037,7 +1037,7 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *arg_op)
        block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
        uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT);
        
-       but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 180, 19, "");
+       but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 180, 19, 0, 0, "");
        uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL);
        
        /* fake button, it holds space for search items */