Orange; stuff for the animation department!
[blender.git] / source / blender / src / space.c
index 4f64b0fd87e66c624457a8202c700ce73a9179d6..b2b091f572b2f52dc17270768d29a15e85ed0bf1 100644 (file)
@@ -76,6 +76,7 @@
 #include "BKE_global.h"
 #include "BKE_ipo.h"
 #include "BKE_main.h"
+#include "BKE_node.h"
 #include "BKE_scene.h"
 #include "BKE_utildefines.h"
 
@@ -87,7 +88,9 @@
 #include "BIF_drawtext.h"
 #include "BIF_drawscript.h"
 #include "BIF_editarmature.h"
+#include "BIF_editconstraint.h"
 #include "BIF_editfont.h"
+#include "BIF_editgroup.h"
 #include "BIF_editkey.h"
 #include "BIF_editlattice.h"
 #include "BIF_editmesh.h"
@@ -576,31 +579,10 @@ static void select_parent(void)   /* Makes parent active and de-selected OBACT */
        }
 }
 
-
-void select_group_menu(void)
-{
-       char *str;
-       short nr;
-
-       /* make menu string */
-       
-       str= MEM_mallocN(160, "groupmenu");
-       strcpy(str, "Select Grouped%t|Children%x1|"
-                   "Immediate Children%x2|Parent%x3|"
-                   "Objects on Shared Layers%x4");
-
-       /* here we go */
-       
-       nr= pupmenu(str);
-       MEM_freeN(str);
-       
-       select_group(nr);
-}
-
-void select_group(short nr)
+void select_grouped(short nr)
 {
        Base *base;
-
+       
        if(nr==4) {
                base= FIRSTBASE;
                while(base) {
@@ -622,6 +604,27 @@ void select_group(short nr)
        allqueue(REDRAWIPO, 0);
 }
 
+static void select_grouped_menu(void)
+{
+       char *str;
+       short nr;
+
+       /* make menu string */
+       
+       str= MEM_mallocN(160, "groupmenu");
+       strcpy(str, "Select Grouped%t|Children%x1|"
+                   "Immediate Children%x2|Parent%x3|"
+                   "Objects on Shared Layers%x4");
+
+       /* here we go */
+       
+       nr= pupmenu(str);
+       MEM_freeN(str);
+       
+       select_grouped(nr);
+}
+
+
 static unsigned short convert_for_nonumpad(unsigned short event)
 {
        if (event>=ZEROKEY && event<=NINEKEY) {
@@ -642,6 +645,8 @@ static unsigned short convert_for_nonumpad(unsigned short event)
 void BIF_undo_push(char *str)
 {
        if(G.obedit) {
+               if (U.undosteps == 0) return;
+
                if(G.obedit->type==OB_MESH)
                        undo_push_mesh(str);
                else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
@@ -676,7 +681,10 @@ void BIF_undo(void)
                else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL));
                else {
                        /* now also in faceselect mode */
-                       if(U.uiflag & USER_GLOBALUNDO) BKE_undo_step(1);
+                       if(U.uiflag & USER_GLOBALUNDO) {
+                               BKE_undo_step(1);
+                               sound_initialize_sounds();
+                       }
                }
        }
 }
@@ -694,7 +702,10 @@ void BIF_redo(void)
                        vpaint_undo();
                else {
                        /* includes faceselect now */
-                       if(U.uiflag & USER_GLOBALUNDO) BKE_undo_step(-1);
+                       if(U.uiflag & USER_GLOBALUNDO) {
+                               BKE_undo_step(-1);
+                               sound_initialize_sounds();
+                       }
                }
        }
 }
@@ -938,9 +949,9 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        else if(G.obedit->type==OB_ARMATURE)
                                                mouse_armature();
                                }
-                               else if((G.obedit) && (G.qual == (LR_CTRLKEY|LR_ALTKEY)))
+                               else if((G.obedit && G.obedit->type==OB_MESH) && (G.qual == (LR_CTRLKEY|LR_ALTKEY)))
                                        mouse_mesh();   // loop select for 1 mousebutton dudes
-                               else if((G.obedit) && (G.qual == (LR_CTRLKEY|LR_ALTKEY|LR_SHIFTKEY)))
+                               else if((G.obedit && G.obedit->type==OB_MESH) && (G.qual == (LR_CTRLKEY|LR_ALTKEY|LR_SHIFTKEY)))
                                        mouse_mesh();   // loop select for 1 mousebutton dudes
                                else if(G.qual==LR_CTRLKEY)
                                        mouse_select(); // also allow in editmode, for vertex parenting
@@ -1157,6 +1168,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        else
                                                convertmenu();  /* editobject.c */
                                }
+                               else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) 
+                                       add_constraint(0);      /* editconstraint.c, generic for objects and posemode */
                                else if((G.qual==LR_SHIFTKEY)) {
                                        view3d_home(1);
                                        curs= give_cursor();
@@ -1238,23 +1251,33 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                                        edge_flip();
                                                else if (G.qual==0)
                                                        addedgeface_mesh();
+                                               else if ( G.qual == 
+                                                        (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
+                                                       select_linked_flat_faces();
+                                               }
+
                                        }
                                        else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) addsegment_nurb();
                                }
                                else if(G.qual==LR_CTRLKEY)
                                        sort_faces();
-                               else if((G.qual==LR_SHIFTKEY))
-                                       fly();
+                               else if((G.qual==LR_SHIFTKEY)) {
+                                       if(ob && (ob->flag & OB_POSEMODE))
+                                          pose_activate_flipped_bone();
+                                       else if(G.f & G_WEIGHTPAINT)
+                                               pose_activate_flipped_bone();
+                                       else
+                                               fly();
+                               }
                                else {
-                                               set_faceselect();
-                                       }
+                                       set_faceselect();
+                               }
                                
                                break;
                        case GKEY:
-                               /* RMGRP if(G.qual & LR_CTRLKEY) add_selected_to_group();
-                               else if(G.qual & LR_ALTKEY) rem_selected_from_group(); */
-                               if((G.qual==LR_SHIFTKEY))
-                                       select_group_menu();
+                               if(G.qual & LR_CTRLKEY) group_operation_with_menu();
+                               else if((G.qual==LR_SHIFTKEY))
+                                       select_grouped_menu();
                                else if(G.qual==LR_ALTKEY) {
                                        if(okee("Clear location")) {
                                                clear_object('g');
@@ -1451,7 +1474,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        mirrormenu();
                                }
                                else if(G.qual==0) {
-                                    movetolayer();
+                                       if(ob && (ob->flag & OB_POSEMODE))
+                                               pose_movetolayer();
+                                       else
+                                               movetolayer();
                                }
                                break;
                        case NKEY:
@@ -1617,7 +1643,9 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                                initTransform(TFM_TOSPHERE, CTX_NONE);
                                                Transform();
                                        }
-                                       
+                                       if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
+                                               if(G.obedit->type==OB_MESH) select_sharp_edges();
+                                       }
                                }
                                else if(G.qual==LR_ALTKEY) {
                                        if(G.f & G_WEIGHTPAINT)
@@ -2067,7 +2095,7 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                        break;
                case HKEY:
                        if(G.qual==LR_ALTKEY)
-                               sethandles_ipo(4);              // tsk tsk ton!
+                               sethandles_ipo(HD_AUTO_ANIM);
                        if(G.qual==LR_SHIFTKEY)
                                sethandles_ipo(HD_AUTO);
                        else if(G.qual==0)
@@ -2227,7 +2255,7 @@ static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3)
 
        /* main choices pup */
        uiDefButS(block, MENU, B_CHANGE_THEME, "UI and Buttons %x1|%l|3D View %x2|%l|Ipo Curve Editor %x3|Action Editor %x4|"
-               "NLA Editor %x5|%l|UV/Image Editor %x6|Video Sequence Editor %x7|Timeline %x15|Audio Window %x8|Text Editor %x9|%l|User Preferences %x10|"
+               "NLA Editor %x5|%l|UV/Image Editor %x6|Video Sequence Editor %x7|Node Editor %x16|Timeline %x15|Audio Window %x8|Text Editor %x9|%l|User Preferences %x10|"
                "Outliner %x11|Buttons Window %x12|%l|File Browser %x13|Image Browser %x14",
                                                                                                        255,y2,200,20, &curmain, 0, 0, 0, 0, "Specify theme for...");
        if(curmain==1) spacetype= 0;
@@ -2245,6 +2273,7 @@ static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3)
        else if(curmain==13) spacetype= SPACE_FILE;
        else if(curmain==14) spacetype= SPACE_IMASEL;
        else if(curmain==15) spacetype= SPACE_TIME;
+       else if(curmain==16) spacetype= SPACE_NODE;
        else return; // only needed while coding... when adding themes for more windows
        
        /* color choices pup */
@@ -2277,7 +2306,7 @@ static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3)
        }
        else {
                uiBlockBeginAlign(block);
-               if ELEM6(th_curcol, TH_PANEL, TH_FACE, TH_FACE_SELECT, TH_MENU_BACK, TH_MENU_HILITE, TH_MENU_ITEM) {
+               if ELEM7(th_curcol, TH_PANEL, TH_LAMP, TH_FACE, TH_FACE_SELECT, TH_MENU_BACK, TH_MENU_HILITE, TH_MENU_ITEM) {
                        uiDefButC(block, NUMSLI, B_UPDATE_THEME,"A ",   465,y3+25,200,20,  col+3, 0.0, 255.0, B_THEMECOL, 0, "");
                }
                uiDefButC(block, NUMSLI, B_UPDATE_THEME,"R ",   465,y3,200,20,  col, 0.0, 255.0, B_THEMECOL, 0, "");
@@ -2430,6 +2459,10 @@ void drawinfospace(ScrArea *sa, void *spacedata)
 #else 
                U.curssize=0; /*Small Cursor always for OS X for now */
 #endif
+               uiDefButBitI(block, TOG, USER_PLAINMENUS, B_PLAINMENUS, "Plain menus",
+                       (xpos+edgsp),y1,spref,buth,
+                       &(U.uiflag), 0, 0, 0, 0,
+                       "Use column layout for toolbox and do not flip contents in any menu");
                uiBlockEndAlign(block);
 
                uiDefBut(block, LABEL,0,"Menus:",
@@ -2606,16 +2639,26 @@ void drawinfospace(ScrArea *sa, void *spacedata)
                uiBlockBeginAlign(block);
                uiDefButS(block, NUM, B_REDRCURW3D, "Size:",
                                         (xpos+edgsp+(5*mpref)+(6*midsp)),y5,(mpref/2),buth,
-                                        &(U.tw_size), 2, 40, 0, 0, "Size of widget as percentage of window size");
+                                        &(U.tw_size), 2, 40, 0, 0, "Diameter of widget, in 10 pixel units");
                uiDefButS(block, NUM, B_REDRCURW3D, "Handle:",
                                         (xpos+edgsp+(5*mpref)+(6*midsp)+(mpref/2)),y5,(mpref/2),buth,
                                         &(U.tw_handlesize), 2, 40, 0, 0, "Size of widget handles as percentage of widget radius");
                uiDefButS(block, NUM, B_REDRCURW3D, "Hotspot:",
                                  (xpos+edgsp+(5*mpref)+(6*midsp)),y4,(mpref),buth,
                                  &(U.tw_hotspot), 4, 40, 0, 0, "Hotspot in pixels for clicking widget handles");
-               
                uiBlockEndAlign(block);
                
+               
+               uiDefBut(block, LABEL,0,"Object center diameter",
+                                (xpos+(2*edgsp)+(5*mpref)+(5*midsp)),y3label,mpref,buth,
+                                0, 0, 0, 0, 0, "");
+               uiBlockBeginAlign(block);
+               uiDefButS(block, NUM, B_REDRCURW3D, "Size",
+                                 (xpos+(2*edgsp)+(5*mpref)+(5*midsp)),y2,mpref,buth,
+                                 &(U.obcenter_dia), 4, 10, 0, 0,
+                                 "Diameter in Pixels for Object/Lamp center drawing");
+               
+               
        } else if (U.userpref == 1) { /* edit methods */
 
 
@@ -2632,27 +2675,32 @@ void drawinfospace(ScrArea *sa, void *spacedata)
                uiBlockEndAlign(block);
 
 
-               uiDefBut(block, LABEL,0,"Editmode undo:",
+               uiDefBut(block, LABEL,0,"Undo:",
                        (xpos+(2*edgsp)+mpref),y3label, mpref,buth,
                        0, 0, 0, 0, 0, "");
                uiBlockBeginAlign(block);
                uiDefButS(block, NUMSLI, B_DRAWINFO, "Steps:",
                        (xpos+edgsp+mpref+midsp),y2,mpref,buth,
-                       &(U.undosteps), 2, 64, 0, 0, "Number of undo steps available in Edit Mode (smaller values conserve memory)");
+                       &(U.undosteps), 0, 64, 0, 0, "Number of undo steps available (smaller values conserve memory)");
 
                uiDefButBitI(block, TOG, USER_GLOBALUNDO, B_DRAWINFO, "Global undo",
                        (xpos+edgsp+mpref+midsp),y1,mpref,buth,
-                       &(U.uiflag), 2, 64, 0, 0, "");
+                       &(U.uiflag), 2, 64, 0, 0, "Global undo works by keeping a full copy of the file itself in memory, so takes extra memory");
                uiBlockEndAlign(block);
 
 
                uiDefBut(block, LABEL,0,"Auto keyframe",
                        (xpos+(2*edgsp)+(2*mpref)+midsp),y3label,mpref,buth,
                        0, 0, 0, 0, 0, "");
+
                uiDefButBitI(block, TOG, G_RECORDKEYS, REDRAWTIME, "Action and Object", 
                                        (xpos+edgsp+(2*mpref)+(2*midsp)),y2,mpref, buth,
                                         &(G.flags), 0, 0, 0, 0, "Automatic keyframe insertion in Object and Action Ipo curves");
 
+               uiDefButBitI(block, TOG, USER_KEYINSERTAVAI, REDRAWTIME, "Available", 
+                       (xpos+edgsp+(2*mpref)+(2*midsp)),y1,mpref, buth,
+                       &(U.uiflag), 0, 0, 0, 0, "Automatic keyframe insertion in available curves");
+
 //             uiDefButBitS(block, TOG, USER_KEYINSERTACT, 0, "Action",
 //                     (xpos+edgsp+(2*mpref)+(2*midsp)),y2,(spref+edgsp),buth,
 //                     &(U.uiflag), 0, 0, 0, 0, "Automatic keyframe insertion in Action Ipo curve");
@@ -3181,7 +3229,7 @@ static void winqreadbutspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                        scrarea_queue_winredraw(curarea);
                        break;
                case RENDERPREVIEW:
-                       BIF_previewrender(sbuts);
+                       BIF_previewrender_buts(sbuts);
                        break;
                
                case HOMEKEY:
@@ -3266,12 +3314,15 @@ static void init_butspace(ScrArea *sa)
        /* set_rects only does defaults, so after reading a file the cur has not changed */
        set_rects_butspace(buts);
        buts->v2d.cur= buts->v2d.tot;
+
+       buts->ri = NULL;
 }
 
 void extern_set_butspace(int fkey)
 {
        ScrArea *sa;
        SpaceButs *sbuts;
+       Object *ob= OBACT;
        
        /* when a f-key pressed: 'closest' button window is initialized */
        if(curarea->spacetype==SPACE_BUTS) sa= curarea;
@@ -3294,32 +3345,79 @@ void extern_set_butspace(int fkey)
                sbuts->mainb= CONTEXT_LOGIC;
        }
        else if(fkey==F5KEY) {
-               sbuts->mainb= CONTEXT_SHADING;
-               if(OBACT) {
-                       if(OBACT->type==OB_CAMERA) 
+               /* if it's already in shading context, cycle between tabs with the same key */
+               if (sbuts->oldkeypress == F5KEY) {
+
+                       if (sbuts->tab[CONTEXT_SHADING]==TAB_SHADING_LAMP)
+                               sbuts->tab[CONTEXT_SHADING]=TAB_SHADING_MAT;
+                       else if (sbuts->tab[CONTEXT_SHADING]==TAB_SHADING_MAT)
+                               sbuts->tab[CONTEXT_SHADING]=TAB_SHADING_TEX;
+                       else if (sbuts->tab[CONTEXT_SHADING]==1) {
+                               sbuts->tab[CONTEXT_SHADING]=TAB_SHADING_RAD;
+                       }
+                       else if (sbuts->tab[CONTEXT_SHADING]==TAB_SHADING_RAD)
+                               sbuts->tab[CONTEXT_SHADING]=TAB_SHADING_WORLD;
+                       else if (sbuts->tab[CONTEXT_SHADING]==TAB_SHADING_WORLD)
+                               sbuts->tab[CONTEXT_SHADING]=TAB_SHADING_LAMP;
+               }
+               /* if we're coming in from texture buttons, 
+               or from outside the shading context, just go to the 'default' */
+               else if (ob && ((sbuts->mainb!= CONTEXT_SHADING) || (sbuts->oldkeypress == F6KEY)) ) {
+                       sbuts->mainb= CONTEXT_SHADING;
+                       
+                       if(ob->type==OB_CAMERA) 
                                sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_WORLD;
-                       else if(OBACT->type==OB_LAMP) 
+                       else if(ob->type==OB_LAMP) 
                                sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_LAMP;
                        else  
                                sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_MAT;
                }
-               else sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_MAT;
+               else {
+                       sbuts->mainb= CONTEXT_SHADING;
+                       sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_MAT;
+               }
+               BIF_preview_changed(ID_TE);
        }
        else if(fkey==F6KEY) {
                sbuts->mainb= CONTEXT_SHADING;
                sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_TEX;
+               BIF_preview_changed(ID_TE);
+       }
+       else if(fkey==F7KEY) {
+               /* if it's already in object context, cycle between tabs with the same key */
+               if (sbuts->oldkeypress == F7KEY) {
+
+                       if (sbuts->tab[CONTEXT_OBJECT]==TAB_OBJECT_OBJECT)
+                               sbuts->tab[CONTEXT_OBJECT]=TAB_OBJECT_PHYSICS;
+                       else if (sbuts->tab[CONTEXT_OBJECT]==TAB_OBJECT_PHYSICS)
+                               sbuts->tab[CONTEXT_OBJECT]=TAB_OBJECT_OBJECT;
+               }
+               else sbuts->mainb= CONTEXT_OBJECT;
+               
        }
-       else if(fkey==F7KEY) sbuts->mainb= CONTEXT_OBJECT;
        else if(fkey==F8KEY) {
                sbuts->mainb= CONTEXT_SHADING;
                sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_WORLD;
        }
        else if(fkey==F9KEY) sbuts->mainb= CONTEXT_EDITING;
-       else if(fkey==F10KEY) sbuts->mainb= CONTEXT_SCENE;
+       else if(fkey==F10KEY) {
+               /* if it's already in scene context, cycle between tabs with the same key */
+               if (sbuts->oldkeypress == F10KEY) {
+
+                       if (sbuts->tab[CONTEXT_SCENE]==TAB_SCENE_RENDER)
+                               sbuts->tab[CONTEXT_SCENE]=TAB_SCENE_ANIM;
+                       else if (sbuts->tab[CONTEXT_SCENE]==TAB_SCENE_ANIM)
+                               sbuts->tab[CONTEXT_SCENE]=TAB_SCENE_SOUND;
+                       else if (sbuts->tab[CONTEXT_SCENE]==TAB_SCENE_SOUND)
+                               sbuts->tab[CONTEXT_SCENE]=TAB_SCENE_RENDER;
+               }
+               else sbuts->mainb= CONTEXT_SCENE;
+       }
+
+       sbuts->oldkeypress = fkey;
 
        scrarea_queue_headredraw(sa);
        scrarea_queue_winredraw(sa);
-       BIF_preview_changed(sbuts);
 }
 
 /* ******************** SPACE: SEQUENCE ********************** */
@@ -3402,6 +3500,7 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                case PADPLUSKEY:
                        if(sseq->mainb) {
                                sseq->zoom++;
+                               if(sseq->zoom==-1) sseq->zoom= 1;
                                if(sseq->zoom>8) sseq->zoom= 8;
                        }
                        else {
@@ -3427,7 +3526,8 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                case PADMINUS:
                        if(sseq->mainb) {
                                sseq->zoom--;
-                               if(sseq->zoom<1) sseq->zoom= 1;
+                               if(sseq->zoom==0) sseq->zoom= -2;
+                               if(sseq->zoom<-8) sseq->zoom= -8;
                        }
                        else {
                                if((G.qual==LR_SHIFTKEY))
@@ -3792,8 +3892,7 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        sample_vpaint();
                                break;
                        case AKEY:
-                               if((G.qual==0))
-                                       select_swap_tface_uv();
+                               select_swap_tface_uv();
                                break;
                        case BKEY:
                                if(G.qual==LR_SHIFTKEY)
@@ -3881,6 +3980,8 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        stitch_uv_tface(0);
                                else if(G.qual==LR_SHIFTKEY)
                                        stitch_uv_tface(1);
+                               else if(G.qual==LR_CTRLKEY)
+                                       minimize_stretch_tface_uv();
                                break;
                        case WKEY:
                                weld_align_menu_tface_uv();
@@ -4067,6 +4168,11 @@ static void winqreadoopsspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                        if((G.qual==0))
                                do_oops_buttons(B_OOPSHOME);
                        break;
+               
+               case PADPERIOD:
+                       if((G.qual==0))
+                               do_oops_buttons(B_OOPSVIEWSEL);
+                       break;
                        
                case AKEY:
                        if((G.qual==0)) {
@@ -4339,6 +4445,47 @@ static void init_timespace(ScrArea *sa)
        
 }
 
+/* ******************** SPACE: Time ********************** */
+
+extern void drawnodespace(ScrArea *sa, void *spacedata);
+extern void winqreadnodespace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
+
+static void init_nodespace(ScrArea *sa)
+{
+       SpaceNode *snode;
+       
+       snode= MEM_callocN(sizeof(SpaceNode), "init nodespace");
+       BLI_addhead(&sa->spacedata, snode);
+       
+       snode->spacetype= SPACE_NODE;
+       snode->blockscale= 0.7;
+       
+       snode->v2d.tot.xmin=  -10.0;
+       snode->v2d.tot.ymin=  -10.0;
+       snode->v2d.tot.xmax= (float)sa->winx + 10.0f;
+       snode->v2d.tot.ymax= (float)sa->winy + 10.0f;
+       
+       snode->v2d.cur.xmin=  0.0;
+       snode->v2d.cur.ymin=  0.0;
+       snode->v2d.cur.xmax= (float)sa->winx;
+       snode->v2d.cur.ymax= (float)sa->winy;
+       
+       snode->v2d.min[0]= 1.0;
+       snode->v2d.min[1]= 1.0;
+       
+       snode->v2d.max[0]= 32000.0f;
+       snode->v2d.max[1]= 32000.0f;
+       
+       snode->v2d.minzoom= 0.5f;
+       snode->v2d.maxzoom= 1.21f;
+       
+       snode->v2d.scroll= 0;
+       snode->v2d.keepaspect= 1;
+       snode->v2d.keepzoom= 1;
+       snode->v2d.keeptot= 0;
+}
+
+
 
 /* ******************** SPACE: GENERAL ********************** */
 
@@ -4406,6 +4553,8 @@ void newspace(ScrArea *sa, int type)
                                        init_nlaspace(sa);
                                else if(type==SPACE_TIME)
                                        init_timespace(sa);
+                               else if(type==SPACE_NODE)
+                                       init_nodespace(sa);
 
                                sl= sa->spacedata.first;
                                sl->area= sa;
@@ -4459,7 +4608,10 @@ void freespacelist(ListBase *lb)
                }
                else if(sl->spacetype==SPACE_BUTS) {
                        SpaceButs *buts= (SpaceButs*) sl;
-                       if(buts->rect) MEM_freeN(buts->rect);
+                       if(buts->ri) { 
+                               if (buts->ri->rect) MEM_freeN(buts->ri->rect);
+                               MEM_freeN(buts->ri);
+                       }
                        if(G.buts==buts) G.buts= NULL;
                }
                else if(sl->spacetype==SPACE_IPO) {
@@ -4500,6 +4652,9 @@ void freespacelist(ListBase *lb)
                else if(sl->spacetype==SPACE_SOUND) {
                        free_soundspace((SpaceSound *)sl);
                }
+               else if(sl->spacetype==SPACE_NODE) {
+/*                     SpaceNode *snode= (SpaceNode *)sl; */
+               }
        }
 
        BLI_freelistN(lb);
@@ -4531,6 +4686,10 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
                }
                else if(sl->spacetype==SPACE_TEXT) {
                }
+               else if(sl->spacetype==SPACE_NODE) {
+                       SpaceNode *snode= (SpaceNode *)sl;
+                       snode->nodetree= NULL;
+               }
                /* __PINFAKE */
 /*             else if(sfile->spacetype==SPACE_ACTION) {
                        SpaceAction *sa= (SpaceAction *)sfile;
@@ -4550,7 +4709,7 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
 
                if(sl->spacetype==SPACE_BUTS) {
                        SpaceButs *buts= (SpaceButs *)sl;
-                       buts->rect= NULL;
+                       buts->ri= NULL;
                }
                else if(sl->spacetype==SPACE_IPO) {
                        SpaceIpo *si= (SpaceIpo *)sl;
@@ -4786,6 +4945,12 @@ void allqueue(unsigned short event, short val)
                                        scrarea_queue_winredraw(sa);
                                }
                                break;
+                       case REDRAWNODE:
+                               if(sa->spacetype==SPACE_NODE) {
+                                       scrarea_queue_headredraw(sa);
+                                       scrarea_queue_winredraw(sa);
+                               }
+                               break;
                        case REDRAWANIM:
                                if ELEM6(sa->spacetype, SPACE_IPO, SPACE_SOUND, SPACE_TIME, SPACE_NLA, SPACE_ACTION, SPACE_SEQ) {
                                        scrarea_queue_winredraw(sa);
@@ -5093,3 +5258,15 @@ SpaceType *spacetime_get_type(void)
        
        return st;
 }
+
+SpaceType *spacenode_get_type(void)
+{
+       static SpaceType *st= NULL;
+       
+       if (!st) {
+               st= spacetype_new("Node");
+               spacetype_set_winfuncs(st, drawnodespace, changeview2dspace, winqreadnodespace);
+       }
+       
+       return st;
+}