Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2009-07-24 16:43:59 +0400
committerTon Roosendaal <ton@blender.org>2009-07-24 16:43:59 +0400
commit6abddb0fc4ca483f03e5a111c558824493006af5 (patch)
treea37ee42c3ebdfa7da10237936ff61f9c0264a5f1 /source/blender/windowmanager
parent1844fc7057fcc342c4bc9f4e1385bc97a2bd33e6 (diff)
2.5
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.
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r--source/blender/windowmanager/WM_api.h11
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c9
-rw-r--r--source/blender/windowmanager/intern/wm_files.c8
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c56
-rw-r--r--source/blender/windowmanager/intern/wm_window.c168
-rw-r--r--source/blender/windowmanager/wm.h2
-rw-r--r--source/blender/windowmanager/wm_window.h1
7 files changed, 206 insertions, 49 deletions
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 56ae220f7f0..0a68d2c9053 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -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);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 11b8f7f8c6f..e9affbac87a 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -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);
}
}
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 2019906bd5e..ffaa315f04e 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -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);
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index 6dd150a3416..0fd658dbb64 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -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)
{
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 2d320458543..5816fbb0667 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -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);
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index 36219cf3743..a7529157072 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -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 */
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index 45fa9bf6cf7..c2a2b00b796 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.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);