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.
This commit is contained in:
Ton Roosendaal 2009-07-24 12:43:59 +00:00
parent 1844fc7057
commit 6abddb0fc4
13 changed files with 325 additions and 86 deletions

@ -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 */

@ -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 */

@ -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);

@ -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);

@ -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);

@ -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

@ -53,6 +53,15 @@ void WM_main (struct bContext *C);
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);
int WM_write_homefile (struct bContext *C, struct wmOperator *op);

@ -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)
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);
}
}
}

@ -605,9 +605,15 @@ 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 */

@ -252,11 +252,9 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *steve)
}
}
void WM_jobs_stop_all(wmWindowManager *wm)
/* stop job, free data completely */
static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *steve)
{
wmJob *steve= wm->jobs.first;
for(; steve; steve= steve->next) {
if(steve->running) {
/* signal job to end */
steve->stop= 1;
@ -269,12 +267,23 @@ void WM_jobs_stop_all(wmWindowManager *wm)
steve->free(steve->customdata);
if(steve->run_customdata)
steve->run_free(steve->run_customdata);
/* remove steve */
BLI_remlink(&wm->jobs, steve);
MEM_freeN(steve);
}
BLI_freelistN(&wm->jobs);
void WM_jobs_stop_all(wmWindowManager *wm)
{
wmJob *steve;
while((steve= wm->jobs.first))
wm_jobs_kill_job(wm, steve);
}
/* 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)
{

@ -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,12 +217,27 @@ 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)
{
/* handle the 'temp' window */
if(win->screen && win->screen->full==SCREENTEMP) {
GHOST_SetTitle(win->ghostwin, "Blender");
}
else {
/* 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");
@ -211,7 +260,7 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win)
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);

@ -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 */

@ -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);