UI
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 27 Jun 2009 01:15:31 +0000 (01:15 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 27 Jun 2009 01:15:31 +0000 (01:15 +0000)
* Search popup + autocomplete for bones, vertex groups, etc. This
  is done with layout.item_pointerR, specifying an RNA collection to
  take the items from. Used by constraints and modifiers.

* Some tests with the List template, ignore those for now..

15 files changed:
release/ui/buttons_data_mesh.py
release/ui/buttons_data_modifier.py
release/ui/buttons_object_constraint.py
release/ui/space_image.py
release/ui/space_text.py
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_handlers.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_utils.c
source/blender/makesrna/intern/rna_ui_api.c

index 6f64de312edca6bcd6b1eb703c21989321ed9a31..3360f4c47ad512c0aeb387f1e1dfa4dd1e0e4929 100644 (file)
@@ -74,6 +74,18 @@ class DATA_PT_materials(DataButtonsPanel):
                row.itemO("OBJECT_OT_material_slot_select", text="Select");
                row.itemO("OBJECT_OT_material_slot_deselect", text="Deselect");
 
+               layout.itemS()
+
+               box= layout.box()
+
+               row = box.row()
+               row.template_list(ob, "materials", "active_material_index", compact=True)
+
+               subrow = row.row(align=True)
+               subrow.itemO("OBJECT_OT_material_slot_add", icon="ICON_ZOOMIN", text="")
+               subrow.itemO("OBJECT_OT_material_slot_remove", icon="ICON_ZOOMOUT", text="")
+
+
 bpy.types.register(DATA_PT_mesh)
 bpy.types.register(DATA_PT_materials)
 
index ecb0590f8e59338fbe6ccaefb2d799f87d395e50..366f2b8a86b10ae9b3d33853df3cc04b23ed2e1b 100644 (file)
@@ -23,68 +23,68 @@ class DATA_PT_modifiers(DataButtonsPanel):
 
                        if box:
                                if md.type == 'ARMATURE':
-                                       self.armature(box, md)
+                                       self.armature(box, ob, md)
                                if md.type == 'ARRAY':
-                                       self.array(box, md)
+                                       self.array(box, ob, md)
                                if md.type == 'BEVEL':
-                                       self.bevel(box, md)
+                                       self.bevel(box, ob, md)
                                if md.type == 'BOOLEAN':
-                                       self.boolean(box, md)
+                                       self.boolean(box, ob, md)
                                if md.type == 'BUILD':
-                                       self.build(box, md)
+                                       self.build(box, ob, md)
                                if md.type == 'CAST':
-                                       self.cast(box, md)
+                                       self.cast(box, ob, md)
                                if md.type == 'CLOTH':
-                                       self.cloth(box, md)
+                                       self.cloth(box, ob, md)
                                if md.type == 'COLLISION':
-                                       self.collision(box, md)
+                                       self.collision(box, ob, md)
                                if md.type == 'CURVE':
-                                       self.curve(box, md)
+                                       self.curve(box, ob, md)
                                if md.type == 'DECIMATE':
-                                       self.decimate(box, md)
+                                       self.decimate(box, ob, md)
                                if md.type == 'DISPLACE':
-                                       self.displace(box, md)
+                                       self.displace(box, ob, md)
                                if md.type == 'EDGE_SPLIT':
-                                       self.edgesplit(box, md)
+                                       self.edgesplit(box, ob, md)
                                if md.type == 'EXPLODE':
-                                       self.explode(box, md)
+                                       self.explode(box, ob, md)
                                if md.type == 'FLUID_SIMULATION':
-                                       self.fluid(box, md)
+                                       self.fluid(box, ob, md)
                                if md.type == 'HOOK':
-                                       self.hook(box, md)
+                                       self.hook(box, ob, md)
                                if md.type == 'LATTICE':
-                                       self.lattice(box, md)
+                                       self.lattice(box, ob, md)
                                if md.type == 'MASK':
-                                       self.mask(box, md)
+                                       self.mask(box, ob, md)
                                if md.type == 'MESH_DEFORM':
-                                       self.mesh_deform(box, md)
+                                       self.mesh_deform(box, ob, md)
                                if md.type == 'MIRROR':
-                                       self.mirror(box, md)
+                                       self.mirror(box, ob, md)
                                if md.type == 'MULTIRES':
-                                       self.multires(box, md)
+                                       self.multires(box, ob, md)
                                if md.type == 'PARTICLE_INSTANCE':
-                                       self.particleinstance(box, md)
+                                       self.particleinstance(box, ob, md)
                                if md.type == 'PARTICLE_SYSTEM':
-                                       self.particlesystem(box, md)
+                                       self.particlesystem(box, ob, md)
                                if md.type == 'SHRINKWRAP':
-                                       self.shrinkwrap(box, md)
+                                       self.shrinkwrap(box, ob, md)
                                if md.type == 'SIMPLE_DEFORM':
-                                       self.simpledeform(box, md)
+                                       self.simpledeform(box, ob, md)
                                if md.type == 'SMOOTH':
-                                       self.smooth(box, md)
+                                       self.smooth(box, ob, md)
                                if md.type == 'SOFTBODY':
-                                       self.softbody(box, md)
+                                       self.softbody(box, ob, md)
                                if md.type == 'SUBSURF':
-                                       self.subsurf(box, md)
+                                       self.subsurf(box, ob, md)
                                if md.type == 'UV_PROJECT':
-                                       self.uvproject(box, md)
+                                       self.uvproject(box, ob, md)
                                if md.type == 'WAVE':
-                                       self.wave(box, md)
+                                       self.wave(box, ob, md)
                                                        
-       def armature(self, layout, md):
+       def armature(self, layout, ob, md):
                layout.itemR(md, "object")
                row = layout.row()
-               row.itemR(md, "vertex_group")
+               row.item_pointerR(md, "vertex_group", ob, "vertex_groups")
                row.itemR(md, "invert")
                flow = layout.column_flow()
                flow.itemR(md, "use_vertex_groups", text="Vertex Groups")
@@ -92,7 +92,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
                flow.itemR(md, "quaternion")
                flow.itemR(md, "multi_modifier")
                
-       def array(self, layout, md):
+       def array(self, layout, ob, md):
                layout.itemR(md, "fit_type")
                if md.fit_type == 'FIXED_COUNT':
                        layout.itemR(md, "count")
@@ -141,7 +141,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
                col.itemR(md, "start_cap")
                col.itemR(md, "end_cap")
        
-       def bevel(self, layout, md):
+       def bevel(self, layout, ob, md):
                row = layout.row()
                row.itemR(md, "width")
                row.itemR(md, "only_vertices")
@@ -156,11 +156,11 @@ class DATA_PT_modifiers(DataButtonsPanel):
                        row = layout.row()
                        row.itemR(md, "edge_weight_method", expand=True)
                        
-       def boolean(self, layout, md):
+       def boolean(self, layout, ob, md):
                layout.itemR(md, "operation")
                layout.itemR(md, "object")
                
-       def build(self, layout, md):
+       def build(self, layout, ob, md):
                split = layout.split()
                
                col = split.column()
@@ -175,7 +175,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
                        
                
                        
-       def cast(self, layout, md):
+       def cast(self, layout, ob, md):
                layout.itemR(md, "cast_type")
                col = layout.column_flow()
                col.itemR(md, "x")
@@ -184,26 +184,26 @@ class DATA_PT_modifiers(DataButtonsPanel):
                col.itemR(md, "factor")
                col.itemR(md, "radius")
                col.itemR(md, "size")
-               layout.itemR(md, "vertex_group")
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
                #Missing: "OB" and "From Radius"
                
-       def cloth(self, layout, md):
+       def cloth(self, layout, ob, md):
                layout.itemL(text="See Cloth panel.")
                
-       def collision(self, layout, md):
+       def collision(self, layout, ob, md):
                layout.itemL(text="See Collision panel.")
                
-       def curve(self, layout, md):
+       def curve(self, layout, ob, md):
                layout.itemR(md, "object")
-               layout.itemR(md, "vertex_group")
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
                layout.itemR(md, "deform_axis")
                
-       def decimate(self, layout, md):
+       def decimate(self, layout, ob, md):
                layout.itemR(md, "ratio")
                layout.itemR(md, "face_count")
                
-       def displace(self, layout, md):
-               layout.itemR(md, "vertex_group")
+       def displace(self, layout, ob, md):
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
                layout.itemR(md, "texture")
                layout.itemR(md, "midlevel")
                layout.itemR(md, "strength")
@@ -211,10 +211,10 @@ class DATA_PT_modifiers(DataButtonsPanel):
                layout.itemR(md, "texture_coordinates")
                if md.texture_coordinates == 'OBJECT':
                        layout.itemR(md, "texture_coordinate_object", text="Object")
-               if md.texture_coordinates == 'UV':
-                       layout.itemR(md, "uv_layer")
+               if md.texture_coordinates == 'UV' and ob.type == 'MESH':
+                       layout.item_pointerR(md, "uv_layer", ob.data, "uv_layers")
        
-       def edgesplit(self, layout, md):
+       def edgesplit(self, layout, ob, md):
                split = layout.split()
                
                col = split.column()
@@ -225,8 +225,8 @@ class DATA_PT_modifiers(DataButtonsPanel):
                col = split.column()
                col.itemR(md, "use_sharp", text="Sharp Edges")
                
-       def explode(self, layout, md):
-               layout.itemR(md, "vertex_group")
+       def explode(self, layout, ob, md):
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
                layout.itemR(md, "protect")
                layout.itemR(md, "split_edges")
                layout.itemR(md, "unborn")
@@ -234,31 +234,31 @@ class DATA_PT_modifiers(DataButtonsPanel):
                layout.itemR(md, "dead")
                # Missing: "Refresh" and "Clear Vertex Group" ?
                
-       def fluid(self, layout, md):
+       def fluid(self, layout, ob, md):
                layout.itemL(text="See Fluidsim panel.")
                
-       def hook(self, layout, md):
+       def hook(self, layout, ob, md):
                layout.itemR(md, "falloff")
                layout.itemR(md, "force", slider=True)
                layout.itemR(md, "object")
-               layout.itemR(md, "vertex_group")
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
                # Missing: "Reset" and "Recenter"
                
-       def lattice(self, layout, md):
+       def lattice(self, layout, ob, md):
                layout.itemR(md, "object")
-               layout.itemR(md, "vertex_group")
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
                
-       def mask(self, layout, md):
+       def mask(self, layout, ob, md):
                layout.itemR(md, "mode")
                if md.mode == 'ARMATURE':
                        layout.itemR(md, "armature")
                if md.mode == 'VERTEX_GROUP':
-                       layout.itemR(md, "vertex_group")
+                       layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
                layout.itemR(md, "inverse")
                
-       def mesh_deform(self, layout, md):
+       def mesh_deform(self, layout, ob, md):
                layout.itemR(md, "object")
-               layout.itemR(md, "vertex_group")
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
                layout.itemR(md, "invert")
 
                layout.itemS()
@@ -267,7 +267,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
                row.itemR(md, "precision")
                row.itemR(md, "dynamic")
                
-       def mirror(self, layout, md):
+       def mirror(self, layout, ob, md):
                layout.itemR(md, "merge_limit")
                split = layout.split()
                
@@ -285,12 +285,12 @@ class DATA_PT_modifiers(DataButtonsPanel):
                
                layout.itemR(md, "mirror_object")
                
-       def multires(self, layout, md):
+       def multires(self, layout, ob, md):
                layout.itemR(md, "subdivision_type")
                layout.itemO("OBJECT_OT_multires_subdivide", text="Subdivide")
                layout.itemR(md, "level")
        
-       def particleinstance(self, layout, md):
+       def particleinstance(self, layout, ob, md):
                layout.itemR(md, "object")
                layout.itemR(md, "particle_system_number")
                
@@ -302,12 +302,12 @@ class DATA_PT_modifiers(DataButtonsPanel):
                col.itemR(md, "alive")
                col.itemR(md, "dead")
                
-       def particlesystem(self, layout, md):
+       def particlesystem(self, layout, ob, md):
                layout.itemL(text="See Particle panel.")
                
-       def shrinkwrap(self, layout, md):
+       def shrinkwrap(self, layout, ob, md):
                layout.itemR(md, "target")
-               layout.itemR(md, "vertex_group")
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
                layout.itemR(md, "offset")
                layout.itemR(md, "subsurf_levels")
                layout.itemR(md, "mode")
@@ -329,9 +329,9 @@ class DATA_PT_modifiers(DataButtonsPanel):
                        layout.itemR(md, "keep_above_surface")
                # To-Do: Validate if structs
                
-       def simpledeform(self, layout, md):
+       def simpledeform(self, layout, ob, md):
                layout.itemR(md, "mode")
-               layout.itemR(md, "vertex_group")
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
                layout.itemR(md, "origin")
                layout.itemR(md, "relative")
                layout.itemR(md, "factor")
@@ -340,7 +340,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
                        layout.itemR(md, "lock_x_axis")
                        layout.itemR(md, "lock_y_axis")
        
-       def smooth(self, layout, md):
+       def smooth(self, layout, ob, md):
                split = layout.split()
                sub = split.column()
                sub.itemR(md, "x")
@@ -350,12 +350,12 @@ class DATA_PT_modifiers(DataButtonsPanel):
                sub.itemR(md, "factor")
                sub.itemR(md, "repeat")
                
-               layout.itemR(md, "vertex_group")
+               layout.template_pointer(md, "vertex_group", ob, "vertex_groups")
                
-       def softbody(self, layout, md):
+       def softbody(self, layout, ob, md):
                layout.itemL(text="See Softbody panel.")
        
-       def subsurf(self, layout, md):
+       def subsurf(self, layout, ob, md):
                layout.itemR(md, "subdivision_type")
                col = layout.column_flow()
                col.itemR(md, "levels", text="Preview")
@@ -363,16 +363,17 @@ class DATA_PT_modifiers(DataButtonsPanel):
                col.itemR(md, "optimal_draw", text="Optimal Display")
                col.itemR(md, "subsurf_uv")
        
-       def uvproject(self, layout, md):
-               layout.itemR(md, "uv_layer")
-               layout.itemR(md, "projectors")
-               layout.itemR(md, "image")
-               layout.itemR(md, "horizontal_aspect_ratio")
-               layout.itemR(md, "vertical_aspect_ratio")
-               layout.itemR(md, "override_image")
-               #"Projectors" don't work.
-               
-       def wave(self, layout, md):
+       def uvproject(self, layout, ob, md):
+               if ob.type == 'MESH':
+                       layout.item_pointerR(md, "uv_layer", ob.data, "uv_layers")
+                       layout.itemR(md, "projectors")
+                       layout.itemR(md, "image")
+                       layout.itemR(md, "horizontal_aspect_ratio")
+                       layout.itemR(md, "vertical_aspect_ratio")
+                       layout.itemR(md, "override_image")
+                       #"Projectors" don't work.
+               
+       def wave(self, layout, ob, md):
                split = layout.split()
                
                sub = split.column()
@@ -398,11 +399,11 @@ class DATA_PT_modifiers(DataButtonsPanel):
                col.itemR(md, "start_position_y")
                
                layout.itemR(md, "start_position_object")
-               layout.itemR(md, "vertex_group")
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
                layout.itemR(md, "texture")
                layout.itemR(md, "texture_coordinates")
-               if md.texture_coordinates == 'MAP_UV':
-                       layout.itemR(md, "uv_layer")
+               if md.texture_coordinates == 'MAP_UV' and ob.type == 'MESH':
+                       layout.item_pointerR(md, "uv_layer", ob.data, "uv_layers")
                if md.texture_coordinates == 'OBJECT':
                        layout.itemR(md, "texture_coordinates_object")
                
@@ -412,4 +413,4 @@ class DATA_PT_modifiers(DataButtonsPanel):
                col.itemR(md, "width", slider=True)
                col.itemR(md, "narrowness", slider=True)
 
-bpy.types.register(DATA_PT_modifiers)
\ No newline at end of file
+bpy.types.register(DATA_PT_modifiers)
index 52e434067905c51cfc93935d55e1c07c47e15414..3048bdaa39978903c749dcbb3b37fb963ccb793a 100644 (file)
@@ -77,13 +77,14 @@ class ConstraintButtonsPanel(bpy.types.Panel):
                
                if con.target and subtargets:
                        if con.target.type == "ARMATURE":
-                               layout.itemR(con, "subtarget", text="Bone") # XXX autocomplete
+                               layout.item_pointerR(con, "subtarget", con.target.data, "bones", text="Bone")
                                
-                               row = layout.row()
-                               row.itemL(text="Head/Tail:")
-                               row.itemR(con, "head_tail", text="")
+                               if con.type == 'COPY_LOCATION':
+                                       row = layout.row()
+                                       row.itemL(text="Head/Tail:")
+                                       row.itemR(con, "head_tail", text="")
                        elif con.target.type in ("MESH", "LATTICE"):
-                               layout.itemR(con, "subtarget", text="Vertex Group") # XXX autocomplete
+                               layout.item_pointerR(con, "subtarget", con.target, "vertex_groups", text="Vertex Group")
        
        def child_of(self, layout, con):
                self.target_template(layout, con)
index e49172fd3f194b9ff1dbe29c7372f13cfecde789..63ca316efe755ba04bd3ad160ce30bcc8f65b071 100644 (file)
@@ -273,16 +273,8 @@ class IMAGE_HT_header(bpy.types.Header):
                                row.itemR(settings, "snap_mode", text="")
 
                        """
-                       /* uv layers */
-                       {
-                               Object *obedit= CTX_data_edit_object(C);
-                               char menustr[34*MAX_MTFACE];
-                               static int act;
-                               
-                               image_menu_uvlayers(obedit, menustr, &act);
-
-                               but = uiDefButI(block, MENU, B_NOP, menustr ,xco,yco,85,YIC, &act, 0, 0, 0, 0, "Active UV Layer for editing.");
-                               // uiButSetFunc(but, do_image_buttons_set_uvlayer_callback, &act, NULL);
+                       mesh = context.edit_object.data
+                       row.item_pointerR(mesh, "active_uv_layer", mesh, "uv_layers")
                        """
 
                if ima:
index 19a495d375ed08846b700bacdf3eb092ea2c1f9f..07e43f32054241de61e7f44c53858bb874da02a4 100644 (file)
@@ -29,7 +29,7 @@ class TEXT_HT_header(bpy.types.Header):
                row.itemR(st, "word_wrap", text="")
                row.itemR(st, "syntax_highlight", text="")
 
-               layout.template_ID(st, "text", new="TEXT_OT_new", open="TEXT_OT_open", unlink="TEXT_OT_unlink")
+               layout.template_ID(st, "text", new="TEXT_OT_new", unlink="TEXT_OT_unlink")
 
                if text:
                        row = layout.row()
index f5e2b45d41ea824ac6ef214c608bceb488172a3a..b6d7175937380a27a74abe8b4b356b21a8d4d1ba 100644 (file)
@@ -609,7 +609,7 @@ uiBlock *uiLayoutFreeBlock(uiLayout *layout);
 /* templates */
 void uiTemplateHeader(uiLayout *layout, struct bContext *C);
 void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
-       char *newop, char *openop, char *unlinkop);
+       char *newop, char *unlinkop);
 uiLayout *uiTemplateModifier(uiLayout *layout, struct PointerRNA *ptr);
 uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
 void uiTemplatePreview(uiLayout *layout, struct ID *id);
@@ -617,7 +617,7 @@ void uiTemplateColorRamp(uiLayout *layout, struct ColorBand *coba, int expand);
 void uiTemplateCurveMapping(uiLayout *layout, struct CurveMapping *cumap, int type);
 void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, char *propname);
 void uiTemplateImageLayers(uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser);
-void uiTemplateList(uiLayout *layout, struct PointerRNA *ptr, char *propname, char *activeprop, int items);
+ListBase uiTemplateList(uiLayout *layout, struct PointerRNA *ptr, char *propname, char *activeprop, int rows, int columns, int compact);
 
 /* items */
 void uiItemO(uiLayout *layout, char *name, int icon, char *opname);
@@ -634,6 +634,7 @@ void uiItemR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, cha
 void uiItemFullR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, int value, int expand, int slider, int toggle);
 void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int value);
 void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname);
+void uiItemPointerR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, struct PointerRNA *searchptr, char *searchpropname);
 
 void uiItemL(uiLayout *layout, char *name, int icon); /* label */
 void uiItemM(uiLayout *layout, struct bContext *C, char *name, int icon, char *menuname); /* menu */
index 73425eac0e16e1d4dfd2dbf50065dcfb3c186b6e..3a61237e1cb126f0c99d1da91e2e7fd03c5d3a14 100644 (file)
@@ -80,7 +80,6 @@
  */
 
 static void ui_free_but(const bContext *C, uiBut *but);
-static void ui_rna_ID_autocomplete(bContext *C, char *str, void *arg_but);
 
 /* ************* translation ************** */
 
@@ -1334,61 +1333,6 @@ void ui_get_but_string(uiBut *but, char *str, int maxlen)
        }
 }
 
-static void ui_rna_ID_collection(bContext *C, uiBut *but, PointerRNA *ptr, PropertyRNA **prop)
-{
-       StructRNA *srna;
-
-       /* look for collection property in Main */
-       RNA_pointer_create(NULL, &RNA_Main, CTX_data_main(C), ptr);
-
-       *prop= NULL;
-
-       RNA_STRUCT_BEGIN(ptr, iprop) {
-               /* if it's a collection and has same pointer type, we've got it */
-               if(RNA_property_type(iprop) == PROP_COLLECTION) {
-                       srna= RNA_property_pointer_type(ptr, iprop);
-
-                       if(RNA_property_pointer_type(ptr, but->rnaprop) == srna) {
-                               *prop= iprop;
-                               break;
-                       }
-               }
-       }
-       RNA_STRUCT_END;
-}
-
-/* autocomplete callback for RNA pointers */
-static void ui_rna_ID_autocomplete(bContext *C, char *str, void *arg_but)
-{
-       uiBut *but= arg_but;
-       AutoComplete *autocpl;
-       PointerRNA ptr;
-       PropertyRNA *prop;
-       char *name;
-       
-       if(str[0]==0) return;
-
-       /* get the collection */
-       ui_rna_ID_collection(C, but, &ptr, &prop);
-       if(prop==NULL) return;
-
-       autocpl= autocomplete_begin(str, ui_get_but_string_max_length(but));
-
-       /* loop over items in collection */
-       RNA_PROP_BEGIN(&ptr, itemptr, prop) {
-               name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
-
-               /* test item name */
-               if(name) {
-                       autocomplete_do_name(autocpl, name);
-                       MEM_freeN(name);
-               }
-       }
-       RNA_PROP_END;
-
-       autocomplete_end(autocpl, str);
-}
-
 int ui_set_but_string(bContext *C, uiBut *but, const char *str)
 {
        if(but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
@@ -1407,21 +1351,21 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str)
                                PointerRNA ptr, rptr;
                                PropertyRNA *prop;
 
-                               /* XXX only ID pointers at the moment, needs to support
-                                * custom collection too for bones, vertex groups, .. */
-                               ui_rna_ID_collection(C, but, &ptr, &prop);
-
                                if(str == NULL || str[0] == '\0') {
-                                       memset(&rptr, 0, sizeof(rptr));
-                                       RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr);
+                                       RNA_property_pointer_set(&but->rnapoin, but->rnaprop, PointerRNA_NULL);
                                        return 1;
                                }
-                               else if(prop && RNA_property_collection_lookup_string(&ptr, prop, str, &rptr)) {
-                                       RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr);
+                               else {
+                                       ptr= but->rnasearchpoin;
+                                       prop= but->rnasearchprop;
+                                       
+                                       if(prop && RNA_property_collection_lookup_string(&ptr, prop, str, &rptr))
+                                               RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr);
+
                                        return 1;
                                }
-                               else
-                                       return 0;
+
+                               return 0;
                        }
                }
        }
@@ -2133,7 +2077,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short
                rgb_to_hsv(rgb[0], rgb[1], rgb[2], but->hsv, but->hsv+1, but->hsv+2);
        }
 
-       if((block->flag & UI_BLOCK_LOOP) || ELEM6(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM)) {
+       if((block->flag & UI_BLOCK_LOOP) || ELEM7(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU)) {
                but->flag |= UI_TEXT_LEFT;
        }
        
@@ -2289,10 +2233,6 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1,
                        but->rnaindex= index;
                else
                        but->rnaindex= 0;
-
-               if(type == IDPOIN)
-                       uiButSetCompleteFunc(but, ui_rna_ID_autocomplete, but);
-
        }
 
        if(icon) {
@@ -2408,7 +2348,11 @@ void autocomplete_do_name(AutoComplete *autocpl, const char *name)
                else {
                        /* remove from truncate what is not in bone->name */
                        for(a=0; a<autocpl->maxlen-1; a++) {
-                               if(truncate[a]!=name[a])
+                               if(name[a] == 0) {
+                                       truncate[a]= 0;
+                                       break;
+                               }
+                               else if(truncate[a]!=name[a])
                                        truncate[a]= 0;
                        }
                }
index 2382af53a116fcb9e69531e54f62335be2ec2518..5049fc0b130eb4568a76de511c8f3c889ba4e46b 100644 (file)
@@ -1223,8 +1223,14 @@ static int ui_textedit_autocomplete(bContext *C, uiBut *but, uiHandleButtonData
        int changed= 1;
 
        str= data->str;
-       but->autocomplete_func(C, str, but->autofunc_arg);
+
+       if(data->searchbox)
+               ui_searchbox_autocomplete(C, data->searchbox, but, data->str);
+       else
+               but->autocomplete_func(C, str, but->autofunc_arg);
+
        but->pos= strlen(str);
+       but->selsta= but->selend= but->pos;
 
        return changed;
 }
@@ -1351,14 +1357,14 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
                return;
 
        for(but= actbut->next; but; but= but->next) {
-               if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
+               if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
                        data->postbut= but;
                        data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
                        return;
                }
        }
        for(but= block->buttons.first; but!=actbut; but= but->next) {
-               if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
+               if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
                        data->postbut= but;
                        data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
                        return;
@@ -1375,14 +1381,14 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
                return;
 
        for(but= actbut->prev; but; but= but->prev) {
-               if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
+               if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
                        data->postbut= but;
                        data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
                        return;
                }
        }
        for(but= block->buttons.last; but!=actbut; but= but->prev) {
-               if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
+               if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
                        data->postbut= but;
                        data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
                        return;
@@ -1506,7 +1512,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                                
                        case TABKEY:
                                /* there is a key conflict here, we can't tab with autocomplete */
-                               if(but->autocomplete_func) {
+                               if(but->autocomplete_func || data->searchbox) {
                                        changed= ui_textedit_autocomplete(C, but, data);
                                        retval= WM_UI_HANDLER_BREAK;
                                }
@@ -4103,7 +4109,7 @@ static int ui_handle_menu_return_submenu(bContext *C, wmEvent *event, uiPopupBlo
        uiBlock *block;
        uiHandleButtonData *data;
        uiPopupBlockHandle *submenu;
-       int mx, my;
+       int mx, my, update;
 
        ar= menu->region;
        block= ar->uiblocks.first;
@@ -4121,14 +4127,16 @@ static int ui_handle_menu_return_submenu(bContext *C, wmEvent *event, uiPopupBlo
                                menu->butretval= data->retval;
                        }
                }
-               else if(submenu->menuretval == UI_RETURN_UPDATE)
+
+               update= (submenu->menuretval == UI_RETURN_UPDATE);
+               if(update)
                        menu->menuretval = UI_RETURN_UPDATE;
 
                /* now let activated button in this menu exit, which
                 * will actually close the submenu too */
                ui_handle_button_return_submenu(C, event, but);
 
-               if(submenu->menuretval == UI_RETURN_UPDATE)
+               if(update)
                        submenu->menuretval = 0;
        }
 
index 6b566012525663fe262113040ac617b0c866f943..4d8ec5996beb09729f17184926fcdb1089fdc63d 100644 (file)
@@ -927,7 +927,28 @@ void ui_id_icon_render(Scene *scene, ID *id)
        }
 }
 
+int ui_id_icon_get(Scene *scene, ID *id)
+{
+       int iconid= 0;
+       
+       /* icon */
+       switch(GS(id->name))
+       {
+               case ID_MA: /* fall through */
+               case ID_TE: /* fall through */
+               case ID_IM: /* fall through */
+               case ID_WO: /* fall through */
+               case ID_LA: /* fall through */
+                       iconid= BKE_icon_getid(id);
+                       /* checks if not exists, or changed */
+                       ui_id_icon_render(scene, id);
+                       break;
+               default:
+                       break;
+       }
 
+       return iconid;
+}
 
 static void icon_draw_mipmap(float x, float y, int icon_id, float aspect, int miplevel, int nocreate)
 {
index c27eafd501cddc9af3d872b2e24bc70f9a74e6a2..1b16155c7e6fff68814bfe5fd8a8fbd80e1ebaa7 100644 (file)
@@ -211,6 +211,9 @@ struct uiBut {
        struct PropertyRNA *rnaprop;
        int rnaindex;
 
+       struct PointerRNA rnasearchpoin;
+       struct PropertyRNA *rnasearchprop;
+
        /* Operator data */
        struct wmOperatorType *optype;
        int opcontext;
@@ -371,6 +374,7 @@ void ui_tooltip_free(struct bContext *C, struct ARegion *ar);
 ARegion *ui_searchbox_create(struct bContext *C, struct ARegion *butregion, uiBut *but);
 int ui_searchbox_inside(struct ARegion *ar, int x, int y);
 void ui_searchbox_update(struct bContext *C, struct ARegion *ar, uiBut *but, int reset);
+void ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str);
 void ui_searchbox_event(struct bContext *C, struct ARegion *ar, uiBut *but, struct wmEvent *event);
 void ui_searchbox_apply(uiBut *but, struct ARegion *ar);
 void ui_searchbox_free(struct bContext *C, struct ARegion *ar);
@@ -429,6 +433,7 @@ void uiStyleInit(void);
 
 /* interface_icons.c */
 void ui_id_icon_render(struct Scene *scene, struct ID *id);
+int ui_id_icon_get(struct Scene *scene, struct ID *id);
 
 /* resources.c */
 void init_userdef_do_versions(void);
@@ -437,8 +442,9 @@ void ui_resources_init(void);
 void ui_resources_free(void);
 
 /* interface_layout.c */
-void ui_layout_add_but(struct uiLayout *layout, uiBut *but);
+void ui_layout_add_but(uiLayout *layout, uiBut *but);
 int ui_but_can_align(uiBut *but);
+void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop);
 
 /* interface_anim.c */
 void ui_but_anim_flag(uiBut *but, float cfra);
index 03da6861974d528b40894b6536546ecacc40ac22..94280ec37d36d11aa51f5af12a44360364ae4b14 100644 (file)
@@ -455,9 +455,10 @@ static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr,
 }
 
 /* create label + button for RNA property */
-static void ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int x, int y, int w, int h)
+static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int x, int y, int w, int h)
 {
        uiLayout *sub;
+       uiBut *but;
        PropertySubType subtype;
 
        sub= uiLayoutRow(layout, 0);
@@ -473,12 +474,13 @@ static void ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int
        if(subtype == PROP_FILEPATH || subtype == PROP_DIRPATH) {
                uiBlockSetCurLayout(block, uiLayoutRow(sub, 1));
                uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w-UI_UNIT_X, h);
-               uiDefIconBut(block, BUT, 0, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL, 0.0f, 0.0f, 0.0f, 0.0f, "DUMMY file select button"); /* XXX */
+               but= uiDefIconBut(block, BUT, 0, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL, 0.0f, 0.0f, 0.0f, 0.0f, "DUMMY file select button"); /* XXX */
        }
        else
-               uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w, h);
+               but= uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w, h);
 
        uiBlockSetCurLayout(block, layout);
+       return but;
 }
 
 /********************* Button Items *************************/
@@ -782,8 +784,10 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper
        else if(type == PROP_ENUM && expand)
                ui_item_enum_row(layout, block, ptr, prop, name, 0, 0, w, h);
        /* property with separate label */
-       else if(type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER)
-               ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h);
+       else if(type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) {
+               but= ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h);
+               ui_but_add_search(but, ptr, prop, NULL, NULL);
+       }
        /* single button */
        else {
                but= uiDefAutoButR(block, ptr, prop, index, (char*)name, icon, 0, 0, w, h);
@@ -854,6 +858,142 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname)
        }
 }
 
+/* Pointer RNA button with search */
+
+static void rna_search_cb(const struct bContext *C, void *arg_but, char *str, uiSearchItems *items)
+{
+       Scene *scene= CTX_data_scene(C);
+       uiBut *but= arg_but;
+       char *name;
+       int i, iconid;
+
+       i = 0;
+       RNA_PROP_BEGIN(&but->rnasearchpoin, itemptr, but->rnasearchprop) {
+               iconid= 0;
+               if(RNA_struct_is_ID(itemptr.type))
+                       iconid= ui_id_icon_get(scene, itemptr.data);
+
+               name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+
+               if(name) {
+                       if(BLI_strcasestr(name, str)) {
+                               if(!uiSearchItemAdd(items, name, SET_INT_IN_POINTER(i), iconid)) {
+                                       MEM_freeN(name);
+                                       break;
+                               }
+                       }
+
+                       MEM_freeN(name);
+               }
+
+               i++;
+       }
+       RNA_PROP_END;
+}
+
+static void search_id_collection(StructRNA *ptype, PointerRNA *ptr, PropertyRNA **prop)
+{
+       StructRNA *srna;
+
+       /* look for collection property in Main */
+       RNA_main_pointer_create(G.main, ptr);
+
+       *prop= NULL;
+
+       RNA_STRUCT_BEGIN(ptr, iprop) {
+               /* if it's a collection and has same pointer type, we've got it */
+               if(RNA_property_type(iprop) == PROP_COLLECTION) {
+                       srna= RNA_property_pointer_type(ptr, iprop);
+
+                       if(ptype == srna) {
+                               *prop= iprop;
+                               break;
+                       }
+               }
+       }
+       RNA_STRUCT_END;
+}
+
+void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop)
+{
+       StructRNA *ptype;
+       PointerRNA sptr;
+
+       /* for ID's we do automatic lookup */
+       if(!searchprop) {
+               if(RNA_property_type(prop) == PROP_POINTER) {
+                       ptype= RNA_property_pointer_type(ptr, prop);
+                       search_id_collection(ptype, &sptr, &searchprop);
+                       searchptr= &sptr;
+               }
+       }
+
+       /* turn button into search button */
+       if(searchprop) {
+               but->type= SEARCH_MENU;
+               but->hardmax= MAX2(but->hardmax, 256);
+               but->rnasearchpoin= *searchptr;
+               but->rnasearchprop= searchprop;
+               but->flag |= UI_ICON_LEFT|UI_TEXT_LEFT;
+
+               uiButSetSearchFunc(but, rna_search_cb, but, NULL);
+       }
+}
+
+void uiItemPointerR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, struct PointerRNA *searchptr, char *searchpropname)
+{
+       PropertyRNA *prop, *searchprop;
+       PropertyType type;
+       uiBut *but;
+       uiBlock *block;
+       StructRNA *icontype;
+       int w, h;
+       
+       /* validate arguments */
+       if(!ptr->data || !searchptr->data)
+               return;
+
+       prop= RNA_struct_find_property(ptr, propname);
+
+       if(!prop) {
+               printf("uiItemPointerR: property not found: %s\n", propname);
+               return;
+       }
+       
+       type= RNA_property_type(prop);
+       if(!ELEM(type, PROP_POINTER, PROP_STRING)) {
+               printf("uiItemPointerR: property %s must be a pointer or string.\n", propname);
+               return;
+       }
+
+       searchprop= RNA_struct_find_property(searchptr, searchpropname);
+
+       if(!searchprop || RNA_property_type(searchprop) != PROP_COLLECTION) {
+               printf("uiItemPointerR: search collection property not found: %s\n", searchpropname);
+               return;
+       }
+
+       /* get icon & name */
+       if(!icon) {
+               if(type == PROP_POINTER)
+                       icontype= RNA_property_pointer_type(ptr, prop);
+               else
+                       icontype= RNA_property_pointer_type(searchptr, searchprop);
+
+               icon= RNA_struct_ui_icon(icontype);
+       }
+       if(!name)
+               name= (char*)RNA_property_ui_name(prop);
+
+       /* create button */
+       block= uiLayoutGetBlock(layout);
+
+       ui_item_rna_size(layout, name, icon, prop, 0, &w, &h);
+       but= ui_item_with_label(layout, block, name, icon, ptr, prop, 0, 0, 0, w, h);
+
+       ui_but_add_search(but, ptr, prop, searchptr, searchprop);
+}
+
 /* menu item */
 static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
 {
index a1dae39d68768bd34e957654cfebafeb6cdbe945..61cf612e912354452e3da535057fb28d4db3ef52 100644 (file)
@@ -435,6 +435,8 @@ struct uiSearchItems {
        char **names;
        void **pointers;
        int *icons;
+
+       AutoComplete *autocpl;
 };
 
 typedef struct uiSearchboxData {
@@ -451,6 +453,11 @@ typedef struct uiSearchboxData {
 /* returns zero if nothing to add */
 int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int iconid)
 {
+       /* hijack for autocomplete */
+       if(items->autocpl) {
+               autocomplete_do_name(items->autocpl, name);
+               return 1;
+       }
        
        if(items->totitem>=items->maxitem) {
                items->more= 1;
@@ -622,6 +629,18 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, int reset)
        ED_region_tag_redraw(ar);
 }
 
+void ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str)
+{
+       uiSearchboxData *data= ar->regiondata;
+
+       data->items.autocpl= autocomplete_begin(str, ui_get_but_string_max_length(but));
+
+       but->search_func(C, but->search_arg, but->editstr, &data->items);
+
+       autocomplete_end(data->items.autocpl, str);
+       data->items.autocpl= NULL;
+}
+
 static void ui_searchbox_region_draw(const bContext *C, ARegion *ar)
 {
        uiSearchboxData *data= ar->regiondata;
@@ -683,7 +702,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
        uiSearchboxData *data;
        float aspect= but->block->aspect;
        float x1f, x2f, y1f, y2f;
-       int x1, x2, y1, y2, winx, winy;
+       int x1, x2, y1, y2, winx, winy, ofsx, ofsy;
        
        /* create area region */
        ar= ui_add_temporary_region(CTX_wm_screen(C));
@@ -736,6 +755,14 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
                x2f= but->x2 + 5;       /* symmetrical */
                y2f= but->y1;
                y1f= y2f - uiSearchBoxhHeight();
+
+               ofsx= (but->block->panel)? but->block->panel->ofsx: 0;
+               ofsy= (but->block->panel)? but->block->panel->ofsy: 0;
+
+               x1f += ofsx;
+               x2f += ofsx;
+               y1f += ofsy;
+               y2f += ofsy;
        
                /* minimal width */
                if(x2f - x1f < 150) x2f= x1f+150; // XXX arbitrary
index 37b2a4af84e219e2e76fc7a9eadb1247b3f040fa..a006187c4aa78f5d92a06e8be9605b286ba459c5 100644 (file)
 
 #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"
 
@@ -62,121 +64,51 @@ void uiTemplateHeader(uiLayout *layout, bContext *C)
        ED_area_header_standardbuttons(C, block, 0);
 }
 
-/******************* Header ID Template ************************/
+/********************** Search Callbacks *************************/
 
 typedef struct TemplateID {
        PointerRNA ptr;
        PropertyRNA *prop;
 
-       int flag;
-       short browse;
-
-       char newop[256];
-       char openop[256];
-       char unlinkop[256];
-       
-       short idtype;
+       ListBase *idlb;
 } TemplateID;
 
-static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
+/* Search browse menu, assign  */
+static void id_search_call_cb(struct bContext *C, void *arg_template, void *item)
 {
-       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);
-       
-       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;
 
-       switch(event) {
-               case UI_ID_BROWSE:
-                       printf("warning, id browse shouldnt come here\n");
-                       break;
-               case UI_ID_DELETE:
-                       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) {
-                               if(id->flag & LIB_FAKEUSER) id->us++;
-                               else id->us--;
-                       }
-                       else return;
-                       break;
-               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)
-                               return;
-                       break;
-               case UI_ID_LOCAL:
-                       if(!id || id->us < 1)
-                               return;
-                       break;
-               case UI_ID_AUTO_NAME:
-                       break;
-#endif
-       }
-}
-
-/* ID Search browse menu, assign  */
-static void id_search_call_cb(struct bContext *C, void *arg_litem, void *item)
-{
+       /* ID */
        if(item) {
-               TemplateID *template= (TemplateID*)arg_litem;
-               PointerRNA idptr= RNA_property_pointer_get(&template->ptr, template->prop);
+               PointerRNA idptr;
 
                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_litem, char *str, uiSearchItems *items)
+static void id_search_cb(const struct bContext *C, void *arg_template, char *str, uiSearchItems *items)
 {
-       TemplateID *template= (TemplateID*)arg_litem;
-       ListBase *lb= wich_libbase(CTX_data_main(C), template->idtype);
+       TemplateID *template= (TemplateID*)arg_template;
+       Scene *scene= CTX_data_scene(C);
+       ListBase *lb= template->idlb;
        ID *id;
-       
+       int iconid;
+
+       /* ID listbase */
        for(id= lb->first; id; id= id->next) {
-               int iconid= 0;
-               
-               /* icon */
-               switch(GS(id->name))
-               {
-                       case ID_MA: /* fall through */
-                       case ID_TE: /* fall through */
-                       case ID_IM: /* fall through */
-                       case ID_WO: /* fall through */
-                       case ID_LA: /* fall through */
-                               iconid= BKE_icon_getid(id);
-                               /* checks if not exists, or changed */
-                               ui_id_icon_render(CTX_data_scene(C), id);
-                               break;
-                       default:
-                               break;
-               }
-               
-               if(BLI_strcasestr(id->name+2, str)) {
-                       if(0==uiSearchItemAdd(items, id->name+2, id, iconid))
+               iconid= ui_id_icon_get(scene, id);
+
+               if(BLI_strcasestr(id->name+2, str))
+                       if(!uiSearchItemAdd(items, id->name+2, id, iconid))
                                break;
-               }
        }
 }
 
 /* ID Search browse menu, open */
-static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
+static uiBlock *search_menu(bContext *C, ARegion *ar, void *arg_litem)
 {
        static char search[256];
        static TemplateID template;
@@ -213,17 +145,57 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
        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:
+               case UI_ID_OPEN:
+               case UI_ID_ADD_NEW:
+                       printf("warning, id event %d shouldnt come here\n", event);
+                       break;
+               case UI_ID_DELETE:
+                       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) {
+                               if(id->flag & LIB_FAKEUSER) id->us++;
+                               else id->us--;
+                       }
+                       else return;
+                       break;
+#if 0
+               case UI_ID_ALONE:
+                       if(!id || id->us < 1)
+                               return;
+                       break;
+               case UI_ID_LOCAL:
+                       if(!id || id->us < 1)
+                               return;
+                       break;
+               case UI_ID_AUTO_NAME:
+                       break;
+#endif
+       }
+}
 
-static void template_header_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type)
+static void template_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type, int flag, char *newop, char *unlinkop)
 {
        uiBut *but;
        PointerRNA idptr;
        ListBase *lb;
 
        idptr= RNA_property_pointer_get(&template->ptr, template->prop);
-       lb= wich_libbase(CTX_data_main(C), template->idtype);
+       lb= template->idlb;
 
        if(idptr.type)
                type= idptr.type;
@@ -231,29 +203,8 @@ static void template_header_ID(bContext *C, uiBlock *block, TemplateID *template
                uiDefIconBut(block, LABEL, 0, RNA_struct_ui_icon(type), 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
 
        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);
-
-               but= uiDefButS(block, MENU, 0, str, 0, 0, UI_UNIT_X, UI_UNIT_Y, &duptemplate->browse, 0, 0, 0, 0, "Browse existing choices, or add new");
-               uiButSetNFunc(but, template_id_cb, duptemplate, SET_INT_IN_POINTER(UI_ID_BROWSE));
-       
-               MEM_freeN(str);
-               */
-               uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Browse ID data");
-       }
+       if(flag & UI_ID_BROWSE)
+               uiDefBlockButN(block, search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Browse ID data");
 
        /* text button with name */
        if(idptr.data) {
@@ -265,11 +216,11 @@ static void template_header_ID(bContext *C, uiBlock *block, TemplateID *template
                uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
        }
        
-       if(template->flag & UI_ID_ADD_NEW) {
+       if(flag & UI_ID_ADD_NEW) {
                int w= idptr.data?UI_UNIT_X:UI_UNIT_X*6;
                
-               if(template->newop[0]) {
-                       but= uiDefIconTextButO(block, BUT, template->newop, WM_OP_EXEC_REGION_WIN, ICON_ZOOMIN, "Add New", 0, 0, w, UI_UNIT_Y, NULL);
+               if(newop) {
+                       but= uiDefIconTextButO(block, BUT, newop, WM_OP_EXEC_REGION_WIN, ICON_ZOOMIN, "Add New", 0, 0, w, UI_UNIT_Y, NULL);
                }
                else {
                        but= uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, "Add New", 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
@@ -278,9 +229,9 @@ static void template_header_ID(bContext *C, uiBlock *block, TemplateID *template
        }
        
        /* delete button */
-       if(idptr.data && (template->flag & UI_ID_DELETE)) {
-               if(template->unlinkop[0]) {
-                       but= uiDefIconButO(block, BUT, template->unlinkop, WM_OP_EXEC_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
+       if(idptr.data && (flag & UI_ID_DELETE)) {
+               if(unlinkop) {
+                       but= uiDefIconButO(block, BUT, unlinkop, WM_OP_EXEC_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);
@@ -291,12 +242,13 @@ static void template_header_ID(bContext *C, uiBlock *block, TemplateID *template
        uiBlockEndAlign(block);
 }
 
-void uiTemplateID(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)
 {
        TemplateID *template;
        uiBlock *block;
        PropertyRNA *prop;
        StructRNA *type;
+       int flag;
 
        if(!ptr->data)
                return;
@@ -311,26 +263,19 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname
        template= MEM_callocN(sizeof(TemplateID), "TemplateID");
        template->ptr= *ptr;
        template->prop= prop;
-       template->flag= UI_ID_BROWSE|UI_ID_RENAME|UI_ID_DELETE;
 
-       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)
-               BLI_strncpy(template->unlinkop, unlinkop, sizeof(template->unlinkop));
+       flag= UI_ID_BROWSE|UI_ID_RENAME|UI_ID_DELETE;
+
+       if(newop)
+               flag |= UI_ID_ADD_NEW;
 
        type= RNA_property_pointer_type(ptr, prop);
-       template->idtype = RNA_type_to_ID_code(type);
+       template->idlb= wich_libbase(CTX_data_main(C), RNA_type_to_ID_code(type));
 
-       if(template->idtype) {
+       if(template->idlb) {
                uiLayoutRow(layout, 1);
                block= uiLayoutGetBlock(layout);
-               template_header_ID(C, block, template, type);
+               template_ID(C, block, template, type, flag, newop, unlinkop);
        }
 
        MEM_freeN(template);
@@ -1529,6 +1474,7 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, char *propname)
 
 /************************* List Template **************************/
 
+#if 0
 typedef struct ListItem {
        PointerRNA ptr;
        PropertyRNA *prop;
@@ -1560,50 +1506,52 @@ static void list_item_cb(bContext *C, void *arg_item, void *arg_unused)
                }
        }
 }
+#endif
 
-void uiTemplateList(uiLayout *layout, PointerRNA *ptr, char *propname, char *activepropname, int items)
+ListBase uiTemplateList(uiLayout *layout, PointerRNA *ptr, char *propname, char *activepropname, int rows, int columns, int compact)
 {
+       CollectionPointerLink *link;
        PropertyRNA *prop, *activeprop;
        PropertyType type, activetype;
        PointerRNA activeptr;
        uiLayout *box, *row, *col;
        uiBlock *block;
        uiBut *but;
-       char *name, *activename= NULL;
-       int i= 1, activei= 0, len;
+       ListBase lb;
+       char *name, *activename= NULL, str[32];
+       int i= 1, activei= 0, len, items, found;
        static int scroll = 1;
+
+       lb.first= lb.last= NULL;
        
        /* validate arguments */
        if(!ptr->data)
-               return;
+               return lb;
        
        prop= RNA_struct_find_property(ptr, propname);
        if(!prop) {
                printf("uiTemplateList: property not found: %s\n", propname);
-               return;
+               return lb;
        }
 
        activeprop= RNA_struct_find_property(ptr, activepropname);
        if(!activeprop) {
                printf("uiTemplateList: property not found: %s\n", activepropname);
-               return;
+               return lb;
        }
 
        type= RNA_property_type(prop);
        if(type != PROP_COLLECTION) {
                printf("uiTemplateList: expected collection property.\n");
-               return;
+               return lb;
        }
 
        activetype= RNA_property_type(activeprop);
        if(!ELEM3(activetype, PROP_POINTER, PROP_INT, PROP_STRING)) {
                printf("uiTemplateList: expected pointer, integer or string property.\n");
-               return;
+               return lb;
        }
 
-       if(items == 0)
-               items= 5;
-
        /* get active data */
        if(activetype == PROP_POINTER)
                activeptr= RNA_property_pointer_get(ptr, activeprop);
@@ -1612,62 +1560,119 @@ void uiTemplateList(uiLayout *layout, PointerRNA *ptr, char *propname, char *act
        else if(activetype == PROP_STRING)
                activename= RNA_property_string_get_alloc(ptr, activeprop, NULL, 0);
 
-       box= uiLayoutBox(layout);
-       row= uiLayoutRow(box, 0);
-       col = uiLayoutColumn(row, 1);
+       block= uiLayoutGetBlock(layout);
 
-       block= uiLayoutGetBlock(col);
-       uiBlockSetEmboss(block, UI_EMBOSSN);
+       if(compact) {
+               /* compact layout */
+               found= 0;
+
+               row= uiLayoutRow(layout, 1);
+
+               RNA_PROP_BEGIN(ptr, itemptr, prop) {
+                       if(activetype == PROP_POINTER)
+                               found= (activeptr.data == itemptr.data);
+                       else if(activetype == PROP_INT)
+                               found= (activei == i);
+                       else if(activetype == PROP_STRING)
+                               found= (strcmp(activename, name) == 0);
+
+                       if(found) {
+                               name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+                               if(name) {
+                                       uiItemL(row, name, RNA_struct_ui_icon(itemptr.type));
+                                       MEM_freeN(name);
+                               }
+
+                               link= MEM_callocN(sizeof(CollectionPointerLink), "uiTemplateList return");
+                               link->ptr= itemptr;
+                               BLI_addtail(&lb, link);
+                       }
+
+                       i++;
+               }
+               RNA_PROP_END;
 
-       len= RNA_property_collection_length(ptr, prop);
-       scroll= MIN2(scroll, len-items+1);
-       scroll= MAX2(scroll, 1);
+               if(i == 1)
+                       uiItemL(row, "", 0);
 
-       RNA_PROP_BEGIN(ptr, itemptr, prop) {
-               if(i >= scroll && i<scroll+items) {
-                       name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+               sprintf(str, "%d :", i-1);
+               but= uiDefIconTextButR(block, NUM, 0, 0, str, 0,0,UI_UNIT_X*5,UI_UNIT_Y, ptr, activepropname, 0, 0, 0, 0, 0, "");
+               if(i == 1)
+                       uiButSetFlag(but, UI_BUT_DISABLED);
+       }
+       else {
+               if(rows == 0)
+                       rows= 5;
+               if(columns == 0)
+                       columns= 1;
 
-                       if(name) {
-                               ListItem *item= MEM_callocN(sizeof(ListItem), "uiTemplateList ListItem");
+               items= rows*columns;
 
-                               item->ptr= *ptr;
-                               item->prop= prop;
-                               item->activeprop= activeprop;
-                               item->activeptr= itemptr;
-                               item->activei= i;
+               box= uiLayoutBox(layout);
+               row= uiLayoutRow(box, 0);
+               col = uiLayoutColumn(row, 1);
+
+               uiBlockSetEmboss(block, UI_EMBOSSN);
+
+               len= RNA_property_collection_length(ptr, prop);
+               scroll= MIN2(scroll, len-items+1);
+               scroll= MAX2(scroll, 1);
+
+               RNA_PROP_BEGIN(ptr, itemptr, prop) {
+                       if(i >= scroll && i<scroll+items) {
+                               name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+
+                               if(name) {
+#if 0
+                                       ListItem *item= MEM_callocN(sizeof(ListItem), "uiTemplateList ListItem");
+
+                                       item->ptr= *ptr;
+                                       item->prop= prop;
+                                       item->activeprop= activeprop;
+                                       item->activeptr= itemptr;
+                                       item->activei= i;
+
+                                       if(activetype == PROP_POINTER)
+                                               item->selected= (activeptr.data == itemptr.data)? i: -1;
+                                       else if(activetype == PROP_INT)
+                                               item->selected= (activei == i)? i: -1;
+                                       else if(activetype == PROP_STRING)
+                                               item->selected= (strcmp(activename, name) == 0)? i: -1;
+#endif
 
-                               if(activetype == PROP_POINTER)
-                                       item->selected= (activeptr.data == itemptr.data)? i: -1;
-                               else if(activetype == PROP_INT)
-                                       item->selected= (activei == i)? i: -1;
-                               else if(activetype == PROP_STRING)
-                                       item->selected= (strcmp(activename, name) == 0)? i: -1;
+                                       //but= uiDefIconTextButI(block, ROW, 0, RNA_struct_ui_icon(itemptr.type), name, 0,0,UI_UNIT_X*10,UI_UNIT_Y, &item->selected, 0, i, 0, 0, "");
+                                       but= uiDefIconTextButR(block, ROW, 0, RNA_struct_ui_icon(itemptr.type), name, 0,0,UI_UNIT_X*10,UI_UNIT_Y, ptr, activepropname, 0/*&item->selected*/, 0, i, 0, 0, "");
+                                       uiButSetFlag(but, UI_ICON_LEFT|UI_TEXT_LEFT);
+                                       //uiButSetNFunc(but, list_item_cb, item, NULL);
 
-                               but= uiDefIconTextButI(block, ROW, 0, RNA_struct_ui_icon(itemptr.type), name, 0,0,UI_UNIT_X*10,UI_UNIT_Y, &item->selected, 0, i, 0, 0, "");
-                               uiButSetFlag(but, UI_ICON_LEFT|UI_TEXT_LEFT);
-                               uiButSetNFunc(but, list_item_cb, item, NULL);
+                                       MEM_freeN(name);
 
-                               MEM_freeN(name);
+                                       link= MEM_callocN(sizeof(CollectionPointerLink), "uiTemplateList return");
+                                       link->ptr= itemptr;
+                                       BLI_addtail(&lb, link);
+                               }
                        }
+
+                       i++;
                }
+               RNA_PROP_END;
 
-               i++;
-       }
-       RNA_PROP_END;
+               while(i < scroll+items) {
+                       if(i >= scroll)
+                               uiItemL(col, "", 0);
+                       i++;
+               }
 
-       while(i < scroll+items) {
-               if(i >= scroll)
-                       uiItemL(col, "", 0);
-               i++;
-       }
+               uiBlockSetEmboss(block, UI_EMBOSS);
 
-       uiBlockSetEmboss(block, UI_EMBOSS);
+               if(len > items) {
+                       col= uiLayoutColumn(row, 0);
+                       uiDefButI(block, SCROLL, 0, "", 0,0,UI_UNIT_X*0.75,UI_UNIT_Y*items, &scroll, 1, len-items+1, items, 0, "");
+               }
 
-       if(len > items) {
-               col= uiLayoutColumn(row, 0);
-               uiDefButI(block, SCROLL, 0, "", 0,0,UI_UNIT_X*0.75,UI_UNIT_Y*items, &scroll, 1, len-items+1, items, 0, "");
+               //uiDefButI(block, SCROLL, 0, "", 0,0,UI_UNIT_X*15,UI_UNIT_Y*0.75, &scroll, 1, 16-5, 5, 0, "");
        }
 
-       //uiDefButI(block, SCROLL, 0, "", 0,0,UI_UNIT_X*15,UI_UNIT_Y*0.75, &scroll, 1, 16-5, 5, 0, "");
+       return lb;
 }
 
index e67e5b5a871dd94d771f43cc7cf58cbd715ea748..3ed81a3e9bcd9288d8a831fff469bb6518ddda8d 100644 (file)
@@ -111,7 +111,12 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
                        but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
                        break;
                case PROP_STRING:
-                       but= uiDefButR(block, TEX, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+                       if(icon && name && strcmp(name, "") == 0)
+                               but= uiDefIconButR(block, TEX, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+                       else if(icon)
+                               but= uiDefIconTextButR(block, TEX, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+                       else
+                               but= uiDefButR(block, TEX, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
                        break;
                case PROP_POINTER: {
                        PointerRNA pptr;
index 75de9d5376649d1ac36ce7d8b8b9c010dd0244c6..a4aa60775f2c658ccd72c65ad3d612ae06195079 100644 (file)
@@ -136,6 +136,14 @@ void RNA_api_ui_layout(StructRNA *srna)
        parm= RNA_def_string(func, "value", "", 0, "", "Enum property value.");
        RNA_def_property_flag(parm, PROP_REQUIRED);*/
 
+       func= RNA_def_function(srna, "item_pointerR", "uiItemPointerR");
+       api_ui_item_common(func);
+       api_ui_item_rna_common(func);
+       parm= RNA_def_pointer(func, "search_data", "AnyType", "", "Data from which to take collection to search in.");
+       RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR);
+       parm= RNA_def_string(func, "search_property", "", 0, "", "Identifier of search collection property.");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+
        func= RNA_def_function(srna, "itemO", "uiItemO");
        api_ui_item_op_common(func);
 
@@ -211,7 +219,6 @@ void RNA_api_ui_layout(StructRNA *srna)
        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 new ID block.");
        RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block.");
 
        func= RNA_def_function(srna, "template_modifier", "uiTemplateModifier");
@@ -252,9 +259,13 @@ void RNA_api_ui_layout(StructRNA *srna)
 
        func= RNA_def_function(srna, "template_list", "uiTemplateList");
        api_ui_item_rna_common(func);
-       parm= RNA_def_string(func, "active_property", "", 0, "", "Identifier of property in data, indicating the active element.");
+       parm= RNA_def_string(func, "active_property", "", 0, "", "Identifier of property in data, for the active element.");
        RNA_def_property_flag(parm, PROP_REQUIRED);
-       parm= RNA_def_int(func, "items", 5, 0, INT_MAX, "", "Number of items to display.", 0, INT_MAX);
+       parm= RNA_def_int(func, "rows", 5, 0, INT_MAX, "", "Number of rows to display.", 0, INT_MAX);
+       parm= RNA_def_int(func, "columns", 5, 0, INT_MAX, "", "Number of columns to display.", 0, INT_MAX);
+       parm= RNA_def_boolean(func, "compact", 0, "", "Use compact, single row list template.");
+       parm= RNA_def_collection(func, "items", 0, "", "Items visible in the list.");
+       RNA_def_function_return(func, parm);
 }
 
 #endif