diff options
Diffstat (limited to 'source/blender/src/interface.c')
-rw-r--r-- | source/blender/src/interface.c | 1522 |
1 files changed, 5 insertions, 1517 deletions
diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c index 521512225c8..bbc49c1da1d 100644 --- a/source/blender/src/interface.c +++ b/source/blender/src/interface.c @@ -101,147 +101,9 @@ */ /***/ - -typedef struct { - short xim, yim; - unsigned int *rect; - short xofs, yofs; -} uiIconImage; - -typedef struct { - short mval[2]; - short qual, val; - int event; -} uiEvent; - -typedef struct { - void *xl, *large, *medium, *small; -} uiFont; - -typedef struct uiLinkLine uiLinkLine; -struct uiLinkLine { /* only for draw/edit */ - uiLinkLine *next, *prev; - - short flag, pad; - - uiBut *from, *to; -}; - -typedef struct { - void **poin; /* pointer to original pointer */ - void ***ppoin; /* pointer to original pointer-array */ - short *totlink; /* if pointer-array, here is the total */ - - short maxlink, pad; - short fromcode, tocode; - - ListBase lines; -} uiLink; - -struct uiBut { - uiBut *next, *prev; - short type, pointype, bit, bitnr, retval, flag, strwidth, ofs, pos; - - char *str; - char strdata[UI_MAX_NAME_STR]; - char drawstr[UI_MAX_DRAW_STR]; - - float x1, y1, x2, y2; - - char *poin; - float min, max; - float a1, a2, rt[4]; - float aspect; - - void (*func)(void *, void *); - void *func_arg1; - void *func_arg2; - - void (*embossfunc)(BIFColorID, float, float, float, float, float, int); - - uiLink *link; - - char *tip, *lockstr; - - BIFColorID col; - void *font; - - BIFIconID icon; - short lock, win; - short iconadd; - - /* IDPOIN data */ - uiIDPoinFuncFP idpoin_func; - ID **idpoin_idpp; - - /* BLOCK data */ - uiBlockFuncFP block_func; - - /* BUTM data */ - void (*butm_func)(void *arg, int event); - void *butm_func_arg; - - /* pointer back */ - uiBlock *block; -}; - -struct uiBlock { - uiBlock *next, *prev; - - ListBase buttons; - Panel *panel; - - char name[UI_MAX_NAME_STR]; - - float winmat[4][4]; - - float minx, miny, maxx, maxy; - float aspect; - - void (*butm_func)(void *arg, int event); - void *butm_func_arg; - - void (*func)(void *arg1, void *arg2); - void *func_arg1; - void *func_arg2; - - /* extra draw function for custom blocks */ - void (*drawextra)(); - - BIFColorID col; - short font; /* indices */ - int afterval; - void *curfont; - - short autofill, flag, win, winq, direction, dt, frontbuf, auto_open; //frontbuf see below - void *saveunder; - - float xofs, yofs; // offset to parent button - rctf parentrct; // for pulldowns, rect the mouse is allowed outside of menu (parent button) -}; - -/* block->frontbuf: (only internal here), to nice localize the old global var uiFrontBuf */ -#define UI_NEED_DRAW_FRONT 1 -#define UI_HAS_DRAW_FRONT 2 - -/* panel drawing defines */ -#define PNL_GRID 4 -#define PNL_DIST 8 -#define PNL_SAFETY 8 -#define PNL_HEADER 20 - -/* panel->flag */ -#define PNL_SELECT 1 -#define PNL_CLOSEDX 2 -#define PNL_CLOSEDY 4 -#define PNL_CLOSED 6 -#define PNL_TABBED 8 -#define PNL_OVERLAP 16 - - /* ************ GLOBALS ************* */ -static float UIwinmat[4][4]; +float UIwinmat[4][4]; static int UIlock= 0, UIafterval; static char *UIlockstr=NULL; static void (*UIafterfunc)(void *arg, int event); @@ -252,14 +114,10 @@ static uiBut *UIbuttip; /* ************* PROTOTYPES ***************** */ -static void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); -static void ui_check_but(uiBut *but); static void ui_set_but_val(uiBut *but, double value); static double ui_get_but_val(uiBut *but); -static void ui_draw_panel(uiBlock *block); -static void ui_drag_panel(uiBlock *block); -static void ui_do_panel(uiBlock *block, uiEvent *uevent); -static int panel_has_tabs(Panel *panel); + + /* ****************************** */ @@ -2195,272 +2053,6 @@ static void ui_draw_but(uiBut *but) } } -/* --------- generic helper drawng calls ---------------- */ - -/* supposes you draw the actual box atop of this. */ -void uiSoftShadow(float minx, float miny, float maxx, float maxy, float rad, int alpha) -{ - - glShadeModel(GL_SMOOTH); - glEnable(GL_BLEND); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - - /* quads start left-top, clockwise */ - - /* left */ - glBegin(GL_POLYGON); - glColor4ub(0, 0, 0, 0); - glVertex2f( minx-rad, maxy-rad); - glColor4ub(0, 0, 0, alpha); - glVertex2f( minx+rad, maxy-rad); - glColor4ub(0, 0, 0, alpha); - glVertex2f( minx+rad, miny+rad); - glColor4ub(0, 0, 0, 0); - glVertex2f( minx-rad, miny-rad); - glEnd(); - - /* bottom */ - glBegin(GL_POLYGON); - glColor4ub(0, 0, 0, alpha); - glVertex2f( minx+rad, miny+rad); - glColor4ub(0, 0, 0, alpha); - glVertex2f( maxx-rad, miny+rad); - glColor4ub(0, 0, 0, 0); - glVertex2f( maxx+rad, miny-rad); - glColor4ub(0, 0, 0, 0); - glVertex2f( minx-rad, miny-rad); - glEnd(); - - /* right */ - glBegin(GL_POLYGON); - glColor4ub(0, 0, 0, alpha); - glVertex2f( maxx-rad, maxy-rad); - glColor4ub(0, 0, 0, 0); - glVertex2f( maxx+rad, maxy-rad); - glColor4ub(0, 0, 0, 0); - glVertex2f( maxx+rad, miny-rad); - glColor4ub(0, 0, 0, alpha); - glVertex2f( maxx-rad, miny+rad); - glEnd(); - - glDisable(GL_BLEND); - glShadeModel(GL_FLAT); -} - - -#define UI_RB_ALPHA 16 -static int roundboxtype= 15; - -void uiSetRoundBox(int type) -{ - roundboxtype= type; - - /* flags to set which corners will become rounded: - - 1------2 - | | - 8------4 - */ - -} - -void gl_round_box_topshade(float minx, float miny, float maxx, float maxy, float rad) -{ - float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293}, - {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; - char col[7]= {140, 165, 195, 210, 230, 245, 255}; - int a; - char alpha=255; - - if(roundboxtype & UI_RB_ALPHA) alpha= 128; - - /* mult */ - for(a=0; a<7; a++) { - vec[a][0]*= rad; vec[a][1]*= rad; - } - - /* shades from grey->white->grey */ - glBegin(GL_LINE_STRIP); - - if(roundboxtype & 3) { - /* corner right-top */ - glColor4ub(140, 140, 140, alpha); - glVertex2f( maxx, maxy-rad); - for(a=0; a<7; a++) { - glColor4ub(col[a], col[a], col[a], alpha); - glVertex2f( maxx-vec[a][1], maxy-rad+vec[a][0]); - } - glColor4ub(225, 225, 225, alpha); - glVertex2f( maxx-rad, maxy); - - - /* corner left-top */ - glVertex2f( minx+rad, maxy); - for(a=0; a<7; a++) { - glColor4ub(col[6-a], col[6-a], col[6-a], alpha); - glVertex2f( minx+rad-vec[a][0], maxy-vec[a][1]); - } - glVertex2f( minx, maxy-rad); - } - else { - glColor4ub(225, 225, 225, alpha); - glVertex2f( minx, maxy); - glVertex2f( maxx, maxy); - } - - glEnd(); -} - - -void gl_round_box(float minx, float miny, float maxx, float maxy, float rad) -{ - float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293}, - {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; - int a; - - /* mult */ - for(a=0; a<7; a++) { - vec[a][0]*= rad; vec[a][1]*= rad; - } - - /* start with corner right-bottom */ - if(roundboxtype & 4) { - glVertex2f( maxx-rad, miny); - for(a=0; a<7; a++) { - glVertex2f( maxx-rad+vec[a][0], miny+vec[a][1]); - } - glVertex2f( maxx, miny+rad); - } - else glVertex2f( maxx, miny); - - /* corner right-top */ - if(roundboxtype & 2) { - glVertex2f( maxx, maxy-rad); - for(a=0; a<7; a++) { - glVertex2f( maxx-vec[a][1], maxy-rad+vec[a][0]); - } - glVertex2f( maxx-rad, maxy); - } - else glVertex2f( maxx, maxy); - - /* corner left-top */ - if(roundboxtype & 1) { - glVertex2f( minx+rad, maxy); - for(a=0; a<7; a++) { - glVertex2f( minx+rad-vec[a][0], maxy-vec[a][1]); - } - glVertex2f( minx, maxy-rad); - } - else glVertex2f( minx, maxy); - - /* corner left-bottom */ - if(roundboxtype & 8) { - glVertex2f( minx, miny+rad); - for(a=0; a<7; a++) { - glVertex2f( minx+vec[a][1], miny+rad-vec[a][0]); - } - glVertex2f( minx+rad, miny); - } - else glVertex2f( minx, miny); - -} - -/* for headers and floating panels */ -void uiRoundBoxEmboss(float minx, float miny, float maxx, float maxy, float rad) -{ - float color[4]; - - if(roundboxtype & UI_RB_ALPHA) { - glGetFloatv(GL_CURRENT_COLOR, color); - color[3]= 0.5; - glColor4fv(color); - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - } - - /* solid part */ - glBegin(GL_POLYGON); - gl_round_box(minx, miny, maxx, maxy, rad); - glEnd(); - - /* set antialias line */ - glEnable( GL_LINE_SMOOTH ); - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - - gl_round_box_topshade(minx+1, miny+1, maxx-1, maxy-1, rad); - - if(roundboxtype & UI_RB_ALPHA) glColor4ub(0,0,0, 128); else glColor4ub(0,0,0, 255); - glBegin(GL_LINE_LOOP); - gl_round_box(minx, miny, maxx, maxy, rad); - glEnd(); - - glDisable( GL_BLEND ); - glDisable( GL_LINE_SMOOTH ); - -} - - -/* plain antialiased unfilled rectangle */ -void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad) -{ - float color[4]; - - if(roundboxtype & UI_RB_ALPHA) { - glGetFloatv(GL_CURRENT_COLOR, color); - color[3]= 0.5; - glColor4fv(color); - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - } - - /* set antialias line */ - glEnable( GL_LINE_SMOOTH ); - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - - glBegin(GL_LINE_LOOP); - gl_round_box(minx, miny, maxx, maxy, rad); - glEnd(); - - glDisable( GL_BLEND ); - glDisable( GL_LINE_SMOOTH ); -} - - - -/* plain antialiased filled box */ -void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad) -{ - float color[4]; - - if(roundboxtype & UI_RB_ALPHA) { - glGetFloatv(GL_CURRENT_COLOR, color); - color[3]= 0.5; - glColor4fv(color); - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - } - - /* solid part */ - glBegin(GL_POLYGON); - gl_round_box(minx, miny, maxx, maxy, rad); - glEnd(); - - /* set antialias line */ - glEnable( GL_LINE_SMOOTH ); - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - - glBegin(GL_LINE_LOOP); - gl_round_box(minx, miny, maxx, maxy, rad); - glEnd(); - - glDisable( GL_BLEND ); - glDisable( GL_LINE_SMOOTH ); -} - - void uiDrawMenuBox(float minx, float miny, float maxx, float maxy) @@ -2744,7 +2336,7 @@ static void ui_positionblock(uiBlock *block, uiBut *but) } -static void ui_autofill(uiBlock *block) +void ui_autofill(uiBlock *block) { uiBut *but; float *maxw, *maxh, startx = 0, starty, height = 0; @@ -5520,7 +5112,7 @@ uiBlock *uiGetBlock(char *name, ScrArea *sa) } -static void ui_check_but(uiBut *but) +void ui_check_but(uiBut *but) { /* if something changed in the button */ ID *id; @@ -6268,1107 +5860,3 @@ short pupmenu_col(char *instr, int maxrow) return val; } -/* ************** panels ************* */ - -static void copy_panel_offset(Panel *pa, Panel *papar) -{ - /* with respect to sizes... papar is parent */ - - pa->ofsx= papar->ofsx; - pa->ofsy= papar->ofsy + papar->sizey-pa->sizey; -} - - - -/* ugly global... but will be NULLed after each 'newPanel' call */ -static char *panel_tabbed=NULL, *group_tabbed=NULL; - -void uiNewPanelTabbed(char *panelname, char *groupname) -{ - panel_tabbed= panelname; - group_tabbed= groupname; -} - -/* another global... */ -static int pnl_style= UI_PNL_TRANSP; - -void uiSetPanelStyle(int style) -{ - pnl_style= style; -} - - -/* ofsx/ofsy only used for new panel definitions */ -/* return 1 if visible (create buttons!) */ -int uiNewPanel(ScrArea *sa, uiBlock *block, char *panelname, char *tabname, int ofsx, int ofsy, int sizex, int sizey) -{ - Panel *pa, *palign; - - /* check if Panel exists, then use that one */ - pa= sa->panels.first; - while(pa) { - if( strncmp(pa->panelname, panelname, UI_MAX_NAME_STR)==0) { - if( strncmp(pa->tabname, tabname, UI_MAX_NAME_STR)==0) { - break; - } - } - pa= pa->next; - } - - if(pa==NULL) { - - /* new panel */ - pa= MEM_callocN(sizeof(Panel), "new panel"); - BLI_addtail(&sa->panels, pa); - strncpy(pa->panelname, panelname, UI_MAX_NAME_STR); - strncpy(pa->tabname, tabname, UI_MAX_NAME_STR); - - pa->ofsx= ofsx & ~(PNL_GRID-1); - pa->ofsy= ofsy & ~(PNL_GRID-1); - pa->sizex= sizex; - pa->sizey= sizey; - pa->style= pnl_style; - - /* pre align, for good sorting later on */ - if(sa->spacetype==SPACE_BUTS && pa->prev) { - SpaceButs *sbuts= sa->spacedata.first; - - palign= pa->prev; - if(sbuts->align==BUT_VERTICAL) { - pa->ofsy= palign->ofsy - pa->sizey - PNL_HEADER; - } - else if(sbuts->align==BUT_HORIZONTAL) { - pa->ofsx= palign->ofsx + palign->sizex; - } - } - /* make new Panel tabbed? */ - if(panel_tabbed && group_tabbed) { - Panel *papar; - for(papar= sa->panels.first; papar; papar= papar->next) { - if(papar->active && papar->paneltab==NULL) { - if( strncmp(panel_tabbed, papar->panelname, UI_MAX_NAME_STR)==0) { - if( strncmp(group_tabbed, papar->tabname, UI_MAX_NAME_STR)==0) { - pa->paneltab= papar; - copy_panel_offset(pa, papar); - break; - } - } - } - } - } - } - - block->panel= pa; - pa->active= 1; - - /* clear global */ - panel_tabbed= group_tabbed= NULL; - - if(block->panel->paneltab) return 0; - if(block->panel->flag & PNL_CLOSED) return 0; - - return 1; -} - -void uiFreePanels(ListBase *lb) -{ - Panel *panel; - - while( (panel= lb->first) ) { - BLI_remlink(lb, panel); - MEM_freeN(panel); - } -} - -void uiNewPanelHeight(uiBlock *block, int sizey) -{ - if(sizey<64) sizey= 64; - - if(block->panel) { - block->panel->ofsy+= (block->panel->sizey - sizey); - block->panel->sizey= sizey; - } -} - -static int panel_has_tabs(Panel *panel) -{ - Panel *pa= curarea->panels.first; - - if(panel==NULL) return 0; - - while(pa) { - if(pa->paneltab==panel) return 1; - pa= pa->next; - } - return 0; -} - -static void ui_scale_panel_block(uiBlock *block) -{ - uiBut *but; - float facx= 1.0, facy= 1.0; - int centrex= 0, topy=0, tabsy=0; - - if(block->panel==NULL) return; - - if(block->autofill) ui_autofill(block); - /* buttons min/max centered, offset calculated */ - uiBoundsBlock(block, 0); - - if( block->maxx-block->minx > block->panel->sizex - 2*PNL_SAFETY ) { - facx= (block->panel->sizex - (2*PNL_SAFETY))/( block->maxx-block->minx ); - } - else centrex= (block->panel->sizex-( block->maxx-block->minx ) - PNL_SAFETY)/2; - - // tabsy= PNL_HEADER*panel_has_tabs(block->panel); - if( (block->maxy-block->miny) > block->panel->sizey - 2*PNL_SAFETY - tabsy) { - facy= (block->panel->sizey - (2*PNL_SAFETY) - tabsy)/( block->maxy-block->miny ); - } - else topy= (block->panel->sizey- 2*PNL_SAFETY - tabsy) - ( block->maxy-block->miny ) ; - - but= block->buttons.first; - while(but) { - but->x1= PNL_SAFETY+centrex+ facx*(but->x1-block->minx); - but->y1= PNL_SAFETY+topy + facy*(but->y1-block->miny); - but->x2= PNL_SAFETY+centrex+ facx*(but->x2-block->minx); - but->y2= PNL_SAFETY+topy + facy*(but->y2-block->miny); - if(facx!=1.0) ui_check_but(but); /* for strlen */ - but= but->next; - } - - block->maxx= block->panel->sizex; - block->maxy= block->panel->sizey; - block->minx= block->miny= 0.0; - -} - -// for 'home' key -void uiSetPanel_view2d(ScrArea *sa) -{ - Panel *pa; - float minx=10000, maxx= -10000, miny=10000, maxy= -10000; - int done=0; - - pa= sa->panels.first; - while(pa) { - if(pa->active) { - done= 1; - if(pa->ofsx < minx) minx= pa->ofsx; - if(pa->ofsx+pa->sizex > maxx) maxx= pa->ofsx+pa->sizex; - if(pa->ofsy < miny) miny= pa->ofsy; - if(pa->ofsy+pa->sizey+PNL_HEADER > maxy) maxy= pa->ofsy+pa->sizey+PNL_HEADER; - } - pa= pa->next; - } - if(done) { - G.v2d->tot.xmin= minx-PNL_DIST; - G.v2d->tot.xmax= maxx+PNL_DIST; - G.v2d->tot.ymin= miny-PNL_DIST; - G.v2d->tot.ymax= maxy+PNL_DIST; - } - else { - G.v2d->tot.xmin= 0; - G.v2d->tot.xmax= 1280; - G.v2d->tot.ymin= 0; - G.v2d->tot.ymax= 228; - } - -} - -// make sure the panels are not outside 'tot' area -void uiMatchPanel_view2d(ScrArea *sa) -{ - Panel *pa; - - pa= sa->panels.first; - while(pa) { - if(pa->active) { - if(pa->ofsx < G.v2d->tot.xmin) G.v2d->tot.xmin= pa->ofsx; - if(pa->ofsx+pa->sizex > G.v2d->tot.xmax) - G.v2d->tot.xmax= pa->ofsx+pa->sizex; - if(pa->ofsy < G.v2d->tot.ymin) G.v2d->tot.ymin= pa->ofsy; - if(pa->ofsy+pa->sizey+PNL_HEADER > G.v2d->tot.ymax) - G.v2d->tot.ymax= pa->ofsy+pa->sizey+PNL_HEADER; - } - pa= pa->next; - } -} - -/* extern used ny previewrender */ -void uiPanelPush(uiBlock *block) -{ - glPushMatrix(); - if(block->panel) { - glTranslatef((float)block->panel->ofsx, (float)block->panel->ofsy, 0.0); - i_translate((float)block->panel->ofsx, (float)block->panel->ofsy, 0.0, UIwinmat); - } -} - -void uiPanelPop(uiBlock *block) -{ - glPopMatrix(); - Mat4CpyMat4(UIwinmat, block->winmat); -} - -uiBlock *uiFindOpenPanelBlockName(ListBase *lb, char *name) -{ - uiBlock *block; - - for(block= lb->first; block; block= block->next) { - if(block->panel && block->panel->active && block->panel->paneltab==NULL) { - if(block->panel->flag & PNL_CLOSED); - else if(strncmp(name, block->panel->panelname, UI_MAX_NAME_STR)==0) break; - } - } - return block; -} - -static void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3) -{ - - // we draw twice, anti polygons not widely supported... - - glBegin(GL_POLYGON); - glVertex2f(x1, y1); - glVertex2f(x2, y2); - glVertex2f(x3, y3); - glEnd(); - - /* set antialias line */ - glEnable( GL_LINE_SMOOTH ); - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - - glBegin(GL_LINE_LOOP); - glVertex2f(x1, y1); - glVertex2f(x2, y2); - glVertex2f(x3, y3); - glEnd(); - - glDisable( GL_LINE_SMOOTH ); - glDisable( GL_BLEND ); - -} - -/* 'icon' for panel header */ -static void ui_draw_tria_icon(float x, float y, float aspect, char dir) -{ - - - glColor3ub(240, 240, 240); - - if(dir=='h') { - ui_draw_anti_tria( x, y, x, y+12.0, x+10, y+6); - } - else { - ui_draw_anti_tria( x, y+10.0, x+12, y+10.0, x+6, y); - } - - -} - -static void ui_set_panel_pattern(char dir) -{ - static int firsttime= 1; - static GLubyte path[4*32], patv[4*32]; - int a,b,i=0; - - if(firsttime) { - firsttime= 0; - for(a=0; a<128; a++) patv[a]= 0x33; - for(a=0; a<8; a++) { - for(b=0; b<4; b++) path[i++]= 0xff; /* 1 scanlines */ - for(b=0; b<12; b++) path[i++]= 0x0; /* 3 lines */ - } - } - glEnable(GL_POLYGON_STIPPLE); - if(dir=='h') glPolygonStipple(path); - else glPolygonStipple(patv); -} - -static char *ui_block_cut_str(uiBlock *block, char *str, short okwidth) -{ - short width, ofs=strlen(str); - static char str1[128]; - - if(ofs>127) return str; - - width= block->aspect*BIF_GetStringWidth(block->curfont, str, (U.transopts & TR_BUTTONS)); - - if(width <= okwidth) return str; - strcpy(str1, str); - - while(width > okwidth && ofs>0) { - ofs--; - str1[ofs]= 0; - - width= block->aspect*BIF_GetStringWidth(block->curfont, str1, 0); - - if(width < 10) break; - } - return str1; -} - - -#define PNL_ICON 20 -#define PNL_DRAGGER 20 - - -static void ui_draw_panel_header(uiBlock *block) -{ - Panel *pa, *panel= block->panel; - float width; - int a, nr= 1; - char *str; - - /* count */ - pa= curarea->panels.first; - while(pa) { - if(pa->active) { - if(pa->paneltab==panel) nr++; - } - pa= pa->next; - } - - if(nr==1) { - glColor3ub(255,255,255); - glRasterPos2f(block->minx+40, block->maxy+5); - BIF_DrawString(block->curfont, block->panel->panelname, (U.transopts & TR_BUTTONS), 0); - return; - } - - a= 0; - width= (panel->sizex - 3 - 2*PNL_ICON)/nr; - pa= curarea->panels.first; - while(pa) { - if(pa->active==0); - else if(pa==panel) { - /* active tab */ - uiSetRoundBox(15); - glColor3ub(140, 140, 147); - uiRoundBox(2+PNL_ICON+a*width, panel->sizey+3, PNL_ICON+(a+1)*width, panel->sizey+PNL_HEADER-3, 8); - - glColor3ub(255,255,255); - glRasterPos2f(10+PNL_ICON+a*width, panel->sizey+5); - str= ui_block_cut_str(block, pa->panelname, (short)(width-10)); - BIF_DrawString(block->curfont, str, (U.transopts & TR_BUTTONS), 0); - - a++; - } - else if(pa->paneltab==panel) { - /* not active tab */ - - glColor3ub(95,95,95); - glRasterPos2f(10+PNL_ICON+a*width, panel->sizey+5); - str= ui_block_cut_str(block, pa->panelname, (short)(width-10)); - BIF_DrawString(block->curfont, str, (U.transopts & TR_BUTTONS), 0); - - a++; - } - pa= pa->next; - } - - // dragger - uiSetRoundBox(15); - glColor3ub(140, 140, 147); - uiRoundBox(panel->sizex-PNL_ICON+5, panel->sizey+5, panel->sizex-5, panel->sizey+PNL_HEADER-5, 5); - -} - -static void ui_draw_panel(uiBlock *block) -{ - int align=0; - - if(block->panel->paneltab) return; - - if(curarea->spacetype==SPACE_BUTS) { - SpaceButs *sbuts= curarea->spacedata.first; - align= sbuts->align; - } - - if(block->panel->flag & PNL_CLOSEDY) { - uiSetRoundBox(15); - glColor3ub(160, 160, 167); - uiRoundBox(block->minx, block->maxy, block->maxx, block->maxy+PNL_HEADER, 10); - - // title - glColor3ub(255,255,255); - glRasterPos2f(block->minx+40, block->maxy+5); - BIF_DrawString(block->curfont, block->panel->panelname, (U.transopts & TR_BUTTONS), 0); - - // border - if(block->panel->flag & PNL_SELECT) { - glColor3ub(64, 64, 64); - uiRoundRect(block->minx, block->maxy, block->maxx, block->maxy+PNL_HEADER, 10); - } - if(block->panel->flag & PNL_OVERLAP) { - glColor3ub(240, 240, 240); - uiRoundRect(block->minx, block->maxy, block->maxx, block->maxy+PNL_HEADER, 10); - } - - } - else if(block->panel->flag & PNL_CLOSEDX) { - char str[4]; - int a, end, ofs; - - uiSetRoundBox(15); - glColor3ub(160, 160, 167); - uiRoundBox(block->minx, block->miny, block->minx+PNL_HEADER, block->maxy+PNL_HEADER, 10); - - // title, only capitals for now - glColor3ub(255,255,255); - str[1]= 0; - end= strlen(block->panel->panelname); - ofs= 20; - for(a=0; a<end; a++) { - str[0]= block->panel->panelname[a]; - if( isupper(str[0]) ) { - glRasterPos2f(block->minx+5, block->maxy-ofs); - BIF_DrawString(block->curfont, str, 0, 0); - ofs+= 15; - } - } - - // border - if(block->panel->flag & PNL_SELECT) { - glColor3ub(64, 64, 64); - uiRoundRect(block->minx, block->miny, block->minx+PNL_HEADER, block->maxy+PNL_HEADER, 10); - } - if(block->panel->flag & PNL_OVERLAP) { - glColor3ub(240, 240, 240); - uiRoundRect(block->minx, block->miny, block->minx+PNL_HEADER, block->maxy+PNL_HEADER, 10); - } - - } - else { - - uiSetRoundBox(3); - - if(block->panel->style== UI_PNL_SOLID) { - glColor3ub(160, 160, 167); - uiRoundBox(block->minx, block->maxy, block->maxx, block->maxy+PNL_HEADER, 10); - // blend now for panels in 3d window, test... - glEnable(GL_BLEND); - glColor4ub(198, 198, 198, 100); - glRectf(block->minx, block->miny, block->maxx, block->maxy); - - if(align) { - glColor4ub(206, 206, 206, 100); - if(align==BUT_HORIZONTAL) ui_set_panel_pattern('h'); - else ui_set_panel_pattern('v'); - - glRectf(block->minx, block->miny, block->maxx, block->maxy); - glDisable(GL_POLYGON_STIPPLE); - } - glDisable(GL_BLEND); - } - else { - glColor3ub(218, 218, 218); - uiRoundRect(block->minx, block->miny, block->maxx, block->maxy+PNL_HEADER, 10); - } - - - ui_draw_panel_header(block); - - // border - uiSetRoundBox(3); - if(block->panel->flag & PNL_SELECT) { - glColor3ub(64, 64, 64); - uiRoundRect(block->minx, block->miny, block->maxx, block->maxy+PNL_HEADER, 10); - } - if(block->panel->flag & PNL_OVERLAP) { - glColor3ub(240, 240, 240); - uiRoundRect(block->minx, block->miny, block->maxx, block->maxy+PNL_HEADER, 10); - } - - /* and a soft shadow-line for now */ - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - glColor4ub(0, 0, 0, 50); - fdrawline(block->maxx, block->miny, block->maxx, block->maxy+PNL_HEADER/2); - fdrawline(block->minx, block->miny, block->maxx, block->miny); - glDisable(GL_BLEND); - - } - - /* draw close icon */ - - if(block->panel->flag & PNL_CLOSEDY) - ui_draw_tria_icon(block->minx+6, block->maxy+3, block->aspect, 'h'); - else if(block->panel->flag & PNL_CLOSEDX) - ui_draw_tria_icon(block->minx+4, block->maxy+2, block->aspect, 'h'); - else - ui_draw_tria_icon(block->minx+6, block->maxy+3, block->aspect, 'v'); - - -} - -static void ui_redraw_select_panel(ScrArea *sa) -{ - /* only for beauty, make sure the panel thats moved is on top */ - /* better solution later? */ - uiBlock *block; - - for(block= sa->uiblocks.first; block; block= block->next) { - if(block->panel && (block->panel->flag & PNL_SELECT)) { - uiDrawBlock(block); - } - } - -} - - -/* ------------ panel alignment ---------------- */ - - -/* this function is needed because uiBlock and Panel itself dont -change sizey or location when closed */ -static int get_panel_real_ofsy(Panel *pa) -{ - if(pa->flag & PNL_CLOSEDY) return pa->ofsy+pa->sizey; - else if(pa->paneltab && (pa->paneltab->flag & PNL_CLOSEDY)) return pa->ofsy+pa->sizey; - else return pa->ofsy; -} - -static int get_panel_real_ofsx(Panel *pa) -{ - if(pa->flag & PNL_CLOSEDX) return pa->ofsx+PNL_HEADER; - else if(pa->paneltab && (pa->paneltab->flag & PNL_CLOSEDX)) return pa->ofsx+PNL_HEADER; - else return pa->ofsx+pa->sizex; -} - - -typedef struct PanelSort { - Panel *pa, *orig; -} PanelSort; - -static int find_leftmost_panel(const void *a1, const void *a2) -{ - const PanelSort *ps1=a1, *ps2=a2; - - if( ps1->pa->ofsx > ps2->pa->ofsx) return 1; - else if( ps1->pa->ofsx < ps2->pa->ofsx) return -1; - - return 0; -} - - -static int find_highest_panel(const void *a1, const void *a2) -{ - const PanelSort *ps1=a1, *ps2=a2; - - if( ps1->pa->ofsy < ps2->pa->ofsy) return 1; - else if( ps1->pa->ofsy > ps2->pa->ofsy) return -1; - - return 0; -} - -/* this doesnt draw */ -/* returns 1 when it did something */ -int uiAlignPanelStep(ScrArea *sa, float fac) -{ - SpaceButs *sbuts= sa->spacedata.first; - Panel *pa; - PanelSort *ps, *panelsort, *psnext; - int a, tot=0, done; - - if(sa->spacetype!=SPACE_BUTS) { - return 0; - } - - /* count active, not tabbed Panels */ - for(pa= sa->panels.first; pa; pa= pa->next) { - if(pa->active && pa->paneltab==NULL) tot++; - } - - if(tot==0) return 0; - - /* extra; change close direction? */ - for(pa= sa->panels.first; pa; pa= pa->next) { - if(pa->active && pa->paneltab==NULL) { - if( (pa->flag & PNL_CLOSEDX) && (sbuts->align==BUT_VERTICAL) ) - pa->flag ^= PNL_CLOSED; - - else if( (pa->flag & PNL_CLOSEDY) && (sbuts->align==BUT_HORIZONTAL) ) - pa->flag ^= PNL_CLOSED; - - } - } - - panelsort= MEM_callocN( tot*sizeof(PanelSort), "panelsort"); - - /* fill panelsort array */ - ps= panelsort; - for(pa= sa->panels.first; pa; pa= pa->next) { - if(pa->active && pa->paneltab==NULL) { - ps->pa= MEM_dupallocN(pa); - ps->orig= pa; - ps++; - } - } - - if(sbuts->align==BUT_VERTICAL) - qsort(panelsort, tot, sizeof(PanelSort), find_highest_panel); - else - qsort(panelsort, tot, sizeof(PanelSort), find_leftmost_panel); - - - /* no smart other default start loc! this keeps switching f5/f6/etc compatible */ - ps= panelsort; - ps->pa->ofsx= 0; - ps->pa->ofsy= 0; - - for(a=0 ; a<tot-1; a++, ps++) { - psnext= ps+1; - - if(sbuts->align==BUT_VERTICAL) { - psnext->pa->ofsx = ps->pa->ofsx; - psnext->pa->ofsy = get_panel_real_ofsy(ps->pa) - psnext->pa->sizey-PNL_HEADER-PNL_DIST; - } - else { - psnext->pa->ofsx = get_panel_real_ofsx(ps->pa)+PNL_DIST; - psnext->pa->ofsy = ps->pa->ofsy; - } - } - - /* we interpolate */ - done= 0; - ps= panelsort; - for(a=0; a<tot; a++, ps++) { - if( (ps->pa->flag & PNL_SELECT)==0) { - if( (ps->orig->ofsx != ps->pa->ofsx) || (ps->orig->ofsy != ps->pa->ofsy)) { - ps->orig->ofsx= floor(0.5 + fac*ps->pa->ofsx + (1.0-fac)*ps->orig->ofsx); - ps->orig->ofsy= floor(0.5 + fac*ps->pa->ofsy + (1.0-fac)*ps->orig->ofsy); - done= 1; - } - } - } - - /* copy locations to tabs */ - for(pa= sa->panels.first; pa; pa= pa->next) { - if(pa->paneltab && pa->active) { - copy_panel_offset(pa, pa->paneltab); - } - } - - /* free panelsort array */ - ps= panelsort; - for(a=0; a<tot; a++, ps++) { - MEM_freeN(ps->pa); - } - MEM_freeN(panelsort); - - return done; -} - - -static void ui_animate_panels(ScrArea *sa) -{ - double time=0, ltime; - float result= 0.0, fac= 0.2; - - ltime = PIL_check_seconds_timer(); - - /* for max 1 second, interpolate positions */ - while(TRUE) { - - if( uiAlignPanelStep(sa, fac) ) { - /* warn: this re-allocs uiblocks! */ - scrarea_do_windraw(curarea); - ui_redraw_select_panel(curarea); - screen_swapbuffers(); - } - else { - addqueue(curarea->win, REDRAW,1 ); // because 'Animate' is also called as redraw - break; - } - - if(result >= 1.0) break; - - if(result==0.0) { // firsttime - time = PIL_check_seconds_timer()-ltime; - if(time > 0.5) fac= 0.7; - else if(time > 0.2) fac= 0.5; - else if(time > 0.1) fac= 0.4; - else if(time > 0.05) fac= 0.3; // 11 steps - } - - result= fac + (1.0-fac)*result; - - if(result > 0.98) { - result= 1.0; - fac= 1.0; - } - } -} - -/* only draws blocks with panels */ -void uiDrawBlocksPanels(ScrArea *sa, int re_align) -{ - uiBlock *block; - Panel *panot, *panew, *patest; - - /* scaling contents */ - block= sa->uiblocks.first; - while(block) { - if(block->panel) ui_scale_panel_block(block); - block= block->next; - } - - /* consistancy; are panels not made, whilst they have tabs */ - for(panot= sa->panels.first; panot; panot= panot->next) { - if(panot->active==0) { // not made - - for(panew= sa->panels.first; panew; panew= panew->next) { - if(panew->active) { - if(panew->paneltab==panot) { // panew is tab in notmade pa - break; - } - } - } - /* now panew can become the new parent, check all other tabs */ - if(panew) { - for(patest= sa->panels.first; patest; patest= patest->next) { - if(patest->paneltab == panot) { - patest->paneltab= panew; - } - } - panot->paneltab= panew; - panew->paneltab= NULL; - addqueue(sa->win, REDRAW, 1); // the buttons panew were not made - } - } - } - - /* re-align */ - if(re_align) uiAlignPanelStep(sa, 1.0); - - /* draw */ - block= sa->uiblocks.first; - while(block) { - if(block->panel) uiDrawBlock(block); - block= block->next; - } - -} - - - -/* ------------ panel merging ---------------- */ - -static void check_panel_overlap(ScrArea *sa, Panel *panel) -{ - Panel *pa= sa->panels.first; - - /* also called with panel==NULL for clear */ - - while(pa) { - pa->flag &= ~PNL_OVERLAP; - if(panel && (pa != panel)) { - if(pa->paneltab==NULL && pa->active) { - float safex= 0.2, safey= 0.2; - - if( pa->flag & PNL_CLOSEDX) safex= 0.05; - else if(pa->flag & PNL_CLOSEDY) safey= 0.05; - else if( panel->flag & PNL_CLOSEDX) safex= 0.05; - else if(panel->flag & PNL_CLOSEDY) safey= 0.05; - - if( pa->ofsx > panel->ofsx- safex*panel->sizex) - if( pa->ofsx+pa->sizex < panel->ofsx+ (1.0+safex)*panel->sizex) - if( pa->ofsy > panel->ofsy- safey*panel->sizey) - if( pa->ofsy+pa->sizey < panel->ofsy+ (1.0+safey)*panel->sizey) - pa->flag |= PNL_OVERLAP; - } - } - - pa= pa->next; - } -} - -static void test_add_new_tabs(ScrArea *sa) -{ - Panel *pa, *pasel=NULL, *palap=NULL; - /* search selected and overlapped panel */ - - pa= sa->panels.first; - while(pa) { - if(pa->active) { - if(pa->flag & PNL_SELECT) pasel= pa; - if(pa->flag & PNL_OVERLAP) palap= pa; - } - pa= pa->next; - } - - if(pasel && palap==NULL) { - - /* copy locations */ - pa= sa->panels.first; - while(pa) { - if(pa->paneltab==pasel) { - copy_panel_offset(pa, pasel); - } - pa= pa->next; - } - } - - if(pasel==NULL || palap==NULL) return; - - /* the overlapped panel becomes a tab */ - palap->paneltab= pasel; - - /* the selected panel gets coords of overlapped one */ - copy_panel_offset(pasel, palap); - - /* and its tabs */ - pa= sa->panels.first; - while(pa) { - if(pa->paneltab == pasel) { - copy_panel_offset(pa, palap); - } - pa= pa->next; - } - - /* but, the overlapped panel already can have tabs too! */ - pa= sa->panels.first; - while(pa) { - if(pa->paneltab == palap) { - pa->paneltab = pasel; - } - pa= pa->next; - } -} - -/* ------------ panel drag ---------------- */ - - -static void ui_drag_panel(uiBlock *block) -{ - Panel *panel= block->panel; - short align=0, first=1, ofsx, ofsy, dx=0, dy=0, dxo=0, dyo=0, mval[2], mvalo[2]; - - if(curarea->spacetype==SPACE_BUTS) { - SpaceButs *sbuts= curarea->spacedata.first; - align= sbuts->align; - } - - uiGetMouse(block->win, mvalo); - ofsx= block->panel->ofsx; - ofsy= block->panel->ofsy; - - panel->flag |= PNL_SELECT; - - while(TRUE) { - - if( !(get_mbut() & L_MOUSE) ) break; - - /* first clip for window, no dragging outside */ - getmouseco_areawin(mval); - if( mval[0]>0 && mval[0]<curarea->winx && mval[1]>0 && mval[1]<curarea->winy) { - uiGetMouse(mywinget(), mval); - dx= (mval[0]-mvalo[0]) & ~(PNL_GRID-1); - dy= (mval[1]-mvalo[1]) & ~(PNL_GRID-1); - } - - if(dx!=dxo || dy!=dyo || first || align) { - dxo= dx; dyo= dy; - first= 0; - - panel->ofsx = ofsx+dx; - panel->ofsy = ofsy+dy; - - check_panel_overlap(curarea, panel); - - if(align) uiAlignPanelStep(curarea, 0.2); - - /* warn: this re-allocs blocks! */ - scrarea_do_windraw(curarea); - ui_redraw_select_panel(curarea); - screen_swapbuffers(); - - /* so, we find the new block */ - block= curarea->uiblocks.first; - while(block) { - if(block->panel == panel) break; - block= block->next; - } - // temporal debug - if(block==NULL) { - printf("block null while panel drag, should not happen\n"); - } - - /* restore */ - Mat4CpyMat4(UIwinmat, block->winmat); - - /* idle for align */ - if(dx==dxo && dy==dyo) PIL_sleep_ms(30); - } - /* idle for this poor code */ - else PIL_sleep_ms(30); - } - - test_add_new_tabs(curarea); // also copies locations of tabs in dragged panel - - panel->flag &= ~PNL_SELECT; - check_panel_overlap(curarea, NULL); // clears - - if(align==0) addqueue(block->win, REDRAW, 1); - else ui_animate_panels(curarea); -} - - -static void ui_panel_untab(uiBlock *block) -{ - Panel *panel= block->panel, *pa, *panew=NULL; - short nr, mval[2], mvalo[2]; - - /* while hold mouse, check for movement, then untab */ - - uiGetMouse(block->win, mvalo); - while(TRUE) { - - if( !(get_mbut() & L_MOUSE) ) break; - uiGetMouse(mywinget(), mval); - - if( abs(mval[0]-mvalo[0]) + abs(mval[1]-mvalo[1]) > 6 ) { - /* find new parent panel */ - nr= 0; - pa= curarea->panels.first; - while(pa) { - if(pa->paneltab==panel) { - panew= pa; - nr++; - } - pa= pa->next; - } - - /* make old tabs point to panew */ - if(panew==NULL) printf("panel untab: shouldnt happen\n"); - panew->paneltab= NULL; - - pa= curarea->panels.first; - while(pa) { - if(pa->paneltab==panel) { - pa->paneltab= panew; - } - pa= pa->next; - } - - ui_drag_panel(block); - break; - - } - /* idle for this poor code */ - else PIL_sleep_ms(50); - - } - -} - -/* ------------ panel events ---------------- */ - - -static void panel_clicked_tabs(uiBlock *block, int mousex) -{ - Panel *pa, *tabsel=NULL, *panel= block->panel; - int nr= 1, a, width; - - /* count */ - pa= curarea->panels.first; - while(pa) { - if(pa!=panel) { - if(pa->paneltab==panel) nr++; - } - pa= pa->next; - } - - if(nr==1) return; - - /* find clicked tab, mouse in panel coords */ - a= 0; - width= (panel->sizex - 3- 2*PNL_ICON)/nr; - pa= curarea->panels.first; - while(pa) { - if(pa==panel || pa->paneltab==panel) { - if( (mousex > PNL_ICON+a*width) && (mousex < PNL_ICON+(a+1)*width) ) { - tabsel= pa; - } - a++; - } - pa= pa->next; - } - - if(tabsel) { - - if(tabsel == panel) { - ui_panel_untab(block); - } - else { - /* tabsel now becomes parent for all others */ - panel->paneltab= tabsel; - tabsel->paneltab= NULL; - - pa= curarea->panels.first; - while(pa) { - if(pa->paneltab == panel) pa->paneltab = tabsel; - pa= pa->next; - } - - addqueue(curarea->win, REDRAW, 1); - } - } - -} - - -/* this function is supposed to call general window drawing too */ -/* also it supposes a block has panel, and isnt a menu */ -static void ui_do_panel(uiBlock *block, uiEvent *uevent) -{ - Panel *pa; - int align= 0; - - if(curarea->spacetype==SPACE_BUTS) { - SpaceButs *sbuts= curarea->spacedata.first; - align= sbuts->align; - } - - /* mouse coordinates in panel space! */ - - if(uevent->event==LEFTMOUSE && block->panel->paneltab==NULL) { - int button= 0; - - /* check open/closed button */ - if(block->panel->flag & PNL_CLOSEDX) { - if(uevent->mval[1] >= block->maxy) button= 1; - } - else if(uevent->mval[0] <= block->minx+PNL_ICON+3) button= 1; - - if(button) { - if(block->panel->flag & PNL_CLOSED) block->panel->flag &= ~PNL_CLOSED; - else if(align==BUT_HORIZONTAL) block->panel->flag |= PNL_CLOSEDX; - else block->panel->flag |= PNL_CLOSEDY; - - for(pa= curarea->panels.first; pa; pa= pa->next) { - if(pa->paneltab==block->panel) { - if(block->panel->flag & PNL_CLOSED) pa->flag |= PNL_CLOSED; - else pa->flag &= ~PNL_CLOSED; - } - } - if(align==0) addqueue(block->win, REDRAW, 1); - else ui_animate_panels(curarea); - - } - else if(block->panel->flag & PNL_CLOSED) { - ui_drag_panel(block); - } - /* check if clicked in tabbed area */ - else if(uevent->mval[0] < block->maxx-PNL_ICON-3 && panel_has_tabs(block->panel)) { - panel_clicked_tabs(block, uevent->mval[0]); - } - else { - ui_drag_panel(block); - } - } -} - - |