4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2008 Blender Foundation.
21 * All rights reserved.
24 * Contributor(s): Blender Foundation
26 * ***** END GPL LICENSE BLOCK *****
32 #include "MEM_guardedalloc.h"
34 #include "BLI_blenlib.h"
35 #include "BLI_arithb.h"
38 #include "BKE_global.h"
39 #include "BKE_screen.h"
40 #include "BKE_utildefines.h"
43 #include "ED_screen.h"
47 #include "wm_subwindow.h"
50 #include "BIF_glutil.h"
52 #include "BPY_extern.h"
54 #include "screen_intern.h"
56 /* general area and region code */
58 static void region_draw_emboss(ARegion *ar)
62 winx= ar->winrct.xmax-ar->winrct.xmin;
63 winy= ar->winrct.ymax-ar->winrct.ymin;
67 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
70 glColor4ub(0,0,0, 50);
71 sdrawline(winx, 0, winx, winy);
74 glColor4ub(0,0,0, 80);
75 sdrawline(0, 0, winx, 0);
78 glColor4ub(255,255,255, 60);
79 sdrawline(0, winy, winx, winy);
82 glColor4ub(255,255,255, 50);
83 sdrawline(0, 0, 0, winy);
85 glDisable( GL_BLEND );
89 void ED_region_do_listen(ARegion *ar, wmNotifier *note)
91 if(ar->type->listener)
92 ar->type->listener(ar, note);
95 if(note->type==WM_NOTE_REDRAW)
97 if(note->type==WM_NOTE_REFRESH)
102 void ED_region_do_draw(bContext *C, ARegion *ar)
104 ARegionType *at= ar->type;
106 wm_subwindow_set(C->window, ar->swinid);
108 if(ar->swinid && at->draw) {
112 float fac= 0.1*ar->swinid;
114 glClearColor(0.5, fac, 1.0f-fac, 0.0);
115 glClear(GL_COLOR_BUFFER_BIT);
118 glColor3f(fac, fac, fac);
119 glRecti(2, 2, 12, 12);
121 region_draw_emboss(ar);
127 void ED_region_do_refresh(bContext *C, ARegion *ar)
129 ARegionType *at= ar->type;
131 /* refresh can be called before window opened */
133 wm_subwindow_set(C->window, ar->swinid);
142 /* *************************************************************** */
145 static int rct_fits(rcti *rect, char dir, int size)
148 return rect->xmax-rect->xmin - size;
151 return rect->ymax-rect->ymin - size;
155 static void region_rect_recursive(ARegion *ar, rcti *remainder)
160 /* clear state flag first */
161 ar->flag &= ~RGN_FLAG_TOO_SMALL;
163 if(ar->size<ar->minsize)
164 ar->size= ar->minsize;
166 /* hidden is user flag */
167 if(ar->flag & RGN_FLAG_HIDDEN);
168 /* remainder is too small for any usage */
169 else if( rct_fits(remainder, 'v', 1)==0 || rct_fits(remainder, 'h', 1) < 0 ) {
170 ar->flag |= RGN_FLAG_TOO_SMALL;
172 else if(ar->alignment==RGN_ALIGN_NONE) {
173 /* typically last region */
174 ar->winrct= *remainder;
175 BLI_init_rcti(remainder, 0, 0, 0, 0);
177 else if(ar->alignment==RGN_ALIGN_TOP || ar->alignment==RGN_ALIGN_BOTTOM) {
179 if( rct_fits(remainder, 'v', ar->minsize) < 0 ) {
180 ar->flag |= RGN_FLAG_TOO_SMALL;
183 int fac= rct_fits(remainder, 'v', ar->size);
188 ar->winrct= *remainder;
190 if(ar->alignment==RGN_ALIGN_TOP) {
191 ar->winrct.ymin= ar->winrct.ymax - ar->size;
192 remainder->ymax= ar->winrct.ymin-1;
195 ar->winrct.ymax= ar->winrct.ymin + ar->size;
196 remainder->ymin= ar->winrct.ymax+1;
200 else if(ar->alignment==RGN_ALIGN_LEFT || ar->alignment==RGN_ALIGN_RIGHT) {
202 if( rct_fits(remainder, 'h', ar->minsize) < 0 ) {
203 ar->flag |= RGN_FLAG_TOO_SMALL;
206 int fac= rct_fits(remainder, 'h', ar->size);
211 ar->winrct= *remainder;
213 if(ar->alignment==RGN_ALIGN_RIGHT) {
214 ar->winrct.xmin= ar->winrct.xmax - ar->size;
215 remainder->xmax= ar->winrct.xmin-1;
218 ar->winrct.xmax= ar->winrct.xmin + ar->size;
219 remainder->xmin= ar->winrct.xmax+1;
224 /* percentage subdiv*/
225 ar->winrct= *remainder;
227 if(ar->alignment==RGN_ALIGN_HSPLIT) {
228 ar->winrct.xmax= (remainder->xmin+remainder->xmax)/2;
229 remainder->xmin= ar->winrct.xmax+1;
232 ar->winrct.ymax= (remainder->ymin+remainder->ymax)/2;
233 remainder->ymin= ar->winrct.ymax+1;
237 region_rect_recursive(ar->next, remainder);
240 static void area_calc_totrct(ScrArea *sa, int sizex, int sizey)
243 if(sa->v1->vec.x>0) sa->totrct.xmin= sa->v1->vec.x+1;
244 else sa->totrct.xmin= sa->v1->vec.x;
245 if(sa->v4->vec.x<sizex-1) sa->totrct.xmax= sa->v4->vec.x-1;
246 else sa->totrct.xmax= sa->v4->vec.x;
248 if(sa->v1->vec.y>0) sa->totrct.ymin= sa->v1->vec.y+1;
249 else sa->totrct.ymin= sa->v1->vec.y;
250 if(sa->v2->vec.y<sizey-1) sa->totrct.ymax= sa->v2->vec.y-1;
251 else sa->totrct.ymax= sa->v2->vec.y;
254 sa->winx= sa->totrct.xmax-sa->totrct.xmin+1;
255 sa->winy= sa->totrct.ymax-sa->totrct.ymin+1;
258 /* called in screen_refresh, or screens_init */
259 void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
264 /* set typedefinitions */
265 sa->type= BKE_spacetype_from_id(sa->spacetype);
267 sa->spacetype= SPACE_VIEW3D;
268 sa->type= BKE_spacetype_from_id(sa->spacetype);
271 area_calc_totrct(sa, win->sizex, win->sizey);
273 /* regiontype callback, it should create/verify the amount of subregions with minsizes etc */
277 /* region rect sizes */
279 region_rect_recursive(sa->regionbase.first, &rect);
282 for(ar= sa->regionbase.first; ar; ar= ar->next) {
283 if(ar->flag & (RGN_FLAG_HIDDEN|RGN_FLAG_TOO_SMALL)) {
285 wm_subwindow_close(win, ar->swinid);
288 else if(ar->swinid==0)
289 ar->swinid= wm_subwindow_open(win, &ar->winrct);
291 wm_subwindow_position(win, ar->swinid, &ar->winrct);
295 /* sa2 to sa1, we swap spaces for fullscreen to keep all allocated data */
296 /* area vertices were set */
298 void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space)
300 Panel *pa1, *pa2, *patab;
303 sa1->headertype= sa2->headertype;
304 sa1->spacetype= sa2->spacetype;
307 SWAP(ListBase, sa1->spacedata, sa2->spacedata);
308 /* exception: ensure preview is reset */
309 // if(sa1->spacetype==SPACE_VIEW3D)
310 // XXX BIF_view3d_previewrender_free(sa1->spacedata.first);
313 BKE_spacedata_freelist(&sa1->spacedata);
314 BKE_spacedata_copylist(&sa1->spacedata, &sa2->spacedata);
317 BLI_freelistN(&sa1->panels);
318 BLI_duplicatelist(&sa1->panels, &sa2->panels);
320 /* copy panel pointers */
321 for(pa1= sa1->panels.first; pa1; pa1= pa1->next) {
323 patab= sa1->panels.first;
324 pa2= sa2->panels.first;
326 if( pa1->paneltab == pa2) {
327 pa1->paneltab = patab;
336 BLI_freelistN(&sa1->regionbase);
337 BLI_duplicatelist(&sa1->regionbase, &sa2->regionbase);
338 for(ar= sa1->regionbase.first; ar; ar= ar->next)
342 BPY_free_scriptlink(&sa1->scriptlink);
343 sa1->scriptlink= sa2->scriptlink;
344 BPY_copy_scriptlink(&sa1->scriptlink); /* copies internal pointers */