2.5
authorTon Roosendaal <ton@blender.org>
Sat, 7 Feb 2009 19:37:29 +0000 (19:37 +0000)
committerTon Roosendaal <ton@blender.org>
Sat, 7 Feb 2009 19:37:29 +0000 (19:37 +0000)
- Screen browse button back

- Several fixes in using screens in more windows.
  Still has loose ends, but things are definitely more stable!

13 files changed:
source/blender/blenloader/intern/readfile.c
source/blender/editors/include/ED_screen.h
source/blender/editors/screen/area.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_intern.h
source/blender/editors/screen/screen_ops.c
source/blender/editors/space_info/info_header.c
source/blender/makesdna/DNA_space_types.h
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_window.c

index de920ff9f256bb44ceb8eb0b7eb8437e420bdcf2..d22fc83f1e45bcdb79ca022b9ea3ab578ae5a79c 100644 (file)
@@ -4516,7 +4516,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                /* 2.50: we now always add spacedata for info */
                if(sa->spacedata.first==NULL) {
                        SpaceInfo *sinfo= MEM_callocN(sizeof(SpaceInfo), "spaceinfo");
-                       sa->spacetype= SPACE_INFO;
+                       sa->spacetype= sinfo->spacetype= SPACE_INFO;
                        BLI_addtail(&sa->spacedata, sinfo);
                }
                /* add local view3d too */
index 122da3223314d6cba256808f5e6282aa762db2cb..ce53ac78d20715d1fa9a45749179df4d0a073a86 100644 (file)
@@ -78,6 +78,7 @@ void  ED_screen_draw(struct wmWindow *win);
 void   ED_screen_refresh(struct wmWindowManager *wm, struct wmWindow *win);
 void   ED_screen_do_listen(struct wmWindow *win, struct wmNotifier *note);
 bScreen *ED_screen_duplicate(struct wmWindow *win, struct bScreen *sc);
+void   ED_screen_set(struct bContext *C, struct bScreen *sc);
 void   ED_screen_set_subwinactive(struct wmWindow *win, struct wmEvent *event);
 void   ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen);
 void   ED_screen_animation_timer(struct bContext *C, int enable);
index 347de2e8b6b628da09a41c3e928d2b7022ff5ba2..01ae32e78f6c3484459a13094edf1ce04418a901 100644 (file)
@@ -642,6 +642,10 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space)
        else {
                BKE_spacedata_freelist(&sa1->spacedata);
                BKE_spacedata_copylist(&sa1->spacedata, &sa2->spacedata);
+               
+               if(sa1->spacedata.first==NULL) {
+                       printf("copy data error\n");
+               }
        }
        
        /* regions */
index 76b20c51fc24a09ec766c74a5b9491f0148ed97c..800a618e89e7c69d06038249127953562e3a30dd 100644 (file)
@@ -411,6 +411,7 @@ bScreen *screen_add(wmWindow *win, Scene *scene, char *name)
        sc= alloc_libblock(&G.main->screen, ID_SCR, name);
        sc->scene= scene;
        sc->do_refresh= 1;
+       sc->winid= win->winid;
        
        sv1= screen_addvert(sc, 0, 0);
        sv2= screen_addvert(sc, 0, win->sizey-1);
@@ -907,6 +908,10 @@ bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc)
        /* set in window */
        win->screen= newsc;
        
+       /* store identifier */
+       win->screen->winid= win->winid;
+       BLI_strncpy(win->screenname, win->screen->id.name+2, 21);
+
        return newsc;
 }
 
@@ -1088,12 +1093,20 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
                WM_event_remove_window_timer(window, screen->animtimer);
        screen->animtimer= NULL;
        
+       if(screen->mainwin)
+               wm_subwindow_close(window, screen->mainwin);
+       screen->mainwin= 0;
+       screen->subwinactive= 0;
+       
        for(ar= screen->regionbase.first; ar; ar= ar->next)
                ED_region_exit(C, ar);
 
        for(sa= screen->areabase.first; sa; sa= sa->next)
                ED_area_exit(C, sa);
 
+       /* mark it available for use for other windows */
+       screen->winid= 0;
+       
        CTX_wm_window_set(C, prevwin);
 }
 
@@ -1195,13 +1208,26 @@ int ED_screen_area_active(const bContext *C)
 
 /* operator call, WM + Window + screen already existed before */
 /* Do NOT call in area/region queues! */
-void ed_screen_set(bContext *C, bScreen *sc)
+void ED_screen_set(bContext *C, bScreen *sc)
 {
+       wmWindow *win= CTX_wm_window(C);
        bScreen *oldscreen= CTX_wm_screen(C);
+       ID *id;
+       
+       /* validate screen, it's called with notifier reference */
+       for(id= CTX_data_main(C)->screen.first; id; id= id->next)
+               if(sc == (bScreen *)id)
+                       break;
+       if(id==NULL) 
+               return;
+       
+       /* check for valid winid */
+       if(sc->winid!=0 && sc->winid!=win->winid)
+               return;
        
        if(sc->full) {                          /* find associated full */
                bScreen *sc1;
-               for(sc1= G.main->screen.first; sc1; sc1= sc1->id.next) {
+               for(sc1= CTX_data_main(C)->screen.first; sc1; sc1= sc1->id.next) {
                        ScrArea *sa= sc1->areabase.first;
                        if(sa->full==sc) {
                                sc= sc1;
@@ -1212,7 +1238,6 @@ void ed_screen_set(bContext *C, bScreen *sc)
        }
        
        if (oldscreen != sc) {
-               wmWindow *win= CTX_wm_window(C);
                wmTimer *wt= oldscreen->animtimer;
                
                /* we put timer to sleep, so screen_exit has to think there's no timer */
@@ -1226,6 +1251,9 @@ void ed_screen_set(bContext *C, bScreen *sc)
                win->screen= sc;
                CTX_wm_window_set(C, win);      // stores C->wm.screen... hrmf
                
+               /* prevent multiwin errors */
+               sc->winid= win->winid;
+               
                ED_screen_refresh(CTX_wm_manager(C), CTX_wm_window(C));
                WM_event_add_notifier(C, NC_WINDOW, NULL);
        }
@@ -1274,7 +1302,7 @@ void ed_screen_fullarea(bContext *C, ScrArea *sa)
                        sc->animtimer= oldscreen->animtimer;
                        oldscreen->animtimer= NULL;
                        
-                       ed_screen_set(C, sc);
+                       ED_screen_set(C, sc);
                        
                        free_screen(oldscreen);
                        free_libblock(&G.main->screen, oldscreen);
@@ -1292,6 +1320,7 @@ void ed_screen_fullarea(bContext *C, ScrArea *sa)
                oldscreen->full = SCREENFULL;
                
                sc= screen_add(CTX_wm_window(C), CTX_data_scene(C), "temp");
+               sc->full = SCREENFULL; // XXX
                
                /* timer */
                sc->animtimer= oldscreen->animtimer;
@@ -1307,9 +1336,9 @@ void ed_screen_fullarea(bContext *C, ScrArea *sa)
 
                sa->full= oldscreen;
                newa->full= oldscreen;
-               newa->next->full= oldscreen;
+               newa->next->full= oldscreen; // XXX
 
-               ed_screen_set(C, sc);
+               ED_screen_set(C, sc);
        }
 
        /* XXX bad code: setscreen() ends with first area active. fullscreen render assumes this too */
index 338907958c4ab9a13be42d264ed6d0e7aebb2802..208e7a3f3dcc1be27ba139483e5807f1938492ff 100644 (file)
@@ -52,7 +52,6 @@ ScrEdge               *screen_find_active_scredge(bScreen *sc, int mx, int my);
 
 AZone          *is_in_area_actionzone(ScrArea *sa, int x, int y);
 
-void           ed_screen_set(bContext *C, bScreen *sc);
 void           ed_screen_fullarea(bContext *C, ScrArea *sa);
 
 /* screen_context.c */
index cfb4e2220a43d337ffbba33cc528a18896cc4562..130d5d6ca76a31bfc6e255ddd97e62498a09b600 100644 (file)
@@ -1025,6 +1025,7 @@ void SCREEN_OT_frame_offset(wmOperatorType *ot)
 static int screen_set_exec(bContext *C, wmOperator *op)
 {
        bScreen *screen= CTX_wm_screen(C);
+       int tot= BLI_countlist(&CTX_data_main(C)->screen);
        int delta= RNA_int_get(op->ptr, "delta");
        
        /* this screen is 'fake', solve later XXX */
@@ -1032,19 +1033,27 @@ static int screen_set_exec(bContext *C, wmOperator *op)
                return OPERATOR_CANCELLED;
        
        if(delta==1) {
-               screen= screen->id.next;
-               if(screen==NULL) screen= CTX_data_main(C)->screen.first;
+               while(tot--) {
+                       screen= screen->id.next;
+                       if(screen==NULL) screen= CTX_data_main(C)->screen.first;
+                       if(screen->winid==0 && screen->full==0)
+                               break;
+               }
        }
        else if(delta== -1) {
-               screen= screen->id.prev;
-               if(screen==NULL) screen= CTX_data_main(C)->screen.last;
+               while(tot--) {
+                       screen= screen->id.prev;
+                       if(screen==NULL) screen= CTX_data_main(C)->screen.last;
+                       if(screen->winid==0 && screen->full==0)
+                               break;
+               }
        }
        else {
                screen= NULL;
        }
        
        if(screen) {
-               ed_screen_set(C, screen);
+               ED_screen_set(C, screen);
                return OPERATOR_FINISHED;
        }
        return OPERATOR_CANCELLED;
index 59e30d87407aa0ecf802c7a447444ed67c1bce48..096374a82c485b4cd4fb6b3e05713eed3bf040b7 100644 (file)
@@ -103,10 +103,66 @@ static void do_info_buttons(bContext *C, void *arg, int event)
        }
 }
 
+static void screen_idpoin_handle(bContext *C, ID *id, int event)
+{
+       
+       switch(event) {
+               case UI_ID_BROWSE:
+                       /* exception: can't set screens inside of area/region handers */
+                       WM_event_add_notifier(C, NC_SCREEN|ND_SCREENBROWSE, id);
+                       break;
+               case UI_ID_DELETE:
+                       ED_undo_push(C, "");
+                       break;
+               case UI_ID_RENAME:
+                       break;
+               case UI_ID_ADD_NEW:
+                       /* XXX not implemented */
+                       break;
+               case UI_ID_OPEN:
+                       /* XXX not implemented */
+                       break;
+               case UI_ID_ALONE:
+                       /* XXX not implemented */
+                       break;
+               case UI_ID_PIN:
+                       break;
+       }
+}
+
+static void scene_idpoin_handle(bContext *C, ID *id, int event)
+{
+       
+       switch(event) {
+               case UI_ID_BROWSE:
+                       WM_event_add_notifier(C, NC_SCREEN|ND_SCENEBROWSE, CTX_wm_screen(C));
+                       break;
+               case UI_ID_DELETE:
+                       ED_undo_push(C, "");
+                       break;
+               case UI_ID_RENAME:
+                       break;
+               case UI_ID_ADD_NEW:
+                       /* XXX not implemented */
+                       break;
+               case UI_ID_OPEN:
+                       /* XXX not implemented */
+                       break;
+               case UI_ID_ALONE:
+                       /* XXX not implemented */
+                       break;
+               case UI_ID_PIN:
+                       break;
+       }
+}
+
 
 void info_header_buttons(const bContext *C, ARegion *ar)
 {
+       wmWindow *win= CTX_wm_window(C);
+       bScreen *screen= CTX_wm_screen(C);
        ScrArea *sa= CTX_wm_area(C);
+       SpaceInfo *si= sa->spacedata.first;
        uiBlock *block;
        int xco, yco= 3;
        
@@ -147,6 +203,17 @@ void info_header_buttons(const bContext *C, ARegion *ar)
        }
        
        uiBlockSetEmboss(block, UI_EMBOSS);
+       
+       if(screen->full==NULL) {
+               si->screen= win->screen;
+               xco= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID**)&si->screen, ID_SCR, NULL, xco, yco,
+                                                screen_idpoin_handle, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_DELETE);
+               xco += 8;
+               si->scene= screen->scene;
+               xco= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID**)&si->scene, ID_SCE, NULL, xco, yco,
+                                                        scene_idpoin_handle, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_DELETE);
+               xco += 8;
+       }       
 
        if(WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C))) {
                uiDefIconTextBut(block, BUT, B_STOPRENDER, ICON_REC, "Render", xco+5,yco,75,19, NULL, 0.0f, 0.0f, 0, 0, "Stop rendering");
index 63ad5015649257177fc7503513c6181565f9a98f..a1d8c5cd13b648f0ade04b7acd409631836eb722 100644 (file)
@@ -52,6 +52,8 @@ struct FileList;
 struct bGPdata;
 struct bDopeSheet;
 struct FileSelectParams;
+struct bScreen;
+struct Scene;
 struct wmOperator;
 struct wmTimer;
 
@@ -75,7 +77,11 @@ typedef struct SpaceInfo {
        int spacetype;
        float blockscale;
 
-       short blockhandler[8];
+       short blockhandler[8];          /* XXX depricate this */
+       
+       struct bScreen *screen;         /* browse screen */
+       struct Scene *scene;            /* browse scene */
+       
 } SpaceInfo;
 
 /* 'Graph' Editor (formerly known as the IPO Editor) */
index 75b27505995727f33ebbb3ede8dd60a0a61238ec..1ace7bce09cf9648fc16dd54cdf4855ef74cd063 100644 (file)
@@ -157,10 +157,14 @@ typedef struct wmNotifier {
 /* data type, 256 entries is enough, it can overlap */
 #define NOTE_DATA                      0x00FF0000
 
-       /* windowmanager */
+       /* NC_WM windowmanager */
 #define ND_FILEREAD                    (1<<16)
 
-       /* Scene */
+       /* NC_SCREEN screen */
+#define ND_SCREENBROWSE                (1<<16)
+#define ND_SCENEBROWSE         (2<<16)
+
+       /* NC_SCENE Scene */
 #define        ND_MARKERS                      (2<<16)
 #define        ND_FRAME                        (3<<16)
 #define        ND_RENDER_OPTIONS       (4<<16)
@@ -172,7 +176,7 @@ typedef struct wmNotifier {
 #define ND_RENDER_RESULT       (10<<16)
 #define ND_COMPO_RESULT                (11<<16)
 
-       /* Object */
+       /* NC_OBJECT Object */
 #define        ND_TRANSFORM            (16<<16)
 #define ND_OB_SHADING          (17<<16)
 #define ND_POSE                                (18<<16)
@@ -184,11 +188,11 @@ typedef struct wmNotifier {
 #define ND_KEYS                                (24<<16)
 #define ND_GEOM_DATA           (25<<16)
 
-       /* Material */
+       /* NC_MATERIAL Material */
 #define        ND_SHADING                      (30<<16)
 #define        ND_SHADING_DRAW         (31<<16)
 
-       /* Lamp */
+       /* NC_LAMP Lamp */
 #define        ND_LIGHTING                     (44<<16)
 #define        ND_LIGHTING_DRAW        (45<<16)
 #define ND_SKY                         (46<<16)
index 0b00d955a8aa8b293e593e6812b4dc725c1bf68e..56d8788fdcb7283362eb801dd1d3e3ba698c0d9e 100644 (file)
@@ -131,8 +131,9 @@ void wm_add_default(bContext *C)
        CTX_wm_manager_set(C, wm);
        win= wm_window_new(C);
        win->screen= screen;
-       if(screen)
-               BLI_strncpy(win->screenname, screen->id.name+2, 21);
+       screen->winid= win->winid;
+       BLI_strncpy(win->screenname, screen->id.name+2, 21);
+       
        wm->winactive= win;
        wm_window_make_drawable(C, win); 
 }
index 7c9e0d905bf747cc6e0bf873f73941c57a23b52a..def9d7351acda14581348a3f9c088d3b091ea159 100644 (file)
@@ -130,20 +130,27 @@ void wm_event_do_notifiers(bContext *C)
        if(wm==NULL)
                return;
        
-       /* cache & catch WM level notifiers, such as frame change */
+       /* cache & catch WM level notifiers, such as frame change, scene/screen set */
        /* XXX todo, multiwindow scenes */
        for(win= wm->windows.first; win; win= win->next) {
                int do_anim= 0;
                
+               CTX_wm_window_set(C, win);
+               
                for(note= wm->queue.first; note; note= note->next) {
-                       if(note->window==win)
-                               if(note->category==NC_SCENE)
+                       if(note->window==win) {
+                               if(note->category==NC_SCREEN) {
+                                       if(note->data==ND_SCREENBROWSE)
+                                               ED_screen_set(C, note->reference);      // XXX hrms, think this over!
+                               }
+                               else if(note->category==NC_SCENE) {
                                        if(note->data==ND_FRAME)
                                                do_anim= 1;
+                               }
+                       }
                }
                if(do_anim) {
                        /* depsgraph gets called, might send more notifiers */
-                       CTX_wm_window_set(C, win);
                        ED_update_for_newframe(C, 1);
                }
        }
index 4ff549c06dafa36e64a09577827689535028659c..04583c45ec03808539a488c4251591f700d0b394 100644 (file)
@@ -449,20 +449,23 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist)
                
                /* we've read file without wm..., keep current one entirely alive */
                if(G.main->wm.first==NULL) {
+                       bScreen *screen= CTX_wm_screen(C);
+                       
                        /* match oldwm to new dbase, only old files */
                        
                        for(wm= oldwmlist->first; wm; wm= wm->id.next) {
                                
                                for(win= wm->windows.first; win; win= win->next) {
                                        /* all windows get active screen from file */
-                                       win->screen= CTX_wm_screen(C);
-                                       BLI_strncpy(win->screenname, win->screen->id.name+2, 21);
+                                       if(screen->winid==0)
+                                               win->screen= screen;
+                                       else 
+                                               win->screen= ED_screen_duplicate(win, screen);
                                        
-                                       if(win->screen->winid==0)
-                                               win->screen->winid= win->winid;
+                                       BLI_strncpy(win->screenname, win->screen->id.name+2, 21);
+                                       win->screen->winid= win->winid;
                                }
                        }
-                       /* XXX still solve, case where multiple windows open */
                        
                        G.main->wm= *oldwmlist;
                        
index e5af93f3dd814b8e206ca5cc4febf138f12165fb..67eb043b1cfb857ed3a9bc8d52d0d0c8d461cee5 100644 (file)
@@ -123,7 +123,7 @@ void wm_window_free(bContext *C, wmWindow *win)
 static int find_free_winid(wmWindowManager *wm)
 {
        wmWindow *win;
-       int id= 0;
+       int id= 1;
        
        for(win= wm->windows.first; win; win= win->next)
                if(id <= win->winid)
@@ -155,8 +155,8 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig)
        win->sizex= winorig->sizex;
        win->sizey= winorig->sizey;
        
-       win->screen= ED_screen_duplicate(win, winorig->screen);
-       BLI_strncpy(win->screenname, win->screen->id.name+2, 21);
+       /* duplicate assigns to window */
+       ED_screen_duplicate(win, winorig->screen);
        win->screen->do_refresh= 1;
        win->screen->do_draw= 1;