Outliner features:
authorTon Roosendaal <ton@blender.org>
Mon, 11 Oct 2004 11:54:14 +0000 (11:54 +0000)
committerTon Roosendaal <ton@blender.org>
Mon, 11 Oct 2004 11:54:14 +0000 (11:54 +0000)
- Rename!
CTRL+leftmouse click on name, makes it a text button. Works for all items as
currently being displayed.
Most work was doing the Bones, which is a nightmare :) But it uses same
code as buttons in Armature-Editmode now, without even needing EditMode :)
When renaming a bone, the Outliner makes the Object active though.

- PageUp / PageDown keys
Do what you expect.

source/blender/include/BIF_butspace.h
source/blender/include/BIF_outliner.h
source/blender/include/mydevice.h
source/blender/makesdna/DNA_oops_types.h
source/blender/src/buttons_editing.c
source/blender/src/interface.c
source/blender/src/interface_draw.c
source/blender/src/outliner.c
source/blender/src/space.c

index 9f5d4034b8b76f223184d67d5b47549ed067baa7..437e0a2791d733d6d9e444bc35440559134fb42e 100644 (file)
@@ -42,6 +42,10 @@ struct ID;
 extern void do_butspace(unsigned short event);
 extern void redraw_test_buttons(struct Object *new);
 
+/* buttons_editing.c */
+extern void rename_bone_ext(char *oldname, char *newname);
+
+
 /* buts->mainb old */
 #define BUTS_VIEW                      0
 #define BUTS_LAMP                      1
index ec44e9aa3f432d074cdcee0145caf662e3e6f7e9..af1c249e25a6bb9fc9eb9fb097a18c8427c03c22 100644 (file)
@@ -52,16 +52,19 @@ typedef struct TreeElement {
 #define TE_ICONROW     2
 
 /* TreeStoreElem types */
-#define TE_NLA                         1
-#define TE_NLA_ACTION          2
-#define TE_DEFGROUP_BASE       3
-#define TE_DEFGROUP                    4
-#define TE_BONE                                5
-#define TE_CONSTRAINT_BASE     6
-#define TE_CONSTRAINT          7
-#define TE_HOOKS_BASE          8
-#define TE_HOOK                                9
-#define TE_SCRIPT_BASE         10
+#define TSE_NLA                                1
+#define TSE_NLA_ACTION         2
+#define TSE_DEFGROUP_BASE      3
+#define TSE_DEFGROUP                   4
+#define TSE_BONE                               5
+#define TSE_CONSTRAINT_BASE    6
+#define TSE_CONSTRAINT         7
+#define TSE_HOOKS_BASE         8
+#define TSE_HOOK                               9
+#define TSE_SCRIPT_BASE                10
+
+/* button events */
+#define OL_NAMEBUTTON          1
 
 extern void draw_outliner(struct ScrArea *sa, struct SpaceOops *so);
 extern void outliner_free_tree(struct ListBase *lb);
@@ -73,6 +76,7 @@ extern void outliner_one_level(struct ScrArea *sa, int add);
 extern void outliner_select(struct ScrArea *sa);
 extern void outliner_toggle_selected(struct ScrArea *sa);
 extern void outliner_operation_menu(struct ScrArea *sa);
+extern void outliner_page_up_down(struct ScrArea *sa, int up);
 
 #endif
 
index e4ede3a7578fdfbf443aa9ec4cca04b85d1eefb6..1a8c2daeba53cbd83dddfefbac29025260c313b7 100644 (file)
 #define UNKNOWNKEY     171
 #define COMMANDKEY     172
 
+/* used as fake leftmouse event, special handled in interface.c */
+#define BUT_ACTIVATE   200
+
 /* **************** BLENDER QUEUE EVENTS ********************* */
 
 #define CHANGED                                0x4000
index 6b4ed9a3128fa49923f93a3cf26ec61f6cc8df7a..0f49ed23b4707746d8b57a7238809ea2d65a4c16 100644 (file)
@@ -78,6 +78,7 @@ typedef struct OopsLink {
 /* TreeStoreElem->flag */
 #define TSE_CLOSED             1
 #define TSE_SELECTED   2
+#define TSE_TEXTBUT            4
 
 /* TreeStoreElem types in BIF_outliner.h */
 
index 30c1d5da8cd2adbec824b0df85ff3b81581bb2e2..94e074dfe3fd2b1e9e8e03547760ae68296cf234 100644 (file)
@@ -1683,6 +1683,36 @@ static void validate_editbonebutton_cb(void *bonev, void *arg2_unused)
        validate_editbonebutton(curBone);
 }
 
+/* called from outliner now, can be used for buttons in posemode too */
+/* current Armature should be active Object */
+/* after this function, the Bones in Armature are re-allocced! */
+void rename_bone_ext(char *oldname, char *newname)
+{
+       EditBone *ebone;
+       int temp_editmode= 0;
+
+       /* since the naming functions work only on editArmature, we have to... */
+       if(G.obedit!=OBACT) exit_editmode(2);
+       if(G.obedit==NULL) {
+               G.obedit= OBACT;
+               make_editArmature();
+               temp_editmode= 1;
+       }
+       
+       /* now find the eBone with oldname */
+       for(ebone= G.edbo.first; ebone; ebone= ebone->next)
+               if(strcmp(ebone->name, oldname)==0) break;
+
+       if(ebone) {
+               strcpy(ebone->oldname, oldname);
+               strcpy(ebone->name, newname);
+               validate_editbonebutton(ebone); // does exit_editmode... tsk, so armature bones pointers are invalid now
+       }
+       if(temp_editmode) exit_editmode(2);
+       
+}
+
+
 static void armature_rest_pos_func(void *notused1, void *notused2) 
 {
        clear_object_constraint_status(OBACT);
index e546d09f7defb7434029695c69d235f9db7f2581..e36495ac5963bd562279c10009db265e774cf3fe 100644 (file)
@@ -1321,13 +1321,13 @@ static int ui_do_but_TEX(uiBut *but)
 
                if(ascii) {
                        if(len < but->max) {
-                                       for(x= but->max; x>but->pos; x--)
-                                               str[x]= str[x-1];
-                                       str[but->pos]= ascii;
-                                       but->pos++; 
-                                       len++;
-                                       str[len]= '\0';
-                                       dodraw= 1;
+                               for(x= but->max; x>but->pos; x--)
+                                       str[x]= str[x-1];
+                               str[but->pos]= ascii;
+                               but->pos++; 
+                               len++;
+                               str[len]= '\0';
+                               dodraw= 1;
                        }
                }
                else if(val) {
@@ -3027,9 +3027,7 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
                        }
                        if(event && uevent->val) {
        
-                               but= block->buttons.first;
-                               while(but) {
-                                       
+                               for(but= block->buttons.first; but; but= but->next) {
                                        but->flag &= ~UI_MOUSE_OVER;
                
                                        if(but->flag & UI_ACTIVE) {
@@ -3051,7 +3049,6 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
                                                        break;
                                                }
                                        }
-                                       but= but->next;
                                }
        
                                /* nothing done */
@@ -3090,9 +3087,8 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
                        
                        if(get_qual() & LR_ALTKEY) act+= 10;
                        
-                       but= block->buttons.first;
                        count= 0;
-                       while(but) {
+                       for(but= block->buttons.first; but; but= but->next) {
                                int doit= 0;
                                
                                if(but->type!=LABEL && but->type!=SEPR) count++;
@@ -3118,16 +3114,17 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
                                        but->flag &= ~UI_ACTIVE;
                                        ui_draw_but(but);
                                }
-                               but= but->next;
                        }
                }
-               
                break;
-               
+       case BUT_ACTIVATE:
+               for(but= block->buttons.first; but; but= but->next) {
+                       if(but->retval==uevent->val) but->flag |= UI_ACTIVE;
+               }
+               break;
        default:
 
-               but= block->buttons.first;
-               while(but) {
+               for(but= block->buttons.first; but; but= but->next) {
                
                        but->flag &= ~UI_MOUSE_OVER;
                        
@@ -3173,8 +3170,6 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
                                }
                                if(but->flag & UI_ACTIVE) active= 1;
                        }
-                       
-                       but= but->next;
                }
                
                /* if there are no active buttons... otherwise clear lines */
@@ -3187,14 +3182,13 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
        if( (block->flag & UI_BLOCK_LOOP) && uevent->event==MIDDLEMOUSE) uevent->event= LEFTMOUSE;
 
        /* the final dobutton */
-       but= block->buttons.first;
-       while(but) {
+       for(but= block->buttons.first; but; but= but->next) {
                if(but->flag & UI_ACTIVE) {
                        
                        /* UI_BLOCK_RET_1: not return when val==0 */
                        
                        if(uevent->val || (block->flag & UI_BLOCK_RET_1)==0) {
-                               if ELEM3(uevent->event, LEFTMOUSE, PADENTER, RETKEY) {
+                               if ELEM4(uevent->event, LEFTMOUSE, PADENTER, RETKEY, BUT_ACTIVATE) {
                                        /* when mouse outside, don't do button */
                                        if(inside || uevent->event!=LEFTMOUSE) {
                                                butevent= ui_do_button(block, but, uevent);
@@ -3216,8 +3210,6 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
                                }
                        }
                }
-               
-               but= but->next;
        }
 
        /* flush to frontbuffer */
index 12cd21c957bfa9ef5ce353cf333a10623eca272c..dcd96aa69149dc10b8a79730258c13a4b7308694 100644 (file)
@@ -1421,7 +1421,7 @@ static void ui_draw_text_icon(uiBut *but)
        if (but->type == ICONTEXTROW) {
                ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd));
        }
-       else if(but->drawstr[0]!=0) {
+       else {
 
                // text button cursor
                if(but->pos != -1) {
@@ -1429,86 +1429,90 @@ static void ui_draw_text_icon(uiBut *but)
                        
                        pos= but->pos+strlen(but->str);
                        if(pos >= but->ofs) {
-                               ch= but->drawstr[pos];
-                               but->drawstr[pos]= 0;
-       
-                               t= but->aspect*BIF_GetStringWidth(but->font, but->drawstr+but->ofs, (U.transopts & USER_TR_BUTTONS)) + 3;
-       
-                               but->drawstr[pos]= ch;
+                               if(but->drawstr[0]!=0) {
+                                       ch= but->drawstr[pos];
+                                       but->drawstr[pos]= 0;
+               
+                                       t= but->aspect*BIF_GetStringWidth(but->font, but->drawstr+but->ofs, (U.transopts & USER_TR_BUTTONS)) + 3;
+               
+                                       but->drawstr[pos]= ch;
+                               }
+                               else t= 3;
+                               
                                glColor3ub(255,0,0);
-       
                                glRects(but->x1+t, but->y1+2, but->x1+t+3, but->y2-2);
                        }       
                }
-               // cut string in 2 parts
-               cpoin= strchr(but->drawstr, '|');
-               if(cpoin) *cpoin= 0;
+               if(but->drawstr[0]!=0) {
+                       // cut string in 2 parts
+                       cpoin= strchr(but->drawstr, '|');
+                       if(cpoin) *cpoin= 0;
 
-               /* If there's an icon too (made with uiDefIconTextBut) then draw the icon
-               and offset the text label to accomodate it */
-               
-               if ( (but->flag & UI_HAS_ICON) && (but->flag & UI_ICON_LEFT) ) {
-                       ui_draw_icon(but, but->icon);
+                       /* If there's an icon too (made with uiDefIconTextBut) then draw the icon
+                       and offset the text label to accomodate it */
+                       
+                       if ( (but->flag & UI_HAS_ICON) && (but->flag & UI_ICON_LEFT) ) {
+                               ui_draw_icon(but, but->icon);
 
-                       if(but->flag & UI_TEXT_LEFT) x= but->x1+24.0;
-                       else x= (but->x1+but->x2-but->strwidth+1)/2.0;
-               }
-               else {
-                       if(but->flag & UI_TEXT_LEFT) x= but->x1+4.0;
-                       else x= (but->x1+but->x2-but->strwidth+1)/2.0;
-               }
-               
-               /* text color, with pulldown item exception */
-               if(but->dt==UI_EMBOSSP) {
-                       if(but->flag & (UI_SELECT|UI_ACTIVE)) {         
-                               BIF_ThemeColor(TH_MENU_TEXT_HI);
-                       } else {
-                               BIF_ThemeColor(TH_MENU_TEXT);
+                               if(but->flag & UI_TEXT_LEFT) x= but->x1+24.0;
+                               else x= (but->x1+but->x2-but->strwidth+1)/2.0;
                        }
-               }
-               else {
-                       if(but->flag & UI_SELECT) {             
-                               BIF_ThemeColor(TH_BUT_TEXT_HI);
-                       } else {
-                               BIF_ThemeColor(TH_BUT_TEXT);
+                       else {
+                               if(but->flag & UI_TEXT_LEFT) x= but->x1+4.0;
+                               else x= (but->x1+but->x2-but->strwidth+1)/2.0;
                        }
-               }
-
-               /* tog3 button exception */
-               if(but->type==TOG3 && (but->flag & UI_SELECT)) {
-                       int ok= 0;
                        
-                       if( but->pointype==CHA ) {
-                               if( BTST( *(but->poin+2), but->bitnr )) ok= 1;
+                       /* text color, with pulldown item exception */
+                       if(but->dt==UI_EMBOSSP) {
+                               if(but->flag & (UI_SELECT|UI_ACTIVE)) {         
+                                       BIF_ThemeColor(TH_MENU_TEXT_HI);
+                               } else {
+                                       BIF_ThemeColor(TH_MENU_TEXT);
+                               }
+                       }
+                       else {
+                               if(but->flag & UI_SELECT) {             
+                                       BIF_ThemeColor(TH_BUT_TEXT_HI);
+                               } else {
+                                       BIF_ThemeColor(TH_BUT_TEXT);
+                               }
                        }
-                       else if( but->pointype ==SHO ) {
-                               short *sp= (short *)but->poin;
-                               if( BTST( sp[1], but->bitnr )) ok= 1;
+
+                       /* tog3 button exception */
+                       if(but->type==TOG3 && (but->flag & UI_SELECT)) {
+                               int ok= 0;
+                               
+                               if( but->pointype==CHA ) {
+                                       if( BTST( *(but->poin+2), but->bitnr )) ok= 1;
+                               }
+                               else if( but->pointype ==SHO ) {
+                                       short *sp= (short *)but->poin;
+                                       if( BTST( sp[1], but->bitnr )) ok= 1;
+                               }
+                               
+                               ui_tog3_invert(but->x1,but->y1,but->x2,but->y2, ok);
+                               if (ok) glColor3ub(255, 255, 0);
                        }
                        
-                       ui_tog3_invert(but->x1,but->y1,but->x2,but->y2, ok);
-                       if (ok) glColor3ub(255, 255, 0);
-               }
+                       /* LABEL button exception */
+                       if(but->type==LABEL && but->min!=0.0) BIF_ThemeColor(TH_BUT_TEXT_HI);
                
-               /* LABEL button exception */
-               if(but->type==LABEL && but->min!=0.0) BIF_ThemeColor(TH_BUT_TEXT_HI);
-       
-               ui_rasterpos_safe(x, (but->y1+but->y2- 9.0)/2.0, but->aspect);
-               BIF_DrawString(but->font, but->drawstr+but->ofs, (U.transopts & USER_TR_BUTTONS));
-
-               /* part text right aligned */
-               if(cpoin) {
-                       len= BIF_GetStringWidth(but->font, cpoin+1, (U.transopts & USER_TR_BUTTONS));
-                       ui_rasterpos_safe( but->x2 - len*but->aspect-3, (but->y1+but->y2- 9.0)/2.0, but->aspect);
-                       BIF_DrawString(but->font, cpoin+1, (U.transopts & USER_TR_BUTTONS));
-                       *cpoin= '|';
+                       ui_rasterpos_safe(x, (but->y1+but->y2- 9.0)/2.0, but->aspect);
+                       BIF_DrawString(but->font, but->drawstr+but->ofs, (U.transopts & USER_TR_BUTTONS));
+
+                       /* part text right aligned */
+                       if(cpoin) {
+                               len= BIF_GetStringWidth(but->font, cpoin+1, (U.transopts & USER_TR_BUTTONS));
+                               ui_rasterpos_safe( but->x2 - len*but->aspect-3, (but->y1+but->y2- 9.0)/2.0, but->aspect);
+                               BIF_DrawString(but->font, cpoin+1, (U.transopts & USER_TR_BUTTONS));
+                               *cpoin= '|';
+                       }
+               }
+               /* if there's no text label, then check to see if there's an icon only and draw it */
+               else if( but->flag & UI_HAS_ICON ) {
+                       ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd));
                }
        }
-       /* if there's no text label, then check to see if there's an icon only and draw it */
-       else if( but->flag & UI_HAS_ICON ) {
-               ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd));
-       }
-
 }
 
 static void ui_draw_but_COL(uiBut *but)
index 7ff2048463570cb26ae19623e0ad8e1ec649b367..f47082be451726b202c0bafba3f19e4122b39ec3 100644 (file)
@@ -64,6 +64,7 @@
 #include "BLI_blenlib.h"
 
 #include "BKE_global.h"
+#include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_material.h"
 #include "BKE_screen.h"
@@ -74,6 +75,7 @@
 #include "BIF_drawtext.h"
 #include "BIF_editaction.h"
 #include "BIF_editarmature.h"
+#include "BIF_editdeform.h"
 #include "BIF_editnla.h"
 #include "BIF_editview.h"
 #include "BIF_editconstraint.h"
@@ -235,6 +237,20 @@ static void outliner_height(SpaceOops *soops, ListBase *lb, int *h)
        }
 }
 
+static TreeElement *outliner_find_tree_element(ListBase *lb, int store_index)
+{
+       TreeElement *te= lb->first, *tes;
+       while(te) {
+               if(te->store_index==store_index) return te;
+               tes= outliner_find_tree_element(&te->subtree, store_index);
+               if(tes) return tes;
+               te= te->next;
+       }
+       return NULL;
+}
+
+
+
 static ID *outliner_search_back(SpaceOops *soops, TreeElement *te, short idcode)
 {
        TreeStoreElem *tselem;
@@ -315,7 +331,7 @@ static void outliner_sort(SpaceOops *soops, ListBase *lb)
        tselem= TREESTORE(te);
        
        /* sorting rules; only object lists or deformgroups */
-       if( (tselem->type==TE_DEFGROUP) || (tselem->type==0 && te->idcode==ID_OB)) {
+       if( (tselem->type==TSE_DEFGROUP) || (tselem->type==0 && te->idcode==ID_OB)) {
                
                /* count first */
                for(te= lb->first; te; te= te->next) totelem++;
@@ -329,7 +345,7 @@ static void outliner_sort(SpaceOops *soops, ListBase *lb)
                                tp->te= te;
                                tp->name= te->name;
                                tp->idcode= te->idcode;
-                               if(tselem->type) tp->idcode= 0; // dont sort this
+                               if(tselem->type && tselem->type!=TSE_DEFGROUP) tp->idcode= 0;   // dont sort this
                                tp->id= tselem->id;
                        }
                        
@@ -389,7 +405,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                                Scene *sce= (Scene *)id;
                                outliner_add_element(soops, &te->subtree, sce->world, te, 0, 0);
                                if(sce->scriptlink.scripts) {
-                                       TreeElement *tenla= outliner_add_element(soops, &te->subtree, sce, te, TE_SCRIPT_BASE, 0);
+                                       TreeElement *tenla= outliner_add_element(soops, &te->subtree, sce, te, TSE_SCRIPT_BASE, 0);
                                        int a= 0;
                                        tenla->name= "Scripts";
                                        for (a=0; a<sce->scriptlink.totscript; a++) {
@@ -412,12 +428,12 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                                if(ob->constraints.first) {
                                        bConstraint *con;
                                        TreeElement *ten;
-                                       TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TE_CONSTRAINT_BASE, 0);
+                                       TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0);
                                        int a= 0;
                                        
                                        tenla->name= "Constraints";
                                        for(con= ob->constraints.first; con; con= con->next, a++) {
-                                               ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TE_CONSTRAINT, a);
+                                               ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a);
                                                ten->name= con->name;
                                                ten->directdata= con;
                                                outliner_add_element(soops, &ten->subtree, con->ipo, ten, 0, 0);
@@ -427,29 +443,30 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                                if(ob->hooks.first) {
                                        ObHook *hook;
                                        TreeElement *ten;
-                                       TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TE_HOOKS_BASE, 0);
+                                       TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_HOOKS_BASE, 0);
                                        int a= 0;
                                        
                                        tenla->name= "Hooks";
                                        for(hook=ob->hooks.first; hook; hook= hook->next, a++) {
-                                               ten= outliner_add_element(soops, &tenla->subtree, hook->parent, tenla, TE_HOOK, a);
+                                               ten= outliner_add_element(soops, &tenla->subtree, hook->parent, tenla, TSE_HOOK, a);
                                                if(ten) ten->name= hook->name;
                                        }
                                }
                                if(ob->defbase.first) {
                                        bDeformGroup *defgroup;
                                        TreeElement *ten;
-                                       TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TE_DEFGROUP_BASE, 0);
+                                       TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
                                        int a= 0;
                                        
                                        tenla->name= "Vertex Groups";
                                        for (defgroup=ob->defbase.first; defgroup; defgroup=defgroup->next, a++) {
-                                               ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TE_DEFGROUP, a);
+                                               ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a);
                                                ten->name= defgroup->name;
+                                               ten->directdata= defgroup;
                                        }
                                }
                                if(ob->scriptlink.scripts) {
-                                       TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TE_SCRIPT_BASE, 0);
+                                       TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_SCRIPT_BASE, 0);
                                        int a= 0;
                                        
                                        tenla->name= "Scripts";
@@ -460,12 +477,12 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                                if(ob->nlastrips.first) {
                                        bActionStrip *strip;
                                        TreeElement *ten;
-                                       TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TE_NLA, 0);
+                                       TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_NLA, 0);
                                        int a= 0;
                                        
                                        tenla->name= "NLA strips";
                                        for (strip=ob->nlastrips.first; strip; strip=strip->next, a++) {
-                                               ten= outliner_add_element(soops, &tenla->subtree, strip->act, tenla, TE_NLA_ACTION, a);
+                                               ten= outliner_add_element(soops, &tenla->subtree, strip->act, tenla, TSE_NLA_ACTION, a);
                                                if(ten) ten->directdata= strip;
                                        }
                                }
@@ -575,7 +592,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
 static void outliner_add_bone(SpaceOops *soops, ListBase *lb, ID *id, Bone *curBone, 
                                                          TreeElement *parent, int *a)
 {
-       TreeElement *te= outliner_add_element(soops, lb, id, parent, TE_BONE, *a);
+       TreeElement *te= outliner_add_element(soops, lb, id, parent, TSE_BONE, *a);
 
        (*a)++;
        te->name= curBone->name;
@@ -738,7 +755,7 @@ void outliner_toggle_visible(struct ScrArea *sa)
        else 
                outliner_set_flag(soops, &soops->tree, TSE_CLOSED, 1);
 
-       scrarea_queue_redraw(curarea);
+       scrarea_queue_redraw(sa);
 }
 
 void outliner_toggle_selected(struct ScrArea *sa)
@@ -750,7 +767,7 @@ void outliner_toggle_selected(struct ScrArea *sa)
        else 
                outliner_set_flag(soops, &soops->tree, TSE_SELECTED, 1);
        
-       scrarea_queue_redraw(curarea);
+       scrarea_queue_redraw(sa);
 }
 
 
@@ -787,9 +804,20 @@ void outliner_one_level(struct ScrArea *sa, int add)
                if(level) outliner_openclose_level(soops, &soops->tree, 1, level-1, 0);
        }
        
-       scrarea_queue_redraw(curarea);
+       scrarea_queue_redraw(sa);
 }
 
+void outliner_page_up_down(ScrArea *sa, int up)
+{
+       SpaceOops *soops= sa->spacedata.first;
+       int dy= soops->v2d.mask.ymax-soops->v2d.mask.ymin;
+       
+       if(up == -1) dy= -dy;
+       soops->v2d.cur.ymin+= dy;
+       soops->v2d.cur.ymax+= dy;
+       
+       scrarea_queue_redraw(sa);
+}
 
 /* **** do clicks on items ******* */
 
@@ -1157,13 +1185,13 @@ static int tree_element_type_active(SpaceOops *soops, TreeElement *te, TreeStore
 {
        
        switch(tselem->type) {
-               case TE_NLA_ACTION:
+               case TSE_NLA_ACTION:
                        return tree_element_active_nla_action(te, tselem, set);
-               case TE_DEFGROUP:
+               case TSE_DEFGROUP:
                        return tree_element_active_defgroup(te, tselem, set);
-               case TE_BONE:
+               case TSE_BONE:
                        return tree_element_active_bone(te, tselem, set);
-               case TE_HOOK: // actually object
+               case TSE_HOOK: // actually object
                        if(set) tree_element_active_object(soops, te);
                        else if(tselem->id==(ID *)OBACT) return 1;
                        break;
@@ -1203,38 +1231,47 @@ static int do_outliner_mouse_event(SpaceOops *soops, TreeElement *te, short even
                /* name and first icon */
                else if(mval[0]>te->xs && mval[0]<te->xend) {
                        
-                       /* always makes active object */
-                       tree_element_active_object(soops, te);
-                       
-                       if(tselem->type==0) { // the lib blocks
-                               /* editmode? */
-                               if(te->idcode==ID_SCE) {
-                                       if(G.scene!=(Scene *)tselem->id) {
+                       /* activate a name button? */
+                       if(G.qual & LR_CTRLKEY) {
+                               if(ELEM5(tselem->type, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_HOOKS_BASE, TSE_SCRIPT_BASE)) 
+                                       error("Cannot edit builtin name");
+                               else {
+                                       tselem->flag |= TSE_TEXTBUT;
+                               }
+                       }
+                       else {
+                               /* always makes active object */
+                               tree_element_active_object(soops, te);
+                               
+                               if(tselem->type==0) { // the lib blocks
+                                       /* editmode? */
+                                       if(te->idcode==ID_SCE) {
+                                               if(G.scene!=(Scene *)tselem->id) {
+                                                       if(G.obedit) exit_editmode(2);
+                                                       if(G.obpose) exit_posemode(1);
+                                                       set_scene((Scene *)tselem->id);
+                                               }
+                                       }
+                                       else if(ELEM4(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT)) {
+                                               if(G.obpose) exit_posemode(1);
+                                               if(G.obedit) exit_editmode(2);
+                                               else {
+                                                       enter_editmode();
+                                                       mainqenter(F9KEY, 1);
+                                               }
+                                       }
+                                       else if(te->idcode==ID_AR) {
                                                if(G.obedit) exit_editmode(2);
                                                if(G.obpose) exit_posemode(1);
-                                               set_scene((Scene *)tselem->id);
+                                               else enter_posemode();
                                        }
-                               }
-                               else if(ELEM4(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT)) {
-                                       if(G.obpose) exit_posemode(1);
-                                       if(G.obedit) exit_editmode(2);
-                                       else {
-                                               enter_editmode();
-                                               mainqenter(F9KEY, 1);
+                                       else {  // rest of types
+                                               tree_element_active(soops, te, 1);
                                        }
+                                       
                                }
-                               else if(te->idcode==ID_AR) {
-                                       if(G.obedit) exit_editmode(2);
-                                       if(G.obpose) exit_posemode(1);
-                                       else enter_posemode();
-                               }
-                               else {  // rest of types
-                                       tree_element_active(soops, te, 1);
-                               }
-                               
+                               else tree_element_type_active(soops, te, tselem, 1);
                        }
-                       else tree_element_type_active(soops, te, tselem, 1);
-                       
                        return 1;
                }
        }
@@ -1652,7 +1689,8 @@ void outliner_operation_menu(ScrArea *sa)
        else if(datalevel) {
                if(datalevel==-1) error("Mixed selection");
                else {
-                       pupmenu("Data Operations%t|Delete");
+                       error("Not yet...");
+                       //pupmenu("Data Operations%t|Delete");
                }
        }
        else error("Nothing selected");
@@ -1666,21 +1704,21 @@ static void tselem_draw_icon(TreeStoreElem *tselem)
 {
        if(tselem->type) {
                switch( tselem->type) {
-                       case TE_NLA:
+                       case TSE_NLA:
                                BIF_draw_icon(ICON_NLA); break;
-                       case TE_NLA_ACTION:
+                       case TSE_NLA_ACTION:
                                BIF_draw_icon(ICON_ACTION); break;
-                       case TE_DEFGROUP_BASE:
+                       case TSE_DEFGROUP_BASE:
                                BIF_draw_icon(ICON_VERTEXSEL); break;
-                       case TE_BONE:
+                       case TSE_BONE:
                                BIF_draw_icon(ICON_WPAINT_DEHLT); break;
-                       case TE_CONSTRAINT_BASE:
+                       case TSE_CONSTRAINT_BASE:
                                BIF_draw_icon(ICON_CONSTRAINT); break;
-                       case TE_HOOKS_BASE:
+                       case TSE_HOOKS_BASE:
                                BIF_draw_icon(ICON_HOOK); break;
-                       case TE_HOOK:
+                       case TSE_HOOK:
                                BIF_draw_icon(ICON_OBJECT); break;
-                       case TE_SCRIPT_BASE:
+                       case TSE_SCRIPT_BASE:
                                BIF_draw_icon(ICON_TEXT); break;
                        default:
                                BIF_draw_icon(ICON_DOT); break;
@@ -1996,8 +2034,91 @@ static void outliner_back(SpaceOops *soops)
        }
 }
 
+static char bone_newname[40];  // temp storage for bone rename, bones are 32 max.
+
+static void namebutton_cb(void *voidp, void *arg2_unused)
+{
+       SpaceOops *soops= voidp;
+       TreeStore *ts= soops->treestore;
+       TreeStoreElem *tselem;
+       int a;
+       
+       if(ts) {
+               /* only one namebutton can exist */
+               for(a=0, tselem= ts->data; a<ts->usedelem; a++, tselem++) {
+                       if(tselem->flag & TSE_TEXTBUT) {
+                               if(tselem->type==0) {
+                                       test_idbutton(tselem->id->name+2);      // library.c, unique name and alpha sort
+                               }
+                               else {
+                                       TreeElement *te= outliner_find_tree_element(&soops->tree, a);
+                                       
+                                       if(te) {
+                                               switch(tselem->type) {
+                                               case TSE_DEFGROUP:
+                                                       unique_vertexgroup_name(te->directdata, (Object *)tselem->id); //       id = object
+                                                       break;
+                                               case TSE_NLA_ACTION:
+                                                       test_idbutton(tselem->id->name+2);
+                                                       break;
+                                               case TSE_BONE:
+                                                       {
+                                                               Bone *bone= te->directdata;
+                                                               // always make current object active
+                                                               tree_element_active_object(soops, te);
+
+                                                               // dangerous call, it re-allocs the Armature bones, exits editmode too
+                                                               rename_bone_ext(bone->name, bone_newname);
+                                                               allqueue(REDRAWOOPS, 0);
+                                                               allqueue(REDRAWVIEW3D, 1);
+                                                               allqueue(REDRAWBUTSEDIT, 0);
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+                               tselem->flag &= ~TSE_TEXTBUT;
+                       }
+               }
+               scrarea_queue_redraw(curarea);
+       }
+}
+
+void outliner_buttons(uiBlock *block, SpaceOops *soops, ListBase *lb)
+{
+       uiBut *bt;
+       TreeElement *te;
+       TreeStoreElem *tselem;
+       int dx, len;
+       
+       for(te= lb->first; te; te= te->next) {
+               tselem= TREESTORE(te);
+               if(tselem->flag & TSE_TEXTBUT) {
+                       
+                       // darn bones have complex renaming conventions... cannot edit name itself in button
+                       if(tselem->type==TSE_BONE) {
+                               strncpy(bone_newname, te->name, 32); // bone_newname is global
+                               te->name= bone_newname;
+                               len= 24;
+                       }
+                       else len= 19;
+                       
+                       dx= BIF_GetStringWidth(G.font, te->name, 0);
+                       if(dx<50) dx= 50;
+                       
+                       bt= uiDefBut(block, TEX, OL_NAMEBUTTON, "",  te->xs+2*OL_X-4, te->ys, dx+10, OL_H-1, te->name, 1.0, (float)len, 0, 0, "");
+                       uiButSetFunc(bt, namebutton_cb, soops, NULL);
+
+                       // signal for button to open
+                       addqueue(curarea->win, BUT_ACTIVATE, OL_NAMEBUTTON);
+               }
+               if((tselem->flag & TSE_CLOSED)==0) outliner_buttons(block, soops, &te->subtree);
+       }
+}
+
 void draw_outliner(ScrArea *sa, SpaceOops *soops)
 {
+       uiBlock *block;
        int sizey;
        short ofsx, ofsy;
        
@@ -2029,13 +2150,23 @@ void draw_outliner(ScrArea *sa, SpaceOops *soops)
                G.v2d->cur.ymin= -(G.v2d->mask.ymax-G.v2d->mask.ymin);
        }
 
-       myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
+       myortho2(G.v2d->cur.xmin-0.375, G.v2d->cur.xmax-0.375, G.v2d->cur.ymin-0.375, G.v2d->cur.ymax-0.375);
 
        /* draw outliner stuff */
        outliner_back(soops);
        outliner_draw_tree(soops);
+
+       /* restore viewport */
+       mywinset(sa->win);
+       
+       /* ortho corrected */
+       myortho2(G.v2d->cur.xmin-SCROLLB-0.375, G.v2d->cur.xmax-0.375, G.v2d->cur.ymin-0.375, G.v2d->cur.ymax-0.375);
+       
+       block= uiNewBlock(&curarea->uiblocks, "outliner buttons", UI_EMBOSS, UI_HELV, sa->win);
+       outliner_buttons(block, soops, &soops->tree);
+       uiDrawBlock(block);
        
-       /* drawoopsspace handles sliders and restores view */
+       /* drawoopsspace handles sliders */
 }
 
 
index 5c78692749175f64e5c9453584cd871ea52b0f6a..8713d57efee7fb93675f9e3cc9ea8d0aa3231873 100644 (file)
@@ -3785,7 +3785,7 @@ static void winqreadoopsspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
 
        if(val==0) return;
 
-       if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
+       if( uiDoBlocks(&sa->uiblocks, event)!=UI_NOTHING ) event= 0;
 
        if (U.flag & USER_NONUMPAD) {
                event= convert_for_nonumpad(event);
@@ -3795,7 +3795,7 @@ static void winqreadoopsspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
        if(soops->type==SO_OUTLINER) {
                switch(event) {
                case LEFTMOUSE:
-                       outliner_mouse_event(sa, event);
+                       outliner_mouse_event(sa, event);                        
                        break;
                case MIDDLEMOUSE:
                case WHEELUPMOUSE:
@@ -3816,6 +3816,12 @@ static void winqreadoopsspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                case HOMEKEY:
                        outliner_show_hierarchy(sa);
                        break;
+               case PAGEUPKEY:
+                       outliner_page_up_down(sa, 1);
+                       break;
+               case PAGEDOWNKEY:
+                       outliner_page_up_down(sa, -1);
+                       break;
                        
                case RETKEY:
                case PADENTER: