diff options
Diffstat (limited to 'source/blender/src/editscreen.c')
-rw-r--r-- | source/blender/src/editscreen.c | 2931 |
1 files changed, 2931 insertions, 0 deletions
diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c new file mode 100644 index 00000000000..d71ae8c8e3d --- /dev/null +++ b/source/blender/src/editscreen.c @@ -0,0 +1,2931 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * All screen functions that are related to the interface + * handling and drawing. Might be split up as well later... + */ + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "nla.h" + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <math.h> + +#include "MEM_guardedalloc.h" + +#include "PIL_time.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "DNA_action_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_sound_types.h" +#include "DNA_view3d_types.h" +#include "DNA_userdef_types.h" + +#include "BLO_writefile.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_blender.h" +#include "BKE_screen.h" + +#include "BIF_editsound.h" +#include "BIF_glutil.h" +#include "BIF_gl.h" +#include "BIF_graphics.h" +#include "BIF_interface.h" +#include "BIF_mainqueue.h" +#include "BIF_mywindow.h" +#include "BIF_renderwin.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_toets.h" +#include "BIF_toolbox.h" +#include "BIF_usiblender.h" +#include "BIF_keyval.h" + +#include "BSE_edit.h" +#include "BSE_filesel.h" +#include "BSE_headerbuttons.h" +#include "BSE_view.h" + +#include "license_key.h" +#include "interface.h" +#include "mydevice.h" +#include "blendef.h" +#include "render.h" + +#include "winlay.h" + +/* TIPS: + * + * - LET OP DE EDGES, VERTICES ERVAN MOETEN IN VOLGORDE + (laagste pointer eerst). Anders onvoorspelbare effecten! + * - probleem: flags zijn nog niet echt netjes. Altijd na gebruik + op nul zetten. + */ + +static void testareas(void); +static void area_autoplayscreen(void); +static void wait_for_event(void); + +/* ********* Globals *********** */ + +static Window *mainwin= NULL; +static int prefsizx= 0, prefsizy= 0, prefstax= 0, prefstay= 0, start_maximized= 1; +static short dodrawscreen= 0; +static ScrArea *areawinar[MAXWIN]; +static ScrArea *g_activearea= NULL; +short winqueue_break= 0; +ScrArea *curarea= 0; + +/**********************************************************************/ + +static void screen_set_cursor(bScreen *sc) +{ + if (sc->winakt>3) { + ScrArea *sa= areawinar[sc->winakt]; + + set_cursor(sa->cursor); + } else { + set_cursor(CURSOR_STD); + } +} + +void waitcursor(int val) +{ + if(val) { + set_cursor(CURSOR_WAIT); + } else { + screen_set_cursor(G.curscreen); + } +} + +static int choose_cursor(ScrArea *sa) +{ + if (sa->spacetype==SPACE_VIEW3D) { + if(G.obedit) return CURSOR_EDIT; + else if(G.f & G_VERTEXPAINT) return CURSOR_VPAINT; + else if(G.f & G_WEIGHTPAINT) return CURSOR_VPAINT; + else if(G.f & G_FACESELECT) return CURSOR_FACESEL; + else return CURSOR_STD; + } else { + return CURSOR_STD; + } +} + +void wich_cursor(ScrArea *sa) +{ + sa->cursor= choose_cursor(sa); + + screen_set_cursor(G.curscreen); +} + + +void setcursor_space(int spacetype, short cur) +{ + bScreen *sc; + ScrArea *sa; + + for (sc= G.main->screen.first; sc; sc= sc->id.next) + for (sa= sc->areabase.first; sa; sa= sa->next) + if(sa->spacetype==spacetype) + sa->cursor= cur; + + screen_set_cursor(G.curscreen); +} + + +/* ********* IN/OUT ************* */ + +void getmouseco_sc(short *mval) /* screen coordinaten */ +{ + getmouse(mval); +} + +void getmouseco_areawin(short *mval) /* interne area coordinaten */ +{ + getmouseco_sc(mval); + + if(g_activearea && g_activearea->win) { + mval[0]-= g_activearea->winrct.xmin; + mval[1]-= g_activearea->winrct.ymin; + } +} + +void getmouseco_headwin(short *mval) /* interne area coordinaten */ +{ + getmouseco_sc(mval); + + if(g_activearea && g_activearea->headwin) { + mval[0]-= g_activearea->headrct.xmin; + mval[1]-= g_activearea->headrct.ymin; + } +} + +/* *********** STUFF ************** */ + +static int scredge_is_horizontal(ScrEdge *se) +{ + return (se->v1->vec.y == se->v2->vec.y); +} + +static ScrEdge *screen_find_active_scredge(bScreen *sc, short *mval) +{ + ScrEdge *se; + + for (se= sc->edgebase.first; se; se= se->next) { + if (scredge_is_horizontal(se)) { + if (abs(mval[1]-se->v1->vec.y)<=EDGEWIDTH2 && + abs(mval[0]-se->v1->vec.x)<=abs(se->v2->vec.x-se->v1->vec.x)) + return se; + } else { + if (abs(mval[0]-se->v1->vec.x)<=EDGEWIDTH2 && + abs(mval[1]-se->v1->vec.y)<=abs(se->v2->vec.y-se->v1->vec.y)) + return se; + } + } + + return NULL; +} + +void areawinset(short win) +{ + if(win>3) { + curarea= areawinar[win]; + if(curarea==0) { + printf("error in areawinar %d ,areawinset\n", win); + return; + } + + switch(curarea->spacetype) { + case SPACE_VIEW3D: + G.vd= curarea->spacedata.first; + break; + case SPACE_IPO: + if(G.sipo != curarea->spacedata.first) allqueue(REDRAWBUTSANIM, 0); + G.sipo= curarea->spacedata.first; + G.v2d= &G.sipo->v2d; + break; + case SPACE_BUTS: + G.buts= curarea->spacedata.first; + G.v2d= &G.buts->v2d; + break; + case SPACE_SEQ: { + SpaceSeq *sseq= curarea->spacedata.first; + G.v2d= &sseq->v2d; + break; + } + case SPACE_OOPS: + G.soops= curarea->spacedata.first; + G.v2d= &G.soops->v2d; + break; + case SPACE_IMAGE: + G.sima= curarea->spacedata.first; + G.v2d= &G.sima->v2d; + case SPACE_SOUND: + G.ssound= curarea->spacedata.first; + G.v2d= &G.ssound->v2d; + break; + case SPACE_ACTION: + G.saction= curarea->spacedata.first; + G.v2d= &G.saction->v2d; + break; + case SPACE_NLA: + G.snla= curarea->spacedata.first; + G.v2d= &G.snla->v2d; + break; + default: + break; + } + } + + if(win) mywinset(win); +} + +void headerbox(int selcol, int width) +{ + if(selcol) glClearColor(.75, .75, .75, 0.0); + else glClearColor(.65, .65, .65, 0.0); + + glClear(GL_COLOR_BUFFER_BIT); + + glColor3ub(0, 0, 0); + sdrawbox(0, 0, width, HEADERY); + + glColor3ub(220, 220, 220); + sdrawline(0, HEADERY-1, width, HEADERY-1); + + glColor3ub(176, 176, 176); + sdrawline(0, HEADERY-2, width, HEADERY-2); + + glColor3ub(128, 128, 128); + sdrawline(0, 2, width, 2); + + glColor3ub(64, 64, 64); + sdrawline(0, 1, width, 1); + + glColor3ub(0, 0, 0); + sdrawline(0, 0, width, 0); +} + +int area_is_active_area(ScrArea *area) +{ + return (g_activearea && area==g_activearea); +} + +void scrarea_do_headdraw(ScrArea *area) +{ + areawinset(area->headwin); + + headerbox(area_is_active_area(area), area->winx+100); + + switch(area->spacetype) { + case SPACE_FILE: file_buttons(); break; + case SPACE_INFO: info_buttons(); break; + case SPACE_VIEW3D: view3d_buttons(); break; + case SPACE_IPO: ipo_buttons(); break; + case SPACE_BUTS: buts_buttons(); break; + case SPACE_SEQ: seq_buttons(); break; + case SPACE_IMAGE: image_buttons(); break; + case SPACE_IMASEL: imasel_buttons(); break; + case SPACE_OOPS: oops_buttons(); break; + case SPACE_TEXT: text_buttons(); break; + case SPACE_SOUND: sound_buttons(); break; + case SPACE_ACTION: action_buttons(); break; + case SPACE_NLA: nla_buttons(); break; + } + + area->head_swap= WIN_BACK_OK; +} +void scrarea_do_headchange(ScrArea *area) +{ + float ofs= area->headbutofs; + + if (area->headertype==HEADERDOWN) { + bwin_ortho2(area->headwin, 0.5+ofs, area->headrct.xmax-area->headrct.xmin-0.5+ofs, +0.6, area->headrct.ymax-area->headrct.ymin+0.6); + } else { + bwin_ortho2(area->headwin, -0.5+ofs, area->headrct.xmax-area->headrct.xmin-0.5+ofs, -0.5, area->headrct.ymax-area->headrct.ymin-0.5); + } +} + + +static void openheadwin(ScrArea *sa); +static void closeheadwin(ScrArea *sa); + +static void scrarea_change_headertype(ScrArea *sa, int newtype) +{ + sa->headertype= newtype; + + if (!newtype) { + if (sa->headwin) { + uiFreeBlocksWin(&sa->uiblocks, sa->headwin); + closeheadwin(sa); + } + } else { + if (!sa->headwin) { + openheadwin(sa); + } + } + + testareas(); + winqueue_break= 1; +} + +static void headmenu(ScrArea *sa) +{ + short val= pupmenu("Header %t|Top%x2|Bottom %x1|No Header %x0"); + + if(val> -1) { + scrarea_change_headertype(sa, val); + } +} + +static void addqueue_ext(short win, unsigned short event, short val, char ascii) +{ + if (win<4 || !areawinar[win]) { + printf("bad call to addqueue: %d (%d, %d)\n", win, event, val); + } else { + bwin_qadd(win, event, val, ascii); + } +} + +void addqueue(short win, unsigned short event, short val) +{ + addqueue_ext(win, event, val, 0); +} + +void scrarea_queue_winredraw(ScrArea *area) +{ + addqueue(area->win, REDRAW, 1); +} +void scrarea_queue_headredraw(ScrArea *area) +{ + if (area->headwin) addqueue(area->headwin, REDRAW, 1); +} +void scrarea_queue_redraw(ScrArea *area) +{ + scrarea_queue_winredraw(area); + scrarea_queue_headredraw(area); +} + +static void scrollheader(ScrArea *area); +static void scrarea_dispatch_header_events(ScrArea *sa) +{ + ScrArea *tempsa; + short do_redraw=0, do_change=0; + + areawinset(sa->headwin); + + while(bwin_qtest(sa->headwin)) { + char ascii; + short val; + unsigned short event= bwin_qread(sa->headwin, &val, &ascii); + + if(val) { + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + switch(event) { + case UI_BUT_EVENT: + do_headerbuttons(val); + break; + + case LEFTMOUSE: + if (G.qual & LR_CTRLKEY) { + window_lower(mainwin); + } else { + window_raise(mainwin); + } + break; + + case MIDDLEMOUSE: + scrollheader(sa); + break; + case RIGHTMOUSE: + headmenu(sa); + break; + case REDRAW: + do_redraw= 1; + break; + case CHANGED: + sa->head_swap= 0; + do_change= 1; + do_redraw= 1; + break; + default: + if (winqueue_break == 0) { + scrarea_do_winhandle(sa, event, val, ascii); + if (winqueue_break == 0) areawinset(sa->headwin); + } + } + + if(winqueue_break) return; + } + } + + /* test: bestaat window nog */ + tempsa= areawinar[sa->headwin]; + if(tempsa==0) return; + + /* dit onderscheid loopt niet lekker... */ + if(do_change) scrarea_do_headchange(sa); + if(do_redraw) scrarea_do_headdraw(sa); +} + +static void scrarea_dispatch_events(ScrArea *sa) +{ + ScrArea *tempsa; + short do_redraw=0, do_change=0; + + if(sa!=curarea || sa->win!=mywinget()) areawinset(sa->win); + + while(bwin_qtest(sa->win)) { + char ascii; + short val; + unsigned short event= bwin_qread(sa->win, &val, &ascii); + + if(event==REDRAW) { + do_redraw= 1; + } + else if(event==CHANGED) { + sa->win_swap= 0; + do_change= 1; + do_redraw= 1; + } + else { + scrarea_do_winhandle(sa, event, val, ascii); + } + + if(winqueue_break) return; + } + + /* test: bestaat window nog */ + tempsa= areawinar[sa->win]; + if(tempsa==0) return; + + if (do_change || do_redraw) { + areawinset(sa->win); + if(do_change) + scrarea_do_winchange(curarea); + if(do_redraw) + scrarea_do_windraw(curarea); + } +} + +/***/ + + +void markdirty_all() +{ + ScrArea *sa; + + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + scrarea_queue_winredraw(sa); + sa->win_swap &= ~WIN_FRONT_OK; + + scrarea_queue_headredraw(sa); + sa->head_swap &= ~WIN_FRONT_OK; + } +} + +int is_allowed_to_change_screen(bScreen *new) +{ + /* niet als curscreen is full + * niet als obedit && old->scene!=new->scene + */ + + if(new==0) return 0; + if(G.curscreen->full != SCREENNORMAL) return 0; + if(curarea->full) return 0; + if(G.obedit) { + if(G.curscreen->scene!=new->scene) return 0; + } + return 1; +} + +void splash(void *data, int datasize, char *string) +{ + ImBuf *bbuf; + int oldwin; + short val; + + bbuf= IMB_ibImageFromMemory((int *)data, datasize, IB_rect); + + if (bbuf) { + + oldwin = mywinget(); + mywinset(G.curscreen->mainwin); + + if (string) { + int x, y, maxy; + unsigned int *rect; + + rect = bbuf->rect; + maxy = MIN2(bbuf->y, 18); + + for (y = 0; y < maxy; y++) { + for (x = 0; x < bbuf->x; x++) { + *rect = 0xffffffff; + rect++; + } + } + } + glDrawBuffer(GL_FRONT); + + /* + // this dims the whole screen a bit. I didn't like it afterall + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0.0,0.0,0.0,0.3); + glRecti(0, 0, G.curscreen->sizex, G.curscreen->sizey); + glDisable(GL_BLEND); + */ + + glRasterPos2i((prefsizx-bbuf->x)/2, (prefsizy-bbuf->y)/2); + glDrawPixels(bbuf->x, bbuf->y, GL_RGBA, GL_UNSIGNED_BYTE, bbuf->rect); + + if (string) { + void *font; + int width; + + if (BMF_GetStringWidth(font= G.font, string) > bbuf->x) + if (BMF_GetStringWidth(font= G.fonts, string) > bbuf->x) + font= G.fontss; + + width= BMF_GetStringWidth(font, string); + + glColor3ub(0, 0, 0); + glRasterPos2i((prefsizx-width)/2, (prefsizy-bbuf->y)/2 + 6); + BMF_DrawString(font, string); + } + + glFinish(); + glDrawBuffer(GL_BACK); + + IMB_freeImBuf(bbuf); + + // flush input buffers .... + // this might break some things + + while (get_mbut()) { + BIF_wait_for_statechange(); + } + while(qtest()) { + extern_qread(&val); + } + + wait_for_event(); + + mywinset(oldwin); + markdirty_all(); + mainqenter(DRAWEDGES, 1); + } +} + +static void moveareas(ScrEdge *edge); +static void joinarea(ScrArea *sa, ScrEdge *onedge); +static void splitarea_interactive(ScrArea *area, ScrEdge *onedge); + +static void screen_edge_edit_event(ScrArea *actarea, ScrEdge *actedge, short evt, short val) { + if (val) { + // don't allow users to edit full screens + if (actarea && actarea->full) { + return; + } + + if (evt==LEFTMOUSE) { + moveareas(actedge); + } else if (evt==MIDDLEMOUSE || evt==RIGHTMOUSE) { + int edgeop; + + if (!actarea->headertype) { + edgeop= pupmenu("Split Area|Join Areas|Add header"); + } else { + edgeop= pupmenu("Split Area|Join Areas|No header"); + } + + if (edgeop==1) { + splitarea_interactive(actarea, actedge); + } else if (edgeop==2) { + joinarea(actarea, actedge); + } else if (edgeop==3) { + scrarea_change_headertype(actarea, actarea->headertype?0:HEADERDOWN); + } + } + } +} + +/***/ + +void mywindow_init_mainwin(Window *win, int orx, int ory, int sizex, int sizey); +void test_scale_screen(bScreen *); + +static void resize_screens(int x, int y, int w, int h) { + prefstax= x; + prefstay= y; + prefsizx= w; + prefsizy= h; + + test_scale_screen(G.curscreen); + testareas(); +} + +static void init_mainwin(void) +{ + int orx, ory, sizex, sizey; + + glEnable(GL_SCISSOR_TEST); + + window_get_position(mainwin, &orx, &ory); + window_get_size(mainwin, &sizex, &sizey); + + /* XXX, temporary stupid fix for minimize at windows */ + if (!sizex && !sizey) { + return; + } + + mywindow_init_mainwin(mainwin, orx, ory, sizex, sizey); + resize_screens(orx, ory, sizex, sizey); +} + +/***/ + +static short afterqueue[MAXQUEUE][3]; +static int nafterqitems= 0; + +void addafterqueue(short win, unsigned short evt, short val) +{ + if (nafterqitems<MAXQUEUE) { + afterqueue[nafterqitems][0]= win; + afterqueue[nafterqitems][1]= evt; + afterqueue[nafterqitems][2]= val; + nafterqitems++; + } +} + +static void append_afterqueue(void) +{ + while (nafterqitems) { + short win= afterqueue[nafterqitems-1][0]; + unsigned short evt= afterqueue[nafterqitems-1][1]; + short val= afterqueue[nafterqitems-1][2]; + + addqueue(win, evt, val); + + nafterqitems--; + } +} + +static char ext_load_str[256]= {0, 0}; +void add_readfile_event(char *filename) +{ + mainqenter(LOAD_FILE, 1); + strcpy(ext_load_str, filename); + BLI_convertstringcode(ext_load_str, G.sce, G.scene->r.cfra); +} + +static short ext_reshape= 0, ext_redraw=0, ext_inputchange=0, ext_mousemove=0; + +static void flush_extqd_events(void) { + if (ext_inputchange) { + mainqenter(INPUTCHANGE, ext_inputchange); + } else if (ext_reshape) { + mainqenter(RESHAPE, ext_redraw); + } else if (ext_redraw) { + mainqenter(REDRAW, ext_redraw); + } else if (ext_mousemove) { + short mouse[2]; + + getmouseco_sc(mouse); + + mainqenter(MOUSEX, mouse[0]); + mainqenter(MOUSEY, mouse[1]); + } + + ext_inputchange= ext_reshape= ext_redraw= ext_mousemove= 0; +} + +unsigned short qtest(void) +{ + if (!mainqtest()) { + winlay_process_events(0); + } + + return mainqtest(); +} + + /* return true if events are waiting anywhere */ +int anyqtest(void) +{ + ScrArea *sa; + + if (nafterqitems || qtest()) return 1; + + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + if (bwin_qtest(sa->win)) return 1; + if (sa->headwin && bwin_qtest(sa->headwin)) return 1; + } + + return 0; +} + +static void wait_for_event(void) +{ + while (!mainqtest()) { + winlay_process_events(1); + } +} + +unsigned short screen_qread(short *val, char *ascii) +{ + unsigned short event; + + wait_for_event(); + + event= mainqread(val, ascii); + + if(event==RIGHTSHIFTKEY || event==LEFTSHIFTKEY) { + if(*val) G.qual |= LR_SHIFTKEY; + else G.qual &= ~LR_SHIFTKEY; + } + else if(event==RIGHTALTKEY || event==LEFTALTKEY) { + if(*val) G.qual |= LR_ALTKEY; + else G.qual &= ~LR_ALTKEY; + } + else if(event==RIGHTCTRLKEY || event==LEFTCTRLKEY) { + if(*val) G.qual |= LR_CTRLKEY; + else G.qual &= ~LR_CTRLKEY; + } + + return event; +} + +unsigned short extern_qread_ext(short *val, char *ascii) +{ + /* bewaart de laatste INPUTCHANGE en de laatste REDRAW */ + unsigned short event; + + event= screen_qread(val, ascii); + if(event==RESHAPE) ext_reshape= *val; + else if(event==REDRAW) ext_redraw= *val; + else if(event==INPUTCHANGE) ext_inputchange= *val; + else if(event==MOUSEY || event==MOUSEX) ext_mousemove= 1; + else if((G.qual & LR_CTRLKEY) && event==F3KEY) { + BIF_screendump(); + } + + return event; +} +unsigned short extern_qread(short *val) +{ + char ascii; + return extern_qread_ext(val, &ascii); +} + +void reset_autosave(void) { + window_set_timer(mainwin, U.savetime*60*1000, AUTOSAVE_FILE); +} + +static void screen_dispatch_events(void) { + int events_remaining= 1; + ScrArea *sa; + + while (events_remaining) { + events_remaining= 0; + + winqueue_break= 0; + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + /* bewust eerst header afhandelen, dan rest. Header is soms init */ + if (sa->headwin && bwin_qtest(sa->headwin)) { + scrarea_dispatch_header_events(sa); + events_remaining= 1; + } + if (winqueue_break) break; + + if (bwin_qtest(sa->win)) { + scrarea_dispatch_events(sa); + events_remaining= 1; + } + if (winqueue_break) break; + } + + if (winqueue_break) break; + } + + if (dodrawscreen) { + drawscreen(); + dodrawscreen= 0; + } + + screen_swapbuffers(); +} + +static ScrArea *screen_find_area_for_pt(bScreen *sc, short *mval) +{ + ScrArea *sa; + + for (sa= sc->areabase.first; sa; sa= sa->next) + if (BLI_in_rcti(&sa->totrct, mval[0], mval[1])) + return sa; + + return NULL; +} + +void screenmain(void) +{ + int has_input= 1; + int firsttime = 1; + while (1) { + unsigned short event; + short val, towin; + char ascii; + + flush_extqd_events(); + if (nafterqitems && !qtest()) { + append_afterqueue(); + event= 0; + } else { + event= screen_qread(&val, &ascii); + } + + window_make_active(mainwin); + + if (event==INPUTCHANGE) { + has_input= val; + } + + if (has_input) { + ScrArea *newactarea; + int newactwin; + short mval[2]; + + getmouseco_sc(mval); + newactarea= screen_find_area_for_pt(G.curscreen, mval); + + if (newactarea) { + if (BLI_in_rcti(&newactarea->headrct, mval[0], mval[1])) { + newactwin= newactarea->headwin; + } else { + newactwin= newactarea->win; + } + } else { + newactwin= 0; + } + + if (newactarea && (newactarea != g_activearea)) { + if (g_activearea) scrarea_queue_headredraw(g_activearea); + scrarea_queue_headredraw(newactarea); + set_cursor(newactarea->cursor); + g_activearea= newactarea; + } + + G.curscreen->winakt= newactwin; + if (G.curscreen->winakt) { + areawinset(G.curscreen->winakt); + set_cursor(choose_cursor(g_activearea)); + } + } else { + if (g_activearea) { + scrarea_queue_headredraw(g_activearea); + } + g_activearea= NULL; + G.curscreen->winakt= 0; + } + + towin= 0; + if (event==WINCLOSE) { + exit_usiblender(); + } + else if (event==DRAWEDGES) { + dodrawscreen= 1; + } + else if (event==RESHAPE) { + init_mainwin(); + markdirty_all(); + dodrawscreen= 1; + } + else if (event==REDRAW) { + markdirty_all(); + dodrawscreen= 1; + } + else if (event==AUTOSAVE_FILE) { + BIF_write_autosave(); + } + else if (event==LOAD_FILE) { + BIF_read_file(ext_load_str); + sound_initialize_sounds(); + } + else { + towin= 1; + } + + if (!g_activearea) { + towin= 0; + } + else if (!G.curscreen->winakt) { + ScrEdge *actedge; + short mval[2]; + + getmouseco_sc(mval); + actedge= screen_find_active_scredge(G.curscreen, mval); + + if (actedge) { + if (scredge_is_horizontal(actedge)) { + set_cursor(CURSOR_Y_MOVE); + } else { + set_cursor(CURSOR_X_MOVE); + } + + screen_edge_edit_event(g_activearea, actedge, event, val); + } else { + set_cursor(CURSOR_STD); + } + + towin= 0; + } + else if (event==QKEY) { + if((G.obedit && G.obedit->type==OB_FONT && g_activearea->spacetype==SPACE_VIEW3D)||g_activearea->spacetype==SPACE_TEXT); + else { + if(val && okee("QUIT BLENDER")) exit_usiblender(); + towin= 0; + } + } + else if (event==ZKEY) { + if(val && G.qual==(LR_ALTKEY|LR_SHIFTKEY|LR_CTRLKEY)) { + extern void set_debug_swapbuffers_ovveride(bScreen *sc, int mode); + + int which= pupmenu("Swapbuffers%t|Simple|Debug|DebugSwap|Redraw|Default|KillSwap"); + + switch (which) { + case 1: set_debug_swapbuffers_ovveride(G.curscreen, 's'); break; + case 2: set_debug_swapbuffers_ovveride(G.curscreen, 'd'); break; + case 3: set_debug_swapbuffers_ovveride(G.curscreen, 'f'); break; + case 4: set_debug_swapbuffers_ovveride(G.curscreen, 'r'); break; + case 5: set_debug_swapbuffers_ovveride(G.curscreen, 0); break; + case 6: + if (g_activearea) { + g_activearea->head_swap= 0; + g_activearea->win_swap= 0; + } + break; + } + towin= 0; + } + } + else if (event==SPACEKEY) { + if((G.obedit && G.obedit->type==OB_FONT && g_activearea->spacetype==SPACE_VIEW3D)||g_activearea->spacetype==SPACE_TEXT); + else { + if(val) toolbox(); + towin= 0; + } + } + else if(ELEM(event, LEFTARROWKEY, RIGHTARROWKEY)) { + if(val && (G.qual & LR_CTRLKEY)) { + bScreen *sc= (event==LEFTARROWKEY)?G.curscreen->id.prev:G.curscreen->id.next; + if(is_allowed_to_change_screen(sc)) setscreen(sc); + g_activearea= NULL; + towin= 0; + } + } + else if(ELEM(event, UPARROWKEY, DOWNARROWKEY)) { + if(val && (G.qual & LR_CTRLKEY)) { + area_fullscreen(); + g_activearea= NULL; + towin= 0; + } + } + + if (towin) { + if (blenderqread(event, val)) + addqueue_ext(G.curscreen->winakt, event, val, ascii); + } + + /* only process subwindow queue's once the + * main queue has been emptyied. + */ + event= qtest(); + if (event==0 || event==EXECUTE) { + screen_dispatch_events(); + } + + /* Bizar hack. The event queue has mutated... */ + if ( (firsttime) && (event == 0) ) { + if (G.fileflags & G_FILE_AUTOPLAY) { + // SET AUTOPLAY in G.flags for + // other fileloads + + G.flags |= G_FLAGS_AUTOPLAY; + area_autoplayscreen(); + + // Let The Games Begin + // fake a 'p' keypress + + mainqenter(PKEY, 1); + } else { + extern char datatoc_splash_jpg[]; + extern int datatoc_splash_jpg_size; + extern char datatoc_ton[]; + extern int datatoc_tonize; + + if (! ((G.main->versionfile >= G.version) + || G.save_over)) { + if (LICENSE_KEY_VALID) { + splash((void *)datatoc_ton, + datatoc_tonize, + NULL); + } else { + splash((void *)datatoc_splash_jpg, + datatoc_splash_jpg_size, + NULL); + } + } + } + firsttime = 0; + } + } +} + +void mainwindow_raise(void) { + window_raise(mainwin); +} +void mainwindow_make_active(void) { + window_make_active(mainwin); +} +void mainwindow_close(void) { + window_destroy(mainwin); + mainwin= NULL; +} + +/* ********* AREAS ************* */ + +void setprefsize(int stax, int stay, int sizx, int sizy) +{ + int scrwidth, scrheight; + + winlay_get_screensize(&scrwidth, &scrheight); + + if(stax<0) stax= 0; + if(stay<0) stay= 0; + if(sizx<320) sizx= 320; + if(sizy<256) sizy= 256; + + if(stax+sizx>scrwidth) sizx= scrwidth-stax; + if(stay+sizy>scrheight) sizy= scrheight-stay; + if(sizx<320 || sizy<256) { + printf("ERROR: illegal prefsize\n"); + return; + } + + prefstax= stax; + prefstay= stay; + prefsizx= sizx; + prefsizy= sizy; + + start_maximized= 0; +} + + +static ScrVert *screen_addvert(bScreen *sc, short x, short y) +{ + ScrVert *sv= MEM_callocN(sizeof(ScrVert), "addscrvert"); + sv->vec.x= x; + sv->vec.y= y; + + BLI_addtail(&sc->vertbase, sv); + return sv; +} + +static void sortscrvert(ScrVert **v1, ScrVert **v2) +{ + ScrVert *tmp; + + if ((long)*v1 > (long)*v2) { + tmp= *v1; + *v1= *v2; + *v2= tmp; + } +} + +static ScrEdge *screen_addedge(bScreen *sc, ScrVert *v1, ScrVert *v2) +{ + ScrEdge *se= MEM_callocN(sizeof(ScrEdge), "addscredge"); + + sortscrvert(&v1, &v2); + se->v1= v1; + se->v2= v2; + + BLI_addtail(&sc->edgebase, se); + return se; +} + +static ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2) +{ + ScrEdge *se; + + sortscrvert(&v1, &v2); + for (se= sc->edgebase.first; se; se= se->next) + if(se->v1==v1 && se->v2==v2) + return se; + + return NULL; +} + +static void removedouble_scrverts(void) +{ + ScrVert *v1, *verg; + ScrEdge *se; + ScrArea *sa; + + verg= G.curscreen->vertbase.first; + while(verg) { + if(verg->newv==0) { /* !!! */ + v1= verg->next; + while(v1) { + if(v1->newv==0) { /* !?! */ + if(v1->vec.x==verg->vec.x && v1->vec.y==verg->vec.y) { + /* printf("doublevert\n"); */ + v1->newv= verg; + } + } + v1= v1->next; + } + } + verg= verg->next; + } + + /* vervang pointers in edges en vlakken */ + se= G.curscreen->edgebase.first; + while(se) { + if(se->v1->newv) se->v1= se->v1->newv; + if(se->v2->newv) se->v2= se->v2->newv; + /* edges zijn veranderd: dus.... */ + sortscrvert(&(se->v1), &(se->v2)); + se= se->next; + } + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->v1->newv) sa->v1= sa->v1->newv; + if(sa->v2->newv) sa->v2= sa->v2->newv; + if(sa->v3->newv) sa->v3= sa->v3->newv; + if(sa->v4->newv) sa->v4= sa->v4->newv; + sa= sa->next; + } + + /* verwijderen */ + verg= G.curscreen->vertbase.first; + while(verg) { + v1= verg->next; + if(verg->newv) { + BLI_remlink(&G.curscreen->vertbase, verg); + MEM_freeN(verg); + } + verg= v1; + } + +} + +static void removenotused_scrverts(void) +{ + ScrVert *sv, *svn; + ScrEdge *se; + + /* ga ervan uit dat de edges goed zijn */ + + se= G.curscreen->edgebase.first; + while(se) { + se->v1->flag= 1; + se->v2->flag= 1; + se= se->next; + } + + sv= G.curscreen->vertbase.first; + while(sv) { + svn= sv->next; + if(sv->flag==0) { + BLI_remlink(&G.curscreen->vertbase, sv); + MEM_freeN(sv); + } + else sv->flag= 0; + sv= svn; + } +} + +static void removedouble_scredges(void) +{ + ScrEdge *verg, *se, *sn; + + /* vergelijken */ + verg= G.curscreen->edgebase.first; + while(verg) { + se= verg->next; + while(se) { + sn= se->next; + if(verg->v1==se->v1 && verg->v2==se->v2) { + BLI_remlink(&G.curscreen->edgebase, se); + MEM_freeN(se); + } + se= sn; + } + verg= verg->next; + } +} + +static void removenotused_scredges(void) +{ + ScrEdge *se, *sen; + ScrArea *sa; + int a=0; + + /* zet flag als edge gebruikt wordt in area */ + sa= G.curscreen->areabase.first; + while(sa) { + se= screen_findedge(G.curscreen, sa->v1, sa->v2); + if(se==0) printf("error: area %d edge 1 bestaat niet\n", a); + else se->flag= 1; + se= screen_findedge(G.curscreen, sa->v2, sa->v3); + if(se==0) printf("error: area %d edge 2 bestaat niet\n", a); + else se->flag= 1; + se= screen_findedge(G.curscreen, sa->v3, sa->v4); + if(se==0) printf("error: area %d edge 3 bestaat niet\n", a); + else se->flag= 1; + se= screen_findedge(G.curscreen, sa->v4, sa->v1); + if(se==0) printf("error: area %d edge 4 bestaat niet\n", a); + else se->flag= 1; + sa= sa->next; + a++; + } + se= G.curscreen->edgebase.first; + while(se) { + sen= se->next; + if(se->flag==0) { + BLI_remlink(&G.curscreen->edgebase, se); + MEM_freeN(se); + } + else se->flag= 0; + se= sen; + } +} + +void calc_arearcts(ScrArea *sa) +{ + + if(sa->v1->vec.x>0) sa->totrct.xmin= sa->v1->vec.x+EDGEWIDTH2+1; + else sa->totrct.xmin= sa->v1->vec.x; + if(sa->v4->vec.x<G.curscreen->sizex-1) sa->totrct.xmax= sa->v4->vec.x-EDGEWIDTH2-1; + else sa->totrct.xmax= sa->v4->vec.x; + + if(sa->v1->vec.y>0) sa->totrct.ymin= sa->v1->vec.y+EDGEWIDTH2+1; + else sa->totrct.ymin= sa->v1->vec.y; + if(sa->v2->vec.y<G.curscreen->sizey-1) sa->totrct.ymax= sa->v2->vec.y-EDGEWIDTH2-1; + else sa->totrct.ymax= sa->v2->vec.y; + + sa->winrct= sa->totrct; + if(sa->headertype) { + sa->headrct= sa->totrct; + if(sa->headertype==HEADERDOWN) { + sa->headrct.ymax= sa->headrct.ymin+HEADERY-1; + sa->winrct.ymin= sa->headrct.ymax+1; + } + else if(sa->headertype==HEADERTOP) { + sa->headrct.ymin= sa->headrct.ymax-HEADERY+1; + sa->winrct.ymax= sa->headrct.ymin-1; + } + } + if(sa->winrct.ymin>sa->winrct.ymax) sa->winrct.ymin= sa->winrct.ymax; + + /* als speedup voor berekeningen */ + sa->winx= sa->winrct.xmax-sa->winrct.xmin+1; + sa->winy= sa->winrct.ymax-sa->winrct.ymin+1; +} + +static void openheadwin(ScrArea *sa) +{ + sa->headwin= myswinopen(G.curscreen->mainwin, + sa->headrct.xmin, sa->headrct.xmax, sa->headrct.ymin, sa->headrct.ymax); + + glMatrixMode(GL_MODELVIEW); + + areawinar[sa->headwin]= sa; /* anders doet addqueue het niet */ + addqueue(sa->headwin, CHANGED, 1); +} + +static void openareawin(ScrArea *sa) +{ + sa->win= myswinopen(G.curscreen->mainwin, + sa->winrct.xmin, sa->winrct.xmax, sa->winrct.ymin, sa->winrct.ymax); + + areawinar[sa->win]= sa; /* anders doet addqueue het niet */ + addqueue(sa->win, CHANGED, 1); +} + +static void closeheadwin(ScrArea *sa) +{ + if(sa->headwin) mywinclose(sa->headwin); + sa->headwin= 0; +} + +static void closeareawin(ScrArea *sa) +{ + uiFreeBlocksWin(&sa->uiblocks, sa->win); + + if(sa->win) mywinclose(sa->win); + sa->win= 0; +} + +static void del_area(ScrArea *sa) +{ + closeareawin(sa); + closeheadwin(sa); + + freespacelist(&sa->spacedata); + + uiFreeBlocks(&sa->uiblocks); + + if(sa==curarea) curarea= 0; + if(sa==g_activearea) g_activearea= 0; +} + +static void copy_areadata(ScrArea *sa1, ScrArea *sa2) +{ + sa1->headertype= sa2->headertype; + sa1->spacetype= sa2->spacetype; + Mat4CpyMat4(sa1->winmat, sa2->winmat); + + freespacelist(&sa1->spacedata); + + duplicatespacelist(sa1, &sa1->spacedata, &sa2->spacedata); +} + +static ScrArea *screen_addarea(bScreen *sc, ScrVert *v1, ScrVert *v2, ScrVert *v3, ScrVert *v4, short headertype, short spacetype) +{ + ScrArea *sa= MEM_callocN(sizeof(ScrArea), "addscrarea"); + sa->cursor= CURSOR_STD; + sa->v1= v1; + sa->v2= v2; + sa->v3= v3; + sa->v4= v4; + sa->headertype= headertype; + sa->spacetype= spacetype; + + calc_arearcts(sa); + + if (sa->headertype) openheadwin(sa); + openareawin(sa); + + BLI_addtail(&sc->areabase, sa); + return sa; +} + +static int rcti_eq(rcti *a, rcti *b) { + return ((a->xmin==b->xmin && a->xmax==b->xmax) && + (a->ymin==b->ymin && a->ymax==b->ymax)); +} + +static void testareas(void) +{ + ScrArea *sa; + + /* testen of header er moet zijn, of weg moet, of verplaatst */ + /* testen of window er moet zijn, of weg moet, of verplaatst */ + + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + rcti oldhr= sa->headrct; + rcti oldwr= sa->winrct; + + calc_arearcts(sa); + + /* test header */ + if (sa->headwin) { + if (!rcti_eq(&oldhr, &sa->headrct)) { + mywinposition(sa->headwin, sa->headrct.xmin, sa->headrct.xmax, sa->headrct.ymin, sa->headrct.ymax); + addqueue(sa->headwin, CHANGED, 1); + } + + if(sa->headbutlen<sa->winx) { + sa->headbutofs= 0; + addqueue(sa->headwin, CHANGED, 1); + } + else if(sa->headbutofs+sa->winx > sa->headbutlen) { + sa->headbutofs= sa->headbutlen-sa->winx; + addqueue(sa->headwin, CHANGED, 1); + } + } + + if (!rcti_eq(&oldwr, &sa->winrct)) { + mywinposition(sa->win, sa->winrct.xmin, sa->winrct.xmax, sa->winrct.ymin, sa->winrct.ymax); + addqueue(sa->win, CHANGED, 1); + } + } + + /* remake global windowarray */ + memset(areawinar, 0, sizeof(void *)*MAXWIN); + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + areawinar[sa->headwin]= sa; + areawinar[sa->win]= sa; + } + + /* test of winakt in orde is */ + if( areawinar[G.curscreen->winakt]==0) G.curscreen->winakt= 0; +} + +static ScrArea *test_edge_area(ScrArea *sa, ScrEdge *se) +{ + /* test of edge in area ligt, zo niet, + vind een area die 'm wel heeft */ + + ScrEdge *se1=0, *se2=0, *se3=0, *se4=0; + + if(sa) { + se1= screen_findedge(G.curscreen, sa->v1, sa->v2); + se2= screen_findedge(G.curscreen, sa->v2, sa->v3); + se3= screen_findedge(G.curscreen, sa->v3, sa->v4); + se4= screen_findedge(G.curscreen, sa->v4, sa->v1); + } + if(se1!=se && se2!=se && se3!=se && se4!=se) { + + sa= G.curscreen->areabase.first; + while(sa) { + /* een beetje optimaliseren? */ + if(se->v1==sa->v1 || se->v1==sa->v2 || se->v1==sa->v3 || se->v1==sa->v4) { + se1= screen_findedge(G.curscreen, sa->v1, sa->v2); + se2= screen_findedge(G.curscreen, sa->v2, sa->v3); + se3= screen_findedge(G.curscreen, sa->v3, sa->v4); + se4= screen_findedge(G.curscreen, sa->v4, sa->v1); + if(se1==se || se2==se || se3==se || se4==se) return sa; + } + sa= sa->next; + } + } + + return sa; /* is keurig 0 als niet gevonden */ +} + +ScrArea *closest_bigger_area(void) +{ + ScrArea *sa, *big=0; + float cent[3], vec[3],len, len1, len2, len3, dist=1000; + short mval[2]; + + getmouseco_sc(mval); + + cent[0]= mval[0]; + cent[1]= mval[1]; + cent[2]= vec[2]= 0; + + sa= G.curscreen->areabase.first; + while(sa) { + if(sa!=curarea) { + if(sa->winy>=curarea->winy) { + + /* mimimum van vier hoekpunten */ + vec[0]= sa->v1->vec.x; vec[1]= sa->v1->vec.y; + len= VecLenf(vec, cent); + vec[0]= sa->v2->vec.x; vec[1]= sa->v2->vec.y; + len1= VecLenf(vec, cent); + vec[0]= sa->v3->vec.x; vec[1]= sa->v3->vec.y; + len2= VecLenf(vec, cent); + vec[0]= sa->v4->vec.x; vec[1]= sa->v4->vec.y; + len3= VecLenf(vec, cent); + + len= MIN4(len, len1, len2, len3); + + /* plus centrum */ + vec[0]= (sa->v2->vec.x+sa->v3->vec.x)/2; + vec[1]= (sa->v1->vec.y+sa->v2->vec.y)/2; + + len+= 0.5*VecLenf(vec, cent); + + /* min afmeting */ + len-= sa->winy+sa->winx; + + if(len<dist) { + dist= len; + big= sa; + } + } + } + sa= sa->next; + } + + if(big) return big; + else return curarea; +} + +/* ************ SCREENBEHEER ************** */ + +static int statechanged= 0; +void BIF_wait_for_statechange(void) +{ + if (!statechanged) { + /* Safety, don't wait more than 0.1 seconds */ + double stime= PIL_check_seconds_timer(); + while (!statechanged) { + winlay_process_events(1); + if ((PIL_check_seconds_timer()-stime)>0.1) break; + } + statechanged= 0; + } +} +void getmouse(short *mval) +{ + winlay_process_events(0); + window_get_mouse(mainwin, mval); +} +short get_qual(void) +{ + winlay_process_events(0); + return window_get_qual(mainwin); +} +short get_mbut(void) +{ + winlay_process_events(0); + return window_get_mbut(mainwin); +} + +static unsigned short convert_for_nonumpad(unsigned short event) +{ + if (event>=ZEROKEY && event<=NINEKEY) { + return event - ZEROKEY + PAD0; + } else if (event==MINUSKEY) { + return PADMINUS; + } else if (event==EQUALKEY) { + return PADPLUSKEY; + } else if (event==BACKSLASHKEY) { + return PADSLASHKEY; + } else { + return event; + } +} + +void add_to_mainqueue(Window *win, void *user_data, short evt, short val, char ascii) +{ + short qual= window_get_qual(win); + + statechanged= 1; + + if (U.flag&NONUMPAD) { + evt= convert_for_nonumpad(evt); + } + + /* enforce some guarentees about ascii values... these should + * be enforced in ghost probably - zr + */ + + if (!val || !isprint(ascii) || (qual&~LR_SHIFTKEY)) { + ascii= '\0'; + } + + mainqenter_ext(evt, val, ascii); +} + +static bScreen *addscreen(char *name) /* gebruik de setprefsize() als je anders dan fullscreen wilt */ +{ + /* deze functie zet de variabele G.curscreen + * omdat alle hulpfuncties moeten weten welk screen + */ + bScreen *sc; + ScrVert *sv1, *sv2, *sv3, *sv4; + short startx, starty, endx, endy; + + sc= G.curscreen= alloc_libblock(&G.main->screen, ID_SCR, name); + + if (!prefsizx) { + prefstax= 0; + prefstay= 0; + + winlay_get_screensize(&prefsizx, &prefsizy); + } + + startx= prefstax; + starty= prefstay; + endx= prefstax+prefsizx-1; + endy= prefstay+prefsizy-1; + + sc->startx= startx; sc->starty= starty; + sc->endx= endx; sc->endy= endy; + sc->sizex= sc->endx-sc->startx+1; + sc->sizey= sc->endy-sc->starty+1; + + sc->scene= G.scene; + + if (!mainwin) { + mainwin= window_open("Blender", sc->startx, sc->starty, sc->sizex, sc->sizey, start_maximized); + if (!mainwin) { + printf("ERROR: Unable to open Blender window\n"); + exit(1); + } + + window_set_handler(mainwin, add_to_mainqueue, NULL); + init_mainwin(); + mywinset(1); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + myortho2(-0.5, sc->sizex-0.5, -0.5, sc->sizey-0.5); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glDrawBuffer(GL_FRONT); + glClearColor(.45, .45, .45, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + glDrawBuffer(GL_BACK); + + warp_pointer(sc->sizex/2, sc->sizey/2); + + mainqenter(REDRAW, 1); + } + + sc->mainwin= 1; + + sv1= screen_addvert(sc, 0, 0); + sv2= screen_addvert(sc, 0, sc->endy-sc->starty); + sv3= screen_addvert(sc, sc->sizex-1, sc->sizey-1); + sv4= screen_addvert(sc, sc->sizex-1, 0); + + screen_addedge(sc, sv1, sv2); + screen_addedge(sc, sv2, sv3); + screen_addedge(sc, sv3, sv4); + screen_addedge(sc, sv4, sv1); + + screen_addarea(sc, sv1, sv2, sv3, sv4, HEADERDOWN, SPACE_INFO); + + G.curscreen= sc; + + return sc; +} + +void setscreen(bScreen *sc) +{ + bScreen *sc1; + ScrArea *sa; + short mval[2]; + + if(sc->full) { /* vind de bijhorende full */ + sc1= G.main->screen.first; + while(sc1) { + sa= sc1->areabase.first; + if(sa->full==sc) { + sc= sc1; + break; + } + sc1= sc1->id.next; + } + if(sc1==0) printf("setscreen error\n"); + } + + /* G.curscreen de-activeren */ + if (G.curscreen && G.curscreen != sc) { + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->win) mywinclose(sa->win); + sa->win= 0; + if(sa->headwin) mywinclose(sa->headwin); + sa->headwin= 0; + + uiFreeBlocks(&sa->uiblocks); + + sa= sa->next; + } + } + + if (G.curscreen != sc) { + mywinset(sc->mainwin); + } + + G.curscreen= sc; + + for (sa= sc->areabase.first; sa; sa= sa->next) { + /* XXX, fixme zr */ +/* if (sa->win || sa->headwin) */ +/* printf("error in setscreen (win): %d, %d\n", sa->win, sa->headwin); */ + if (!sa->win) + openareawin(sa); + if (!sa->headwin && sa->headertype) + openheadwin(sa); + } + + /* recalculate winakt */ + getmouseco_sc(mval); + + test_scale_screen(sc); + testareas(); + + for (sa= sc->areabase.first; sa; sa= sa->next) { + SpaceLink *sl; + + for (sl= sa->spacedata.first; sl; sl= sl->next) { + sl->area= sa; + + if (sl->spacetype==SPACE_OOPS) { + SpaceOops *soops= (SpaceOops*) sl; + + /* patch als deze in oude files zit */ + if (soops->v2d.cur.xmin==soops->v2d.cur.xmax) { + extern void init_v2d_oops(View2D*); + init_v2d_oops(&soops->v2d); + } + } + } + + sa->cursor= CURSOR_STD; + } + + G.scene= sc->scene; + countall(); + + G.curscreen->winakt= 0; + curarea= sc->areabase.first; + + mainqenter(DRAWEDGES, 1); + dodrawscreen= 1; /* patch! even gets lost,,,? */ + + winqueue_break= 1; /* overal uit de queue's gaan */ +} + +static void splitarea(ScrArea *sa, char dir, float fac); + +void area_fullscreen(void) /* met curarea */ +{ + /* deze funktie toggelt: als area full is wordt de parent weer zichtbaar */ + bScreen *sc, *oldscreen; + ScrArea *newa, *old; + short headertype, fulltype; + + if(curarea->full) { + sc= curarea->full; /* de oude screen */ + fulltype = sc->full; + + // refuse to go out of SCREENAUTOPLAY as long as G_FLAGS_AUTOPLAY + // is set + + if (fulltype != SCREENAUTOPLAY || (G.flags & G_FLAGS_AUTOPLAY) == 0) { + sc->full= 0; + + /* vind oude area */ + old= sc->areabase.first; + while(old) { + if(old->full) break; + old= old->next; + } + if(old==0) {error("something wrong in areafullscreen"); return;} + + if (fulltype == SCREENAUTOPLAY) { + // in autoplay screens the headers are disabled by + // default. So use the old headertype instead + headertype = old->headertype; + } else { + // normal fullscreen. Use current headertype + headertype = curarea->headertype; + } + + copy_areadata(old, curarea); + old->headertype = headertype; + + old->full= 0; + + unlink_screen(G.curscreen); + free_libblock(&G.main->screen, G.curscreen); + G.curscreen= NULL; + + setscreen(sc); + } + + } + else { + /* is er maar 1 area? */ + if(G.curscreen->areabase.first==G.curscreen->areabase.last) return; + if(curarea->spacetype==SPACE_INFO) return; + + G.curscreen->full = SCREENFULL; + + old= curarea; + oldscreen= G.curscreen; + sc= addscreen("temp"); /* deze zet G.curscreen */ + + splitarea( (ScrArea *)sc->areabase.first, 'h', 0.99); + newa= sc->areabase.first; + newspace(newa->next, SPACE_INFO); + + curarea= old; + G.curscreen= oldscreen; /* moet voor setscreen */ + + /* area kopieeren */ + copy_areadata(newa, curarea); + + curarea->full= oldscreen; + newa->full= oldscreen; + newa->next->full= oldscreen; + + setscreen(sc); + wich_cursor(newa); + } +} + +static void area_autoplayscreen(void) +{ + bScreen *sc, *oldscreen; + ScrArea *newa, *old, *sa; + + if (curarea->full) { + area_fullscreen(); + } + + if (curarea->full == NULL) { + sa = G.curscreen->areabase.first; + while (sa) { + if (sa->spacetype == SPACE_VIEW3D) { + break; + } + sa= sa->next; + } + + if (sa) { + areawinset(sa->win); + G.curscreen->full = SCREENAUTOPLAY; + + old= curarea; + oldscreen= G.curscreen; + sc= addscreen("temp"); /* deze zet G.curscreen */ + + newa= sc->areabase.first; + + curarea= old; + G.curscreen= oldscreen; /* moet voor setscreen */ + + /* copy area settings */ + copy_areadata(newa, curarea); + newa->headertype= 0; + + curarea->full= oldscreen; + newa->full= oldscreen; + + setscreen(sc); + wich_cursor(newa); + } + } +} + +static void copy_screen(bScreen *to, bScreen *from) +{ + ScrVert *s1, *s2; + ScrEdge *se; + ScrArea *sa; + ListBase lbase; + + /* alles van to vrijgeven */ + free_screen(to); + winqueue_break= 1; /* overal uit queue's gaan */ + + duplicatelist(&to->vertbase, &from->vertbase); + duplicatelist(&to->edgebase, &from->edgebase); + duplicatelist(&to->areabase, &from->areabase); + + s1= from->vertbase.first; + s2= to->vertbase.first; + while(s1) { + s1->newv= s2; + s2= s2->next; + s1= s1->next; + } + se= to->edgebase.first; + while(se) { + se->v1= se->v1->newv; + se->v2= se->v2->newv; + sortscrvert(&(se->v1), &(se->v2)); + se= se->next; + } + + sa= to->areabase.first; + while(sa) { + sa->v1= sa->v1->newv; + sa->v2= sa->v2->newv; + sa->v3= sa->v3->newv; + sa->v4= sa->v4->newv; + sa->win= 0; + sa->headwin= 0; + + sa->uiblocks.first= sa->uiblocks.last= NULL; + + duplicatespacelist(sa, &lbase, &sa->spacedata); + sa->spacedata= lbase; + + sa= sa->next; + } + + /* op nul zetten (nodig?) */ + s1= from->vertbase.first; + while(s1) { + s1->newv= 0; + s1= s1->next; + } +} + +void duplicate_screen(void) +{ + bScreen *sc, *oldscreen; + + if(G.curscreen->full != SCREENNORMAL) return; + + /* nieuw screen maken: */ + + oldscreen= G.curscreen; + sc= addscreen(oldscreen->id.name+2); /* deze zet G.curscreen */ + copy_screen(sc, oldscreen); + + G.curscreen= oldscreen; + setscreen(sc); + +} + + +/* ************ END SCREENBEHEER ************** */ +/* ************ JOIN/SPLIT/MOVE ************** */ + +static void joinarea(ScrArea *sa, ScrEdge *onedge) +{ + ScrArea *sa2; + ScrArea *up=0, *down=0, *right=0, *left=0; + ScrEdge *setest; + short val=0; + + sa= test_edge_area(sa, onedge); + if (sa==0) return; + + /* welke edges kunnen ermee? */ + /* vind richtingen met zelfde edge */ + sa2= G.curscreen->areabase.first; + while(sa2) { + if(sa2 != sa) { + setest= screen_findedge(G.curscreen, sa2->v1, sa2->v2); + if(onedge==setest) right= sa2; + setest= screen_findedge(G.curscreen, sa2->v2, sa2->v3); + if(onedge==setest) down= sa2; + setest= screen_findedge(G.curscreen, sa2->v3, sa2->v4); + if(onedge==setest) left= sa2; + setest= screen_findedge(G.curscreen, sa2->v4, sa2->v1); + if(onedge==setest) up= sa2; + } + sa2= sa2->next; + } + + sa2= 0; + setest= 0; + + if(left) val++; + if(up) val++; + if(right) val++; + if(down) val++; + + if(val==0) return; + else if(val==1) { + if(left) sa2= left; + else if(up) sa2= up; + else if(right) sa2= right; + else if(down) sa2= down; + } + + + if(sa2) { + /* nieuwe area is oude sa */ + if(sa2==left) { + sa->v1= sa2->v1; + sa->v2= sa2->v2; + screen_addedge(G.curscreen, sa->v2, sa->v3); + screen_addedge(G.curscreen, sa->v1, sa->v4); + } + else if(sa2==up) { + sa->v2= sa2->v2; + sa->v3= sa2->v3; + screen_addedge(G.curscreen, sa->v1, sa->v2); + screen_addedge(G.curscreen, sa->v3, sa->v4); + } + else if(sa2==right) { + sa->v3= sa2->v3; + sa->v4= sa2->v4; + screen_addedge(G.curscreen, sa->v2, sa->v3); + screen_addedge(G.curscreen, sa->v1, sa->v4); + } + else if(sa2==down) { + sa->v1= sa2->v1; + sa->v4= sa2->v4; + screen_addedge(G.curscreen, sa->v1, sa->v2); + screen_addedge(G.curscreen, sa->v3, sa->v4); + } + + /* edge en area weg */ + /* remlink(&G.curscreen->edgebase, setest); */ + /* freeN(setest); */ + del_area(sa2); + BLI_remlink(&G.curscreen->areabase, sa2); + MEM_freeN(sa2); + + removedouble_scredges(); + removenotused_scredges(); + removenotused_scrverts(); /* moet als laatste */ + + testareas(); + mainqenter(DRAWEDGES, 1); + /* test cursor en inputwindow */ + mainqenter(MOUSEY, -1); + } +} + +static short testsplitpoint(ScrArea *sa, char dir, float fac) +/* return 0: geen split mogelijk */ +/* else return (integer) screencoordinaat splitpunt */ +{ + short x, y; + + /* area groot genoeg? */ + if(sa->v4->vec.x- sa->v1->vec.x <= 2*AREAMINX) return 0; + if(sa->v2->vec.y- sa->v1->vec.y <= 2*AREAMINY) return 0; + + /* voor zekerheid */ + if(fac<0.0) fac= 0.0; + if(fac>1.0) fac= 1.0; + + if(dir=='h') { + y= sa->v1->vec.y+ fac*(sa->v2->vec.y- sa->v1->vec.y); + + if(sa->v2->vec.y==G.curscreen->sizey-1 && sa->v2->vec.y- y < HEADERY+EDGEWIDTH2) + y= sa->v2->vec.y- HEADERY-EDGEWIDTH2; + + else if(sa->v1->vec.y==0 && y- sa->v1->vec.y < HEADERY+EDGEWIDTH2) + y= sa->v1->vec.y+ HEADERY+EDGEWIDTH2; + + else if(y- sa->v1->vec.y < AREAMINY) y= sa->v1->vec.y+ AREAMINY; + else if(sa->v2->vec.y- y < AREAMINY) y= sa->v2->vec.y- AREAMINY; + else y-= (y % AREAGRID); + + return y; + } + else { + x= sa->v1->vec.x+ fac*(sa->v4->vec.x- sa->v1->vec.x); + if(x- sa->v1->vec.x < AREAMINX) x= sa->v1->vec.x+ AREAMINX; + else if(sa->v4->vec.x- x < AREAMINX) x= sa->v4->vec.x- AREAMINX; + else x-= (x % AREAGRID); + + return x; + } +} + +static void splitarea(ScrArea *sa, char dir, float fac) +{ + bScreen *sc; + ScrArea *newa; + ScrVert *sv1, *sv2; + short split; + + if(sa==0) return; + + split= testsplitpoint(sa, dir, fac); + if(split==0) return; + + sc= G.curscreen; + + areawinset(sa->win); + + if(dir=='h') { + /* nieuwe vertices */ + sv1= screen_addvert(sc, sa->v1->vec.x, split); + sv2= screen_addvert(sc, sa->v4->vec.x, split); + + /* nieuwe edges */ + screen_addedge(sc, sa->v1, sv1); + screen_addedge(sc, sv1, sa->v2); + screen_addedge(sc, sa->v3, sv2); + screen_addedge(sc, sv2, sa->v4); + screen_addedge(sc, sv1, sv2); + + /* nieuwe areas: boven */ + newa= screen_addarea(sc, sv1, sa->v2, sa->v3, sv2, sa->headertype, sa->spacetype); + copy_areadata(newa, sa); + + /* area onder */ + sa->v2= sv1; + sa->v3= sv2; + + } + else { + /* nieuwe vertices */ + sv1= screen_addvert(sc, split, sa->v1->vec.y); + sv2= screen_addvert(sc, split, sa->v2->vec.y); + + /* nieuwe edges */ + screen_addedge(sc, sa->v1, sv1); + screen_addedge(sc, sv1, sa->v4); + screen_addedge(sc, sa->v2, sv2); + screen_addedge(sc, sv2, sa->v3); + screen_addedge(sc, sv1, sv2); + + /* nieuwe areas: links */ + newa= screen_addarea(sc, sa->v1, sa->v2, sv2, sv1, sa->headertype, sa->spacetype); + copy_areadata(newa, sa); + + /* area rechts */ + sa->v1= sv1; + sa->v2= sv2; + } + + /* dubbele vertices en edges verwijderen */ + removedouble_scrverts(); + removedouble_scredges(); + removenotused_scredges(); + + mainqenter(DRAWEDGES, 1); + dodrawscreen= 1; /* patch! even gets lost,,,? */ + testareas(); +} + +static void scrarea_draw_splitpoint(ScrArea *sa, char dir, float fac) +{ + int split= testsplitpoint(sa, dir, fac); + + if (split) { + if(dir=='h') { + glutil_draw_front_xor_line(sa->totrct.xmin, split, sa->totrct.xmax, split); + glutil_draw_front_xor_line(sa->totrct.xmin, split-1, sa->totrct.xmax, split-1); + } else { + glutil_draw_front_xor_line(split, sa->totrct.ymin, split, sa->totrct.ymax); + glutil_draw_front_xor_line(split-1, sa->totrct.ymin, split-1, sa->totrct.ymax); + } + } +} + +static void splitarea_interactive(ScrArea *area, ScrEdge *onedge) +{ + ScrArea *sa= area; + float fac; + unsigned short event; + short ok= 0, val, split = 0, mval[2], mvalo[2], first= 1; + char dir; + + if(sa->win==0) return; + if(sa->full) return; + + dir= scredge_is_horizontal(onedge)?'v':'h'; + + mywinset(G.curscreen->mainwin); + /* hoort al goede matrix te hebben */ + + /* rekening houden met grid en minsize */ + while(ok==0) { + getmouseco_sc(mval); + + if (first || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { + if (!first) { + scrarea_draw_splitpoint(sa, dir, fac); + } + + if(dir=='h') { + fac= mval[1]- (sa->v1->vec.y); + fac/= sa->v2->vec.y- sa->v1->vec.y; + } else { + fac= mval[0]- sa->v1->vec.x; + fac/= sa->v4->vec.x- sa->v1->vec.x; + } + + split= testsplitpoint(sa, dir, fac); + if (split) { + scrarea_draw_splitpoint(sa, dir, fac); + } else { + ok= -1; + } + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + first= 0; + } + + event= extern_qread(&val); + if(val && event==LEFTMOUSE) { + if(dir=='h') { + fac= split- (sa->v1->vec.y); + fac/= sa->v2->vec.y- sa->v1->vec.y; + } + else { + fac= split- sa->v1->vec.x; + fac/= sa->v4->vec.x- sa->v1->vec.x; + } + ok= 1; + } + if(val && event==ESCKEY) { + ok= -1; + } + } + + if (!first) { + scrarea_draw_splitpoint(sa, dir, fac); + } + + if(ok==1) { + splitarea(sa, dir, fac); + mainqenter(DRAWEDGES, 1); + dodrawscreen= 1; /* patch! even gets lost,,,? */ + } +} + +View3D *find_biggest_view3d(void) +{ + ScrArea *sa= find_biggest_area_of_type(SPACE_VIEW3D); + + if (sa) { + return (View3D*) sa->spacedata.first; + } else { + return NULL; + } +} + +ScrArea *find_biggest_area_of_type(int spacecode) +{ + ScrArea *sa, *biggest= NULL; + int bigsize; + + for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { + if (spacecode==0 || sa->spacetype==spacecode) { + int x= sa->v3->vec.x - sa->v1->vec.x; + int y= sa->v3->vec.y - sa->v1->vec.y; + int size= x*x + y*y; + + if (!biggest || size>bigsize) { + biggest= sa; + bigsize= size; + } + } + } + + return biggest; +} + +ScrArea *find_biggest_area(void) +{ + return find_biggest_area_of_type(0); +} + +static void select_connected_scredge(bScreen *sc, ScrEdge *edge) +{ + ScrEdge *se; + ScrVert *sv; + int oneselected; + char dir; + + /* select connected, alleen in de juiste richting */ + /* 'dir' is de richting van de EDGE */ + + if(edge->v1->vec.x==edge->v2->vec.x) dir= 'v'; + else dir= 'h'; + + sv= sc->vertbase.first; + while(sv) { + sv->flag= 0; + sv= sv->next; + } + + edge->v1->flag= 1; + edge->v2->flag= 1; + + oneselected= 1; + while(oneselected) { + se= sc->edgebase.first; + oneselected= 0; + while(se) { + if(se->v1->flag + se->v2->flag==1) { + if(dir=='h') if(se->v1->vec.y==se->v2->vec.y) { + se->v1->flag= se->v2->flag= 1; + oneselected= 1; + } + if(dir=='v') if(se->v1->vec.x==se->v2->vec.x) { + se->v1->flag= se->v2->flag= 1; + oneselected= 1; + } + } + se= se->next; + } + } +} + +void test_scale_screen(bScreen *sc) +/* testen of screenvertices vergroot/verkleind moeten worden */ +/* testen of offset nog klopt */ +{ + ScrVert *sv=0; + ScrEdge *se; + ScrArea *sa, *san; + int yval; + float facx, facy, tempf, min[2], max[2]; + + sc->startx= prefstax; + sc->starty= prefstay; + sc->endx= prefstax+prefsizx-1; + sc->endy= prefstay+prefsizy-1; + + /* calculate size */ + sv= sc->vertbase.first; + min[0]= min[1]= 0.0; + max[0]= sc->sizex; + max[1]= sc->sizey; + while(sv) { + min[0]= MIN2(min[0], sv->vec.x); + min[1]= MIN2(min[1], sv->vec.y); + max[0]= MAX2(max[0], sv->vec.x); + max[1]= MAX2(max[1], sv->vec.y); + sv= sv->next; + } + + /* always make 0.0 left under */ + sv= sc->vertbase.first; + while(sv) { + sv->vec.x -= min[0]; + sv->vec.y -= min[1]; + sv= sv->next; + } + + + sc->sizex= max[0]-min[0]; + sc->sizey= max[1]-min[1]; + + if(sc->sizex!= prefsizx || sc->sizey!= prefsizy) { + facx= prefsizx; + facx/= (float)sc->sizex; + facy= prefsizy; + facy/= (float)sc->sizey; + + /* make sure it fits! */ + sv= sc->vertbase.first; + while(sv) { + tempf= ((float)sv->vec.x)*facx; + sv->vec.x= (short)(tempf+0.5); + sv->vec.x+= AREAGRID-1; + sv->vec.x-= (sv->vec.x % AREAGRID); + + CLAMP(sv->vec.x, 0, prefsizx); + + tempf= ((float)sv->vec.y )*facy; + sv->vec.y= (short)(tempf+0.5); + sv->vec.y+= AREAGRID-1; + sv->vec.y-= (sv->vec.y % AREAGRID); + + CLAMP(sv->vec.y, 0, prefsizy); + + sv= sv->next; + } + + sc->sizex= prefsizx; + sc->sizey= prefsizy; + } + + /* test for collapsed areas. This could happen in some blender version... */ + sa= sc->areabase.first; + while(sa) { + san= sa->next; + if(sa->v1==sa->v2 || sa->v3==sa->v4 || sa->v2==sa->v3) { + del_area(sa); + BLI_remlink(&sc->areabase, sa); + MEM_freeN(sa); + } + sa= san; + } + + /* make each window at least HEADERY high */ + + sa= sc->areabase.first; + while(sa) { + + if(sa->v1->vec.y+HEADERY > sa->v2->vec.y) { + /* lower edge */ + se= screen_findedge(sc, sa->v4, sa->v1); + if(se && sa->v1!=sa->v2 ) { + select_connected_scredge(sc, se); + + /* all selected vertices get the right offset */ + yval= sa->v2->vec.y-HEADERY; + sv= sc->vertbase.first; + while(sv) { + /* if is a collapsed area */ + if(sv!=sa->v2 && sv!=sa->v3) { + if(sv->flag) sv->vec.y= yval; + } + sv= sv->next; + } + } + } + + sa= sa->next; + } + +} + +static void draw_front_xor_dirdist_line(char dir, int dist, int start, int end) +{ + if (dir=='h') { + glutil_draw_front_xor_line(start, dist, end, dist); + glutil_draw_front_xor_line(start, dist+1, end, dist+1); + } else { + glutil_draw_front_xor_line(dist, start, dist, end); + glutil_draw_front_xor_line(dist+1, start, dist+1, end); + } +} + +static void moveareas(ScrEdge *edge) +{ + ScrVert *v1; + ScrArea *sa; + short mvalo[2]; + short edge_start, edge_end, edge_position; + short bigger, smaller, headery, areaminy; + int delta, doit; + char dir; + + if(edge->border) return; + + dir= scredge_is_horizontal(edge)?'h':'v'; + + select_connected_scredge(G.curscreen, edge); + + edge_position= (dir=='h')?edge->v1->vec.y:edge->v1->vec.x; + edge_start= 10000; + edge_end= -10000; + for (v1= G.curscreen->vertbase.first; v1; v1= v1->next) { + if (v1->flag) { + if (dir=='h') { + edge_start= MIN2(edge_start, v1->vec.x); + edge_end= MAX2(edge_end, v1->vec.x); + } else { + edge_start= MIN2(edge_start, v1->vec.y); + edge_end= MAX2(edge_end, v1->vec.y); + } + } + } + + /* nu zijn alle vertices met 'flag==1' degene die verplaatst kunnen worden. */ + /* we lopen de areas af en testen vrije ruimte met MINSIZE */ + bigger= smaller= 10000; + sa= G.curscreen->areabase.first; + while(sa) { + if(dir=='h') { /* als top of down edge select, test hoogte */ + if(sa->headertype) { + headery= HEADERY; + areaminy= AREAMINY; + } + else { + headery= 0; + areaminy= EDGEWIDTH; + } + + if(sa->v1->flag && sa->v4->flag) { + int y1; + if(sa->v2->vec.y==G.curscreen->sizey-1) /* bovenste edge */ + y1= sa->v2->vec.y - sa->v1->vec.y-headery-EDGEWIDTH; + else + y1= sa->v2->vec.y - sa->v1->vec.y-areaminy; + bigger= MIN2(bigger, y1); + } + else if(sa->v2->flag && sa->v3->flag) { + int y1; + if(sa->v1->vec.y==0) /* onderste edge */ + y1= sa->v2->vec.y - sa->v1->vec.y-headery-EDGEWIDTH; + else + y1= sa->v2->vec.y - sa->v1->vec.y-areaminy; + smaller= MIN2(smaller, y1); + } + } + else { /* als left of right edge select, test breedte */ + if(sa->v1->flag && sa->v2->flag) { + int x1= sa->v4->vec.x - sa->v1->vec.x-AREAMINX; + bigger= MIN2(bigger, x1); + } + else if(sa->v3->flag && sa->v4->flag) { + int x1= sa->v4->vec.x - sa->v1->vec.x-AREAMINX; + smaller= MIN2(smaller, x1); + } + } + sa= sa->next; + } + + mywinset(G.curscreen->mainwin); + + doit= delta= 0; + getmouseco_sc(mvalo); + draw_front_xor_dirdist_line(dir, edge_position+delta, edge_start, edge_end); + while (!doit) { + short val; + unsigned short event= extern_qread(&val); + + if (event==MOUSEY) { + short mval[2]; + + getmouseco_sc(mval); + + draw_front_xor_dirdist_line(dir, edge_position+delta, edge_start, edge_end); + + delta= (dir=='h')?(mval[1]-mvalo[1]):(mval[0]-mvalo[0]); + delta= CLAMPIS(delta, -smaller, bigger); + + draw_front_xor_dirdist_line(dir, edge_position+delta, edge_start, edge_end); + } else if (event==LEFTMOUSE) { + doit= 1; + } else if (val) { + if (ELEM(event, ESCKEY, RIGHTMOUSE)) + doit= -1; + else if (ELEM(event, SPACEKEY, RETKEY)) + doit= 1; + } + } + draw_front_xor_dirdist_line(dir, edge_position+delta, edge_start, edge_end); + + if (doit==1) { + for (v1= G.curscreen->vertbase.first; v1; v1= v1->next) { + if (v1->flag) { + /* zo is AREAGRID netjes */ + if((dir=='v') && v1->vec.x>0 && v1->vec.x<G.curscreen->sizex-1) { + v1->vec.x+= delta; + if(delta != bigger && delta != -smaller) v1->vec.x-= (v1->vec.x % AREAGRID); + } + if((dir=='h') && v1->vec.y>0 && v1->vec.y<G.curscreen->sizey-1) { + v1->vec.y+= delta; + + /* with these lines commented out you can pull the top bar exact to the screen border. */ + /* if(delta != bigger && delta != -smaller) { */ + v1->vec.y+= AREAGRID-1; + v1->vec.y-= (v1->vec.y % AREAGRID); + + /* } */ + } + } + v1->flag= 0; + } + + removedouble_scrverts(); + removedouble_scredges(); + testareas(); + } + + glDrawBuffer(GL_BACK); + mainqenter(DRAWEDGES, 1); + dodrawscreen= 1; /* patch! even gets lost,,,? */ +} + +static void scrollheader(ScrArea *area) +{ + short mval[2], mvalo[2]; + + if(area->headbutlen<area->winx) { + area->headbutofs= 0; + } + else if(area->headbutofs+area->winx > area->headbutlen) { + area->headbutofs= area->headbutlen-area->winx; + } + + getmouseco_sc(mvalo); + + while(get_mbut() & M_MOUSE) { + getmouseco_sc(mval); + if(mval[0]!=mvalo[0]) { + area->headbutofs-= (mval[0]-mvalo[0]); + + if(area->headbutlen-area->winx < area->headbutofs) area->headbutofs= area->headbutlen-area->winx; + if(area->headbutofs<0) area->headbutofs= 0; + + scrarea_do_headchange(area); + scrarea_do_headdraw(area); + + screen_swapbuffers(); + + mvalo[0]= mval[0]; + } else { + BIF_wait_for_statechange(); + } + } +} + +int select_area(int spacetype) +{ + /* vanuit editroutines aanroepen, als er meer area's + * zijn van type 'spacetype' kan er een area aangegeven worden + */ + ScrArea *sa, *sact = NULL; + int tot=0; + unsigned short event = 0; + short val, mval[2]; + + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->spacetype==spacetype) { + sact= sa; + tot++; + } + sa= sa->next; + } + + if(tot==0) { + error("Can't do this! Open correct window"); + return 0; + } + + if(tot==1) { + if(curarea!=sact) areawinset(sact->win); + return 1; + } + else if(tot>1) { + set_cursor(CURSOR_HELP); + while(1) { + event= extern_qread(&val); + + if (val) { + if(event==ESCKEY) break; + if(event==LEFTMOUSE) break; + if(event==SPACEKEY) break; + } else { + BIF_wait_for_statechange(); + } + } + screen_set_cursor(G.curscreen); + + /* recalculate winakt */ + getmouseco_sc(mval); + + if(event==LEFTMOUSE) { + ScrArea *sa= screen_find_area_for_pt(G.curscreen, mval); + + if (sa &&sa->spacetype==spacetype) { + G.curscreen->winakt= sa->win; + areawinset(G.curscreen->winakt); + } else { + error("wrong window"); + return 0; + } + } + } + + if(event==LEFTMOUSE) return 1; + else return 0; +} + +/* ************ END JOIN/SPLIT/MOVE ************** */ +/* **************** DRAW SCREENEDGES ***************** */ + +#define EDGE_EXTEND 3 + +void drawedge(short x1, short y1, short x2, short y2) +{ + static unsigned int edcol[EDGEWIDTH]= {0x0, 0x505050, 0x909090, 0xF0F0F0, 0x0}; + int a; + + if(x1==x2) { /* vertical */ + if (y2<y1) + y1^= y2^= y1^= y2; + + if (y1==0) y1-= EDGE_EXTEND; + if (y2==G.curscreen->sizey) y2+= EDGE_EXTEND; + + x1+= EDGEWIDTH2; + x2+= EDGEWIDTH2; + + glBegin(GL_LINES); + for(a=0; a<EDGEWIDTH; a++) { + int rounding= abs(a-EDGEWIDTH2); + + cpack(edcol[a]); + glVertex2i(x1-a, y1+rounding); + glVertex2i(x2-a, y2-rounding); + } + glEnd(); + } + else { /* horizontal */ + if (x2<x1) + x1^= x2^= x1^= x2; + + if (x1==0) x1-= EDGE_EXTEND; + if (x2==G.curscreen->sizex) x2+= EDGE_EXTEND; + + y1-= EDGEWIDTH2; + y2-= EDGEWIDTH2; + + glBegin(GL_LINES); + for(a=0; a<EDGEWIDTH; a++) { + int rounding= abs(a-EDGEWIDTH2); + + cpack(edcol[a]); + glVertex2i(x1+rounding, y1+a); + glVertex2i(x2-rounding, y2+a); + } + glEnd(); + } +} + +static void drawscredge(ScrEdge *se) +{ + bScreen *sc; + vec2s *v1, *v2; + + sc= G.curscreen; + + v1= &(se->v1->vec); + v2= &(se->v2->vec); + + /* borders screen niet tekenen */ + /* vanwege resolutie verschillen (PC/SGI files) de linit een + * beetje afronden? + */ + se->border= 1; + if(v1->x<=1 && v2->x<=1) return; + if(v1->x>=sc->sizex-2 && v2->x>=sc->sizex-2) return; + if(v1->y<=1 && v2->y<=1) return; + if(v1->y>=sc->sizey-2 && v2->y>=sc->sizey-2) return; + se->border= 0; + + drawedge(v1->x, v1->y, v2->x, v2->y); +} + +void drawscreen(void) +{ + ScrEdge *se; + + mywinset(G.curscreen->mainwin); + myortho2(-0.5, (float)G.curscreen->sizex-0.5, -0.5, (float)G.curscreen->sizey-0.5); + + /* two times, because there is no 'win_swap' for this available */ + glDrawBuffer(GL_FRONT); + se= G.curscreen->edgebase.first; + while(se) { + drawscredge(se); + se= se->next; + } + + glDrawBuffer(GL_BACK); + se= G.curscreen->edgebase.first; + while(se) { + drawscredge(se); + se= se->next; + } +} + +/* ********************************* */ + +bScreen *default_twosplit() +{ + bScreen *sc= addscreen("screen"); + ScrArea *sa; + + splitarea( (ScrArea *)sc->areabase.first, 'h', 0.99); + sa= sc->areabase.first; + newspace(sa, SPACE_VIEW3D); + newspace(sa->next, SPACE_INFO); + + return sc; +} + +void initscreen(void) +{ + default_twosplit(); +} + +/***/ + +void screen_draw_info_text(bScreen *sc, char *text) { + Window *oldactwin= winlay_get_active_window(); + ScrArea *sa; + + /* + * Because this is called from within rendering + * internals it is possible our window is not + * active. + */ + window_make_active(mainwin); + + for (sa= sc->areabase.first; sa; sa= sa->next) { + if (sa->spacetype==SPACE_INFO) { + int x= sa->headbutlen - 28; + int y= 6; + + areawinset(sa->headwin); + glDrawBuffer(GL_FRONT); + + cpack(0xA08060); + glRecti(x-11, y-6, x+55, y+13); + + cpack(0x909090); + glRecti(x+55, y-6, x+1280, y+14); + + cpack(0x0); + glRasterPos2i(x, y); + BMF_DrawString(G.fonts, text); + + glFinish(); + glDrawBuffer(GL_BACK); + + sa->head_swap= WIN_FRONT_OK; + } + } + + if (oldactwin && oldactwin!=mainwin) window_make_active(oldactwin); +} + +static int curcursor; + +int get_cursor(void) { + return curcursor; +} + +void set_cursor(int curs) { + if (!(R.flag & R_RENDERING)) { + if (curs!=curcursor) { + curcursor= curs; + window_set_cursor(mainwin, curs); + } + } +} + +void unlink_screen(bScreen *sc) { + ScrArea *sa; + + for (sa= sc->areabase.first; sa; sa= sa->next) + del_area(sa); +} + +void warp_pointer(int x, int y) +{ + window_warp_pointer(mainwin, x, y); +} + +void set_timecursor(int nr) +{ + /* 10 8x8 digits */ + static char number_bitmaps[10][8]= { + {0, 56, 68, 68, 68, 68, 68, 56}, + {0, 24, 16, 16, 16, 16, 16, 56}, + {0, 60, 66, 32, 16, 8, 4, 126}, + {0, 124, 32, 16, 56, 64, 66, 60}, + {0, 32, 48, 40, 36, 126, 32, 32}, + {0, 124, 4, 60, 64, 64, 68, 56}, + {0, 56, 4, 4, 60, 68, 68, 56}, + {0, 124, 64, 32, 16, 8, 8, 8}, + {0, 60, 66, 66, 60, 66, 66, 60}, + {0, 56, 68, 68, 120, 64, 68, 56} + }; + unsigned char mask[16][2]; + unsigned char bitmap[16][2]; + int i, idx; + + memset(&bitmap, 0x00, sizeof(bitmap)); + memset(&mask, 0xFF, sizeof(mask)); + + /* print number bottom right justified */ + for (idx= 3; nr && idx>=0; idx--) { + char *digit= number_bitmaps[nr%10]; + int x = idx%2; + int y = idx/2; + + for (i=0; i<8; i++) + bitmap[i + y*8][x]= digit[i]; + nr/= 10; + } + + curcursor= CURSOR_NONE; + window_set_custom_cursor(mainwin, mask, bitmap); + BIF_renderwin_set_custom_cursor(mask, bitmap); +} + |