2.5
authorTon Roosendaal <ton@blender.org>
Fri, 24 Jul 2009 12:43:59 +0000 (12:43 +0000)
committerTon Roosendaal <ton@blender.org>
Fri, 24 Jul 2009 12:43:59 +0000 (12:43 +0000)
New feature: allowing to open temporarily windows for output.
Implemented for:

- Render output (use output menu "new window" option).
- User Preferences (alt+U, plus added in 'File' menu)

Currently the window opens where your mouse is. The Render window
works as usual, with ESC or F11 moving it to back or front again.
That allows the window position to remain where you moved it on
new renders.
If you close a render window when it renders, the render thread
will be killed.

User prefs show 'info window' now... i thought we'd use outliner?
Anyhoo, I've made the 'save settings' to close the 2nd window as
well.

Opening a secondary file window for save I'll check on later,
this has to be checked with the current event system still.

the WM_window_open_temp() api call for this maintains currently
a *single* temp window. If you have a render window open, and call
for the preferences, the render window will be used for it. And
the other way around.

On closing the blender window, the temp windows close automatically
when there's no regular window open, and blender quits.

13 files changed:
source/blender/editors/include/ED_screen.h
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_image/image_draw.c
source/blender/makesdna/DNA_screen_types.h
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_jobs.c
source/blender/windowmanager/intern/wm_window.c
source/blender/windowmanager/wm.h
source/blender/windowmanager/wm_window.h

index 204d2dcd59e89411b8bda02b4cdc1487030f3614..a2e8f3a4ec14141f46c42beb63c5b6d9864c18d8 100644 (file)
@@ -87,6 +87,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);
+bScreen *ED_screen_add(struct wmWindow *win, struct Scene *scene, char *name);
 void   ED_screen_set(struct bContext *C, struct bScreen *sc);
 void   ED_screen_set_scene(struct bContext *C, struct Scene *scene);
 void   ED_screen_set_subwinactive(struct wmWindow *win, struct wmEvent *event);
@@ -95,6 +96,8 @@ void  ED_screen_animation_timer(struct bContext *C, int redraws, int enable);
 int            ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type);
 void   ED_screen_full_prevspace(struct bContext *C);
 
+void   ED_screen_new_window(struct bContext *C, struct rcti *position, int type);
+
 /* anim */
 void   ED_update_for_newframe(const struct bContext *C, int mute);
 unsigned int ED_screen_view3d_layers(struct bScreen *screen);
@@ -143,5 +146,6 @@ int         ED_operator_posemode(struct bContext *C);
 #define ED_KEYMAP_ANIMATION    8
 #define ED_KEYMAP_FRAMES       16
 
+
 #endif /* ED_SCREEN_H */
 
index 8e667fe04385c6bfff50e4d6d0ab08ea6bfb0fc1..dd6bb09c1e4cc7d306fe2f9fa16385fffabe7f03 100644 (file)
@@ -54,6 +54,7 @@
 #include "ED_screen.h"
 #include "ED_screen_types.h"
 
+/* XXX actually should be not here... solve later */
 #include "wm_subwindow.h"
 
 #include "screen_intern.h"     /* own module include */
@@ -404,7 +405,7 @@ ScrArea *area_split(wmWindow *win, bScreen *sc, ScrArea *sa, char dir, float fac
 
 /* empty screen, with 1 dummy area without spacedata */
 /* uses window size */
-bScreen *screen_add(wmWindow *win, Scene *scene, char *name)
+bScreen *ED_screen_add(wmWindow *win, Scene *scene, char *name)
 {
        bScreen *sc;
        ScrVert *sv1, *sv2, *sv3, *sv4;
@@ -947,7 +948,7 @@ bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc)
        if(sc->full != SCREENNORMAL) return NULL; /* XXX handle this case! */
        
        /* make new empty screen: */
-       newsc= screen_add(win, sc->scene, sc->id.name+2);
+       newsc= ED_screen_add(win, sc->scene, sc->id.name+2);
        /* copy all data */
        screen_copy(newsc, sc);
        /* set in window */
@@ -1368,8 +1369,6 @@ void ED_screen_set_scene(bContext *C, Scene *scene)
        
        ED_update_for_newframe(C, 1);
        
-//     set_radglobal();
-       
        /* complete redraw */
        WM_event_add_notifier(C, NC_WINDOW, NULL);
        
@@ -1434,7 +1433,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= ED_screen_add(CTX_wm_window(C), CTX_data_scene(C), "temp");
                sc->full = SCREENFULL; // XXX
                
                /* timer */
index a0804f3e633a55230918981c78cef1bf0bd0b41a..2b3a816f8de4488bbdf6b01f37a4e6a806157036 100644 (file)
@@ -36,7 +36,6 @@ struct Scene;
 void           area_copy_data  (ScrArea *sa1, ScrArea *sa2, int swap_space);
 
 /* screen_edit.c */
-bScreen                *screen_add(struct wmWindow *win, struct Scene *scene, char *name);
 ScrEdge                *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2);
 ScrArea                *area_split(wmWindow *win, bScreen *sc, ScrArea *sa, char dir, float fac);
 int                    screen_area_join(bContext *C, bScreen* scr, ScrArea *sa1, ScrArea *sa2);
index dc46940a7335b4f0ea733e8ae7ea242a3db6f4e3..46023f278c68c29213bfe38a260c27cd31592a8d 100644 (file)
@@ -74,6 +74,8 @@
 #include "UI_interface.h"
 #include "UI_resources.h"
 
+#include "wm_window.h"
+
 #include "screen_intern.h"     /* own module include */
 
 #define KM_MODAL_CANCEL                1
@@ -502,7 +504,7 @@ static int actionzone_modal(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_RUNNING_MODAL;
 }
 
-void SCREEN_OT_actionzone(wmOperatorType *ot)
+static void SCREEN_OT_actionzone(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Handle area action zones";
@@ -668,7 +670,7 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, wmEvent *event)
        newwin= WM_window_open(C, &rect);
        
        /* allocs new screen and adds to newly created window, using window size */
-       newsc= screen_add(newwin, CTX_data_scene(C), sc->id.name+2);
+       newsc= ED_screen_add(newwin, CTX_data_scene(C), sc->id.name+2);
        newwin->screen= newsc;
        
        /* copy area to new screen */
@@ -921,7 +923,7 @@ static int area_move_modal(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_RUNNING_MODAL;
 }
 
-void SCREEN_OT_area_move(wmOperatorType *ot)
+static void SCREEN_OT_area_move(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Move area edges";
@@ -1237,7 +1239,7 @@ static EnumPropertyItem prop_direction_items[] = {
        {'v', "VERTICAL", 0, "Vertical", ""},
        {0, NULL, 0, NULL, NULL}};
 
-void SCREEN_OT_area_split(wmOperatorType *ot)
+static void SCREEN_OT_area_split(wmOperatorType *ot)
 {
        ot->name = "Split area";
        ot->idname = "SCREEN_OT_area_split";
@@ -1386,7 +1388,7 @@ static int frame_offset_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-void SCREEN_OT_frame_offset(wmOperatorType *ot)
+static void SCREEN_OT_frame_offset(wmOperatorType *ot)
 {
        ot->name = "Frame Offset";
        ot->idname = "SCREEN_OT_frame_offset";
@@ -1442,7 +1444,7 @@ static int screen_set_exec(bContext *C, wmOperator *op)
        return OPERATOR_CANCELLED;
 }
 
-void SCREEN_OT_screen_set(wmOperatorType *ot)
+static void SCREEN_OT_screen_set(wmOperatorType *ot)
 {
        ot->name = "Set Screen";
        ot->idname = "SCREEN_OT_screen_set";
@@ -1465,7 +1467,7 @@ static int screen_full_area_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-void SCREEN_OT_screen_full_area(wmOperatorType *ot)
+static void SCREEN_OT_screen_full_area(wmOperatorType *ot)
 {
        ot->name = "Toggle Make Area Fullscreen";
        ot->idname = "SCREEN_OT_screen_full_area";
@@ -1737,7 +1739,7 @@ static int area_join_modal(bContext *C, wmOperator *op, wmEvent *event)
 }
 
 /* Operator for joining two areas (space types) */
-void SCREEN_OT_area_join(wmOperatorType *ot)
+static void SCREEN_OT_area_join(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Join area";
@@ -1770,7 +1772,7 @@ static int repeat_last_exec(bContext *C, wmOperator *op)
        return OPERATOR_CANCELLED;
 }
 
-void SCREEN_OT_repeat_last(wmOperatorType *ot)
+static void SCREEN_OT_repeat_last(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Repeat Last";
@@ -1822,7 +1824,7 @@ static int repeat_history_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-void SCREEN_OT_repeat_history(wmOperatorType *ot)
+static void SCREEN_OT_repeat_history(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Repeat History";
@@ -1855,7 +1857,7 @@ static int redo_last_invoke(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_CANCELLED;
 }
 
-void SCREEN_OT_redo_last(wmOperatorType *ot)
+static void SCREEN_OT_redo_last(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Redo Last";
@@ -1898,7 +1900,7 @@ static int region_split_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-void SCREEN_OT_region_split(wmOperatorType *ot)
+static void SCREEN_OT_region_split(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Split Region";
@@ -1987,7 +1989,7 @@ static int region_foursplit_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-void SCREEN_OT_region_foursplit(wmOperatorType *ot)
+static void SCREEN_OT_region_foursplit(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Split Region in 4 Parts";
@@ -2025,7 +2027,7 @@ static int region_flip_exec(bContext *C, wmOperator *op)
 }
 
 
-void SCREEN_OT_region_flip(wmOperatorType *ot)
+static void SCREEN_OT_region_flip(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Flip Region";
@@ -2195,7 +2197,7 @@ static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_FINISHED;
 }
 
-void SCREEN_OT_animation_play(wmOperatorType *ot)
+static void SCREEN_OT_animation_play(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Animation player";
@@ -2244,7 +2246,7 @@ static int border_select_do(bContext *C, wmOperator *op)
        return 1;
 }
 
-void SCREEN_OT_border_select(wmOperatorType *ot)
+static void SCREEN_OT_border_select(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Border select";
@@ -2371,13 +2373,36 @@ static ScrArea *find_empty_image_area(bContext *C)
 }
 #endif // XXX not used
 
-static void screen_set_image_output(bContext *C)
+/* new window uses x,y to set position */
+static void screen_set_image_output(bContext *C, int mx, int my)
 {
        Scene *scene= CTX_data_scene(C);
        ScrArea *sa;
        SpaceImage *sima;
        
-       if(scene->r.displaymode==R_OUTPUT_SCREEN) {
+       if(scene->r.displaymode==R_OUTPUT_WINDOW) {
+               rcti rect;
+               int sizex, sizey;
+               
+               sizex= 10 + (scene->r.xsch*scene->r.size)/100;
+               sizey= 40 + (scene->r.ysch*scene->r.size)/100;
+               
+               /* arbitrary... miniature image window views don't make much sense */
+               if(sizex < 320) sizex= 320;
+               if(sizey < 256) sizey= 256;
+               
+               /* XXX some magic to calculate postition */
+               rect.xmin= mx + CTX_wm_window(C)->posx - sizex/2;
+               rect.ymin= my + CTX_wm_window(C)->posy - sizey/2;
+               rect.xmax= rect.xmin + sizex;
+               rect.ymax= rect.ymin + sizey;
+               
+               /* changes context! */
+               WM_window_open_temp(C, &rect, WM_WINDOW_RENDER);
+               
+               sa= CTX_wm_area(C);
+       }
+       else if(scene->r.displaymode==R_OUTPUT_SCREEN) {
                /* this function returns with changed context */
                ED_screen_full_newspace(C, CTX_wm_area(C), SPACE_IMAGE);
                sa= CTX_wm_area(C);
@@ -2710,7 +2735,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
        // store spare
        
        /* ensure at least 1 area shows result */
-       screen_set_image_output(C);
+       screen_set_image_output(C, event->x, event->y);
 
        /* job custom data */
        rj= MEM_callocN(sizeof(RenderJob), "render job");
@@ -2758,7 +2783,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
 
 
 /* contextual render, using current scene, view3d? */
-void SCREEN_OT_render(wmOperatorType *ot)
+static void SCREEN_OT_render(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Render";
@@ -2782,7 +2807,12 @@ static int render_view_cancel_exec(bContext *C, wmOperator *unused)
        ScrArea *sa= CTX_wm_area(C);
        SpaceImage *sima= sa->spacedata.first;
        
-       if(sima->flag & SI_PREVSPACE) {
+       /* test if we have a temp screen in front */
+       if(CTX_wm_window(C)->screen->full==SCREENTEMP) {
+               wm_window_lower(CTX_wm_window(C));
+       }
+       /* determine if render already shows */
+       else if(sima->flag & SI_PREVSPACE) {
                sima->flag &= ~SI_PREVSPACE;
                
                if(sima->flag & SI_FULLWINDOW) {
@@ -2800,7 +2830,7 @@ static int render_view_cancel_exec(bContext *C, wmOperator *unused)
        return OPERATOR_FINISHED;
 }
 
-void SCREEN_OT_render_view_cancel(struct wmOperatorType *ot)
+static void SCREEN_OT_render_view_cancel(struct wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Cancel Render View";
@@ -2813,12 +2843,16 @@ void SCREEN_OT_render_view_cancel(struct wmOperatorType *ot)
 
 /* *********************** show render viewer *************** */
 
-static int render_view_show_exec(bContext *C, wmOperator *unused)
+static int render_view_show_invoke(bContext *C, wmOperator *unused, wmEvent *event)
 {
        ScrArea *sa= find_area_showing_r_result(C);
-       
+
+       /* test if we have a temp screen in front */
+       if(CTX_wm_window(C)->screen->full==SCREENTEMP) {
+               wm_window_lower(CTX_wm_window(C));
+       }
        /* determine if render already shows */
-       if(sa) {
+       else if(sa) {
                SpaceImage *sima= sa->spacedata.first;
                
                if(sima->flag & SI_PREVSPACE) {
@@ -2835,20 +2869,58 @@ static int render_view_show_exec(bContext *C, wmOperator *unused)
                }
        }
        else {
-               screen_set_image_output(C);
+               screen_set_image_output(C, event->x, event->y);
        }
        
        return OPERATOR_FINISHED;
 }
 
-void SCREEN_OT_render_view_show(struct wmOperatorType *ot)
+static void SCREEN_OT_render_view_show(struct wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Show/Hide Render View";
        ot->idname= "SCREEN_OT_render_view_show";
        
        /* api callbacks */
-       ot->exec= render_view_show_exec;
+       ot->invoke= render_view_show_invoke;
+       ot->poll= ED_operator_screenactive;
+}
+
+/* *********** show user pref window ****** */
+
+static int userpref_show_invoke(bContext *C, wmOperator *unused, wmEvent *event)
+{
+       ScrArea *sa;
+       rcti rect;
+       int sizex, sizey;
+       
+       sizex= 640;
+       sizey= 480;
+       
+       /* some magic to calculate postition */
+       rect.xmin= event->x + CTX_wm_window(C)->posx - sizex/2;
+       rect.ymin= event->y + CTX_wm_window(C)->posy - sizey/2;
+       rect.xmax= rect.xmin + sizex;
+       rect.ymax= rect.ymin + sizey;
+       
+       /* changes context! */
+       WM_window_open_temp(C, &rect, WM_WINDOW_USERPREFS);
+       
+       sa= CTX_wm_area(C);
+       
+       
+       return OPERATOR_FINISHED;
+}
+
+
+static void SCREEN_OT_userpref_show(struct wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Show/Hide User Preferences";
+       ot->idname= "SCREEN_OT_userpref_show";
+       
+       /* api callbacks */
+       ot->invoke= userpref_show_invoke;
        ot->poll= ED_operator_screenactive;
 }
 
@@ -2879,6 +2951,7 @@ void ED_operatortypes_screen(void)
        WM_operatortype_append(SCREEN_OT_screen_full_area);
        WM_operatortype_append(SCREEN_OT_screenshot);
        WM_operatortype_append(SCREEN_OT_screencast);
+       WM_operatortype_append(SCREEN_OT_userpref_show);
        
        /*frame changes*/
        WM_operatortype_append(SCREEN_OT_frame_offset);
@@ -2981,6 +3054,9 @@ void ED_keymap_screen(wmWindowManager *wm)
        WM_keymap_add_item(keymap, "SCREEN_OT_render_view_cancel", ESCKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "SCREEN_OT_render_view_show", F11KEY, KM_PRESS, 0, 0);
        
+       /* user prefs */
+       WM_keymap_add_item(keymap, "SCREEN_OT_userpref_show", UKEY, KM_PRESS, KM_ALT, 0);
+       
        /* Anim Playback ------------------------------------------------ */
        keymap= WM_keymap_listbase(wm, "Frames", 0, 0);
        
index da1f050cfd39659a037979a6693d3fd1d4e6bd5c..7050c7f6d7cc9b66a37c9a090e7ea9bb8eeae35b 100644 (file)
@@ -150,8 +150,10 @@ static void draw_render_info(Image *ima, ARegion *ar)
        
        /* clear header rect */
        UI_GetThemeColor3fv(TH_BACK, colf);
-       glColor3f(colf[0]+0.1f, colf[1]+0.1f, colf[2]+0.1f);
+       glEnable(GL_BLEND);
+       glColor4f(colf[0]+0.1f, colf[1]+0.1f, colf[2]+0.1f, 0.5f);
        glRecti(rect.xmin, rect.ymin, rect.xmax, rect.ymax+1);
+       glDisable(GL_BLEND);
        
        UI_ThemeColor(TH_TEXT_HI);
 
index cf10723017130e132564fe2467dae4ae0aacda28..e51da0c0818e55e820cc5a37b9d33ddb3311b8db 100644 (file)
@@ -186,6 +186,8 @@ typedef struct ARegion {
 #define SCREENNORMAL    0
 #define SCREENFULL      1
 #define SCREENAUTOPLAY  2
+#define SCREENTEMP             3
+
 
 /* Panel->snap - for snapping to screen edges */
 #define PNL_SNAP_NONE          0
index 56ae220f7f0ef982e171ffa69c2b37d3fcb19451..0a68d2c9053783814578e3fb11d19cf97d57e44d 100644 (file)
@@ -51,7 +51,16 @@ void         WM_init                         (struct bContext *C);
 void           WM_exit                         (struct bContext *C);
 void           WM_main                         (struct bContext *C);
 
-struct wmWindow        *WM_window_open         (struct bContext *C, struct rcti *rect);
+struct wmWindow        *WM_window_open (struct bContext *C, struct rcti *rect);
+
+                       /* defines for 'type' WM_window_open_temp */
+#define WM_WINDOW_RENDER               0
+#define WM_WINDOW_USERPREFS            1
+#define WM_WINDOW_FILESEL              2
+
+void           WM_window_open_temp     (struct bContext *C, struct rcti *position, int type);
+
+
 
                        /* files */
 int                    WM_read_homefile        (struct bContext *C, struct wmOperator *op);
index 11b8f7f8c6f8d4ee8b722185250ab41991b06f0d..e9affbac87a31858143294702e10e9d0a874c3aa 100644 (file)
@@ -513,8 +513,12 @@ static void wm_handler_op_context(bContext *C, wmEventHandler *handler)
                        for(sa= screen->areabase.first; sa; sa= sa->next)
                                if(sa==handler->op_area)
                                        break;
-                       if(sa==NULL)
-                               printf("internal error: handler (%s) has invalid area\n", handler->op->type->idname);
+                       if(sa==NULL) {
+                               /* when changing screen layouts with running modal handlers (like render display), this
+                                  is not an error to print */
+                               if(handler->op==NULL)
+                                       printf("internal error: handler (%s) has invalid area\n", handler->op->type->idname);
+                       }
                        else {
                                ARegion *ar;
                                CTX_wm_area_set(C, sa);
@@ -663,7 +667,6 @@ static void wm_event_modalkeymap(wmOperator *op, wmEvent *event)
                                        
                                event->type= EVT_MODAL_MAP;
                                event->val= kmi->propvalue;
-                               printf("found modal event %s %d\n", kmi->idname, kmi->propvalue);
                        }
                }
        }
index 2019906bd5e92ff71be95c066e1f022274a93549..ffaa315f04e2ad6208a764947af6fffeb2946cee 100644 (file)
@@ -605,11 +605,17 @@ void WM_write_file(bContext *C, char *target, int compress, ReportList *reports)
 /* operator entry */
 int WM_write_homefile(bContext *C, wmOperator *op)
 {
+       wmWindow *win= CTX_wm_window(C);
        char tstr[FILE_MAXDIR+FILE_MAXFILE];
        int write_flags;
        
+       /* check current window and close it if temp */
+       if(win->screen->full == SCREENTEMP) {
+               wm_window_close(C, win);
+       }
+       
        BLI_make_file_string("/", tstr, BLI_gethome(), ".B25.blend");
-               
+       
        /*  force save as regular blend file */
        write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
 
index 6dd150a3416c48fdc67ab8a7e42c7a031cf4b552..0fd658dbb64e06d8abf38f8b2e007052486ebca2 100644 (file)
@@ -252,29 +252,38 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *steve)
        }
 }
 
+/* stop job, free data completely */
+static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *steve)
+{
+       if(steve->running) {
+               /* signal job to end */
+               steve->stop= 1;
+               BLI_end_threads(&steve->threads);
+       }
+       
+       if(steve->wt)
+               WM_event_remove_window_timer(steve->win, steve->wt);
+       if(steve->customdata)
+               steve->free(steve->customdata);
+       if(steve->run_customdata)
+               steve->run_free(steve->run_customdata);
+       
+       /* remove steve */
+       BLI_remlink(&wm->jobs, steve);
+       MEM_freeN(steve);
+       
+}
+
 void WM_jobs_stop_all(wmWindowManager *wm)
 {
-       wmJob *steve= wm->jobs.first;
+       wmJob *steve;
        
-       for(; steve; steve= steve->next) {
-               if(steve->running) {
-                       /* signal job to end */
-                       steve->stop= 1;
-                       BLI_end_threads(&steve->threads);
-               }
-               
-               if(steve->wt)
-                       WM_event_remove_window_timer(steve->win, steve->wt);
-               if(steve->customdata)
-                       steve->free(steve->customdata);
-               if(steve->run_customdata)
-                       steve->run_free(steve->run_customdata);
-       }       
+       while((steve= wm->jobs.first))
+               wm_jobs_kill_job(wm, steve);
        
-       BLI_freelistN(&wm->jobs);
 }
 
-/* stops job(s) from this owner */
+/* signal job(s) from this owner to stop, timer is required to get handled */
 void WM_jobs_stop(wmWindowManager *wm, void *owner)
 {
        wmJob *steve;
@@ -285,6 +294,19 @@ void WM_jobs_stop(wmWindowManager *wm, void *owner)
                                steve->stop= 1;
 }
 
+/* kill job entirely, also removes timer itself */
+void wm_jobs_timer_ended(wmWindowManager *wm, wmTimer *wt)
+{
+       wmJob *steve;
+       
+       for(steve= wm->jobs.first; steve; steve= steve->next) {
+               if(steve->wt==wt) {
+                       wm_jobs_kill_job(wm, steve);
+                       return;
+               }
+       }
+}
+
 /* hardcoded to event TIMERJOBS */
 static int wm_jobs_timer(bContext *C, wmOperator *op, wmEvent *evt)
 {
index 2d3204585430e50136ebb0bcfc49cff5db51da8c..5816fbb0667114172fef3390356b8e8c937e36b5 100644 (file)
@@ -70,7 +70,7 @@ static int prefsizx= 0, prefsizy= 0, prefstax= 0, prefstay= 0;
 
 /* ******** win open & close ************ */
 
-
+/* XXX this one should correctly check for apple top header... */
 static void wm_get_screensize(int *width_r, int *height_r) 
 {
        unsigned int uiwidth;
@@ -81,6 +81,34 @@ static void wm_get_screensize(int *width_r, int *height_r)
        *height_r= uiheight;
 }
 
+/* keeps offset and size within monitor bounds */
+/* XXX solve dual screen... */
+static void wm_window_check_position(rcti *rect)
+{
+       int width, height, d;
+       
+       wm_get_screensize(&width, &height);
+       
+#ifdef __APPLE__
+       height -= 22;
+#endif
+       
+       if(rect->xmax > width) {
+               d= rect->xmax - width;
+               rect->xmax -= d;
+               rect->xmin -= d;
+       }
+       if(rect->ymax > height) {
+               d= rect->ymax - height;
+               rect->ymax -= d;
+               rect->ymin -= d;
+       }
+       
+       if(rect->xmin < 0) rect->xmin= 0;
+       if(rect->ymin < 0) rect->ymin= 0;
+}
+
+
 static void wm_ghostwindow_destroy(wmWindow *win) 
 {
        if(win->ghostwin) {
@@ -93,7 +121,7 @@ static void wm_ghostwindow_destroy(wmWindow *win)
    ED_screen_exit should have been called */
 void wm_window_free(bContext *C, wmWindow *win)
 {
-       wmTimer *wt;
+       wmTimer *wt, *wtnext;
        
        /* update context */
        if(C) {
@@ -107,14 +135,20 @@ void wm_window_free(bContext *C, wmWindow *win)
                        CTX_wm_window_set(C, NULL);
                
                WM_event_remove_handlers(C, &win->handlers);
+
+               /* end running jobs, a job end also removes its timer */
+               for(wt= win->timers.first; wt; wt= wtnext) {
+                       wtnext= wt->next;
+                       if(wt->event_type==TIMERJOBS)
+                               wm_jobs_timer_ended(wm, wt);
+               }
        }       
        
        if(win->eventstate) MEM_freeN(win->eventstate);
        
-       for(wt= win->timers.first; wt; wt= wt->next)
-               if(wt->customdata)
-                       MEM_freeN(wt->customdata);
-       BLI_freelistN(&win->timers);
+       /* timer removing, need to call this api function */
+       while((wt= win->timers.first))
+               WM_event_remove_window_timer(win, wt);
        
        wm_event_free_all(win);
        wm_subwindows_free(win);
@@ -174,7 +208,7 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig)
 }
 
 /* this is event from ghost, or exit-blender op */
-static void wm_window_close(bContext *C, wmWindow *win)
+void wm_window_close(bContext *C, wmWindow *win)
 {
        wmWindowManager *wm= CTX_wm_manager(C);
        BLI_remlink(&wm->windows, win);
@@ -183,35 +217,50 @@ static void wm_window_close(bContext *C, wmWindow *win)
        ED_screen_exit(C, win, win->screen);
        wm_window_free(C, win);
        
-       if(wm->windows.first==NULL)
+       /* check remaining windows */
+       if(wm->windows.first) {
+               for(win= wm->windows.first; win; win= win->next)
+                       if(win->screen->full!=SCREENTEMP)
+                               break;
+               /* in this case we close all */
+               if(win==NULL)
+                       WM_exit(C);
+       }
+       else
                WM_exit(C);
 }
 
 void wm_window_title(wmWindowManager *wm, wmWindow *win)
 {
-       /* this is set to 1 if you don't have .B.blend open */
-       if(G.save_over) {
-               char *str= MEM_mallocN(strlen(G.sce) + 16, "title");
+       /* handle the 'temp' window */
+       if(win->screen && win->screen->full==SCREENTEMP) {
+               GHOST_SetTitle(win->ghostwin, "Blender");
+       }
+       else {
                
-               if(wm->file_saved)
-                       sprintf(str, "Blender [%s]", G.sce);
+               /* this is set to 1 if you don't have .B.blend open */
+               if(G.save_over) {
+                       char *str= MEM_mallocN(strlen(G.sce) + 16, "title");
+                       
+                       if(wm->file_saved)
+                               sprintf(str, "Blender [%s]", G.sce);
+                       else
+                               sprintf(str, "Blender* [%s]", G.sce);
+                       
+                       GHOST_SetTitle(win->ghostwin, str);
+                       
+                       MEM_freeN(str);
+               }
                else
-                       sprintf(str, "Blender* [%s]", G.sce);
-               
-               GHOST_SetTitle(win->ghostwin, str);
-               
-               MEM_freeN(str);
-       }
-       else
-               GHOST_SetTitle(win->ghostwin, "Blender");
+                       GHOST_SetTitle(win->ghostwin, "Blender");
 
 #ifdef __APPLE__
-       if(wm->file_saved)
-               GHOST_SetWindowState(win->ghostwin, GHOST_kWindowStateUnModified);
-       else
-               GHOST_SetWindowState(win->ghostwin, GHOST_kWindowStateModified);
+               if(wm->file_saved)
+                       GHOST_SetWindowState(win->ghostwin, GHOST_kWindowStateUnModified);
+               else
+                       GHOST_SetWindowState(win->ghostwin, GHOST_kWindowStateModified);
 #endif
-
+       }
 }
 
 /* belongs to below */
@@ -334,6 +383,71 @@ wmWindow *WM_window_open(bContext *C, rcti *rect)
        return win;
 }
 
+/* uses screen->full tag to define what to do, currently it limits
+   to only one "temp" window for render out, preferences, filewindow, etc */
+/* type is #define in WM_api.h */
+
+void WM_window_open_temp(bContext *C, rcti *position, int type)
+{
+       wmWindow *win;
+       ScrArea *sa;
+       
+       /* changes rect to fit within desktop */
+       wm_window_check_position(position);
+       
+       /* test if we have a temp screen already */
+       for(win= CTX_wm_manager(C)->windows.first; win; win= win->next)
+               if(win->screen->full == SCREENTEMP)
+                       break;
+       
+       /* add new window? */
+       if(win==NULL) {
+               win= wm_window_new(C);
+               
+               win->posx= position->xmin;
+               win->posy= position->ymin;
+       }
+       
+       win->sizex= position->xmax - position->xmin;
+       win->sizey= position->ymax - position->ymin;
+       
+       if(win->ghostwin) {
+               wm_window_set_size(win, win->sizex, win->sizey) ;
+               wm_window_raise(win);
+       }
+       
+       /* add new screen? */
+       if(win->screen==NULL)
+               win->screen= ED_screen_add(win, CTX_data_scene(C), "temp");
+       win->screen->full = SCREENTEMP; 
+       
+       /* make window active, and validate/resize */
+       CTX_wm_window_set(C, win);
+       wm_check(C);
+       
+       /* ensure it shows the right spacetype editor */
+       sa= win->screen->areabase.first;
+       CTX_wm_area_set(C, sa);
+       
+       if(type==WM_WINDOW_RENDER) {
+               ED_area_newspace(C, sa, SPACE_IMAGE);
+       }
+       else {
+               ED_area_newspace(C, sa, SPACE_INFO);
+       }
+       
+       ED_screen_set(C, win->screen);
+       
+       if(sa->spacetype==SPACE_IMAGE)
+               GHOST_SetTitle(win->ghostwin, "Blender Render");
+       else if(ELEM(sa->spacetype, SPACE_OUTLINER, SPACE_INFO))
+               GHOST_SetTitle(win->ghostwin, "Blender User Preferences");
+       else if(sa->spacetype==SPACE_FILE)
+               GHOST_SetTitle(win->ghostwin, "Blender File View");
+       else
+               GHOST_SetTitle(win->ghostwin, "Blender");
+}
+
 
 /* ****************** Operators ****************** */
 
@@ -664,10 +778,12 @@ void WM_event_remove_window_timer(wmWindow *win, wmTimer *timer)
 {
        wmTimer *wt;
        
+       /* extra security check */
        for(wt= win->timers.first; wt; wt= wt->next)
                if(wt==timer)
                        break;
        if(wt) {
+               
                BLI_remlink(&win->timers, wt);
                if(wt->customdata)
                        MEM_freeN(wt->customdata);
index 36219cf37436c27b3dca46df8b6c7ffd8a61d9fb..a75291570724dfd9b25a9d8d68a5f72354244cb5 100644 (file)
@@ -66,7 +66,7 @@ void wm_gesture_tag_redraw(bContext *C);
 
 /* wm_jobs.h */
 void WM_OT_jobs_timer(struct wmOperatorType *ot);
-
+void wm_jobs_timer_ended(wmWindowManager *wm, wmTimer *wt);
 
 #endif /* WM_H */
 
index 45fa9bf6cf76600983923426eb9f1507807253ce..c2a2b00b79672f46579b4e58ba5f3949a24fab8f 100644 (file)
@@ -36,6 +36,7 @@ void          wm_ghost_init                   (bContext *C);
 
 wmWindow       *wm_window_new                  (bContext *C);
 void           wm_window_free                  (bContext *C, wmWindow *win);
+void           wm_window_close                 (bContext *C, wmWindow *win);
 
 void           wm_window_title                         (wmWindowManager *wm, wmWindow *win);
 void           wm_window_add_ghostwindows      (wmWindowManager *wm);