diff -rN -ubp old-ion-3plus/ioncore/frame.c new-ion-3plus/ioncore/frame.c --- old-ion-3plus/ioncore/frame.c 2009-03-15 11:57:04.000000000 +0100 +++ new-ion-3plus/ioncore/frame.c 2009-03-15 11:57:04.000000000 +0100 @@ -100,7 +100,8 @@ bool frame_init(WFrame *frame, WWindow * frame->brush=NULL; frame->bar_brush=NULL; frame->mode=mode; - frame->tab_min_w=0; + frame->float_tab_min_w=0; + frame->propor_tab_min_w=0; frame->bar_max_width_q=1.0; gr_stylespec_init(&frame->baseattr); @@ -282,29 +283,61 @@ int frame_nth_tab_x(WFrame *frame, int n } +void frame_get_max_width_and_elastic(WFrame * frame,int bar_w,int *maxw,int *elastic,int *minw);//FIXME + static int frame_nth_tab_w_iw(WFrame *frame, int n, bool inner) { WRectangle bg; GrBorderWidths bdw=GR_BORDER_WIDTHS_INIT; int m=FRAME_MCOUNT(frame); + int maxw,elastic,textw,minw; uint w; + WRegion *sub; + const char * p; - frame_bar_geom(frame, &bg); +//fprintf(stderr,"HERE\n"); - if(m==0) - m=1; + frame_bar_geom(frame, &bg); if(frame->bar_brush!=NULL) grbrush_get_border_widths(frame->bar_brush, &bdw); + if(m==0){ + m=1; + w=bg.w-bdw.left-bdw.right; + }else{ + frame_get_max_width_and_elastic(frame, bg.w, &maxw, &elastic, &minw); + if ((maxw > 0) && (maxw <= frame->propor_tab_min_w)) { /* Remove borders */ w=bg.w-bdw.left-bdw.right-(bdw.tb_ileft+bdw.tb_iright+bdw.spacing)*(m-1); - +//fprintf(stderr,"HEREmin maxw:%i minw:%i totalw:%i pad:%i w:%i (????)\n",maxw,minw,bg.w,elastic,w); if(w<=0) return 0; - /* Get n:th tab's portion of free area */ w=(((n+1)*w)/m-(n*w)/m); + }else{ + + /* Get n:th tab's portion of elastic area */ + elastic=(((n+1)*elastic)/m-(n*elastic)/m); + + sub = mplex_mx_nth((WMPlex*)frame, n); + p=region_displayname(sub); + if(p==NULL) + textw=0; + else + textw=grbrush_get_text_width(frame->bar_brush, + p, strlen(p)); + if (textwpropor_tab_min_w) + textw=frame->propor_tab_min_w; + + if (maxw>0 && (textw>maxw)) + textw=maxw; + w=elastic+textw; +//fprintf(stderr,"HEREsub %p maxw:%i minw:%i totalw:%i pad:%i w:%i (%s)\n",(void *)sub,maxw,minw,bg.w,elastic,w,p); + } + } /* Add n:th tab's borders back */ if(!inner){ @@ -312,6 +345,7 @@ static int frame_nth_tab_w_iw(WFrame *fr w+=(n==m-1 ? bdw.right : bdw.tb_iright+bdw.spacing); } +//fprintf(stderr,"THERE\n"); return w; } diff -rN -ubp old-ion-3plus/ioncore/frame-draw.c new-ion-3plus/ioncore/frame-draw.c --- old-ion-3plus/ioncore/frame-draw.c 2009-03-15 11:57:04.000000000 +0100 +++ new-ion-3plus/ioncore/frame-draw.c 2009-03-15 11:57:04.000000000 +0100 @@ -225,10 +225,11 @@ void frame_clear_shape(WFrame *frame) #define CF_TAB_MAX_TEXT_X_OFF 10 +void frame_get_max_width_and_elastic(WFrame * frame,int bar_w,int *maxw,int *elastic, int *minw);//FIXME static void frame_shaped_recalc_bar_size(WFrame *frame, bool complete) { - int bar_w=0, textw=0, tmaxw=frame->tab_min_w, tmp=0; + int bar_w=0, textw, w, tmaxw, tminw, tmp=0; WLListIterTmp itmp; WRegion *sub; const char *p; @@ -241,43 +242,41 @@ static void frame_shaped_recalc_bar_size return; m=FRAME_MCOUNT(frame); + bar_w=frame->bar_max_width_q*REGION_GEOM(frame).w; if(m>0){ - grbrush_get_border_widths(frame->bar_brush, &bdw); - bdtotal=((m-1)*(bdw.tb_ileft+bdw.tb_iright+bdw.spacing) - +bdw.right+bdw.left); + + frame_get_max_width_and_elastic(frame, bar_w, &tmaxw, &tmp, &tminw); +//fprintf(stderr," * WID total:%i maxw:%i minw:%i elastic:%i m:%i\n",bar_w,tmaxw,tminw,tmp,m); + if ((tmaxw < 0) && (tminw == frame->float_tab_min_w)) { + /* No label truncation needed, good. See how much can be padded. */ + w=bar_w-tmp; FRAME_MX_FOR_ALL(sub, frame, itmp){ p=region_displayname(sub); if(p==NULL) continue; - textw=grbrush_get_text_width(frame->bar_brush, - p, strlen(p)); - if(textw>tmaxw) - tmaxw=textw; + textw=2*CF_TAB_MAX_TEXT_X_OFF+ + grbrush_get_text_width(frame->bar_brush, + p, strlen(p))- + frame->float_tab_min_w; +//fprintf(stderr," * WID addtextw:%i\n",textw); + if (textw>=2*CF_TAB_MAX_TEXT_X_OFF) + w+=2*CF_TAB_MAX_TEXT_X_OFF; + else if (textw >=0) + w+=textw; } + if (bar_w>w)/*Padded to much*/ + bar_w=w; - bar_w=frame->bar_max_width_q*REGION_GEOM(frame).w; - if(bar_wtab_min_w && - REGION_GEOM(frame).w>frame->tab_min_w) - bar_w=frame->tab_min_w; - - tmp=bar_w-bdtotal-m*tmaxw; - - if(tmp>0){ - /* No label truncation needed, good. See how much can be padded. */ - tmp/=m*2; - if(tmp>CF_TAB_MAX_TEXT_X_OFF) - tmp=CF_TAB_MAX_TEXT_X_OFF; - bar_w=(tmaxw+tmp*2)*m+bdtotal; - }else{ + } else { /* Some labels must be truncated */ } + }else{ - bar_w=frame->tab_min_w; - if(bar_w>frame->bar_max_width_q*REGION_GEOM(frame).w) - bar_w=frame->bar_max_width_q*REGION_GEOM(frame).w; + if(bar_w>frame->float_tab_min_w) + bar_w=frame->float_tab_min_w; } if(complete || frame->bar_w!=bar_w){ @@ -302,9 +301,133 @@ static int init_title(WFrame *frame, int } +/* Proportional tabs algorithm: + * Sort tabs by text sizes. + * From smallest to largest do: + * Compare current tab width with remaining width (incl. current) + divided by no. of remaining tabs (incl. current). + * If larger or equal, then set maximum width to the number computed + above and set elastic space to zero (resp. to remain after division). + (Return.) + * If smaller, subctract current width from remaining width and + subtract one from no. of remaining tabs. If this is the last + tab, then set additional padding to remaining width divided + by total number of tabs. + + Do not use w for shaped frames. +*/ +void frame_get_max_width_and_elastic(WFrame * frame,int bar_w,int *maxw,int *elastic, int *minw){ + /* Dummy implementation O(n^2), instead of O(n*log(n)) */ + int textw=0,tmp,tmaxw,tminw=frame->propor_tab_min_w; + WLListIterTmp itmp; + WRegion *sub; + const char *p; + GrBorderWidths bdw; + //char *title; + uint bdtotal,curw,nextw; + int i, m, n; + + m=FRAME_MCOUNT(frame); + *minw=0; + +// if(frame->bar_brush==NULL) +// *elastic=0; +// *maxw=-1; +//fprintf(stderr,"ZERR\n"); +// return; + if(m>0){ + grbrush_get_border_widths(frame->bar_brush, &bdw); + bdtotal=((m-1)*(bdw.tb_ileft+bdw.tb_iright+bdw.spacing) + +bdw.right+bdw.left); + tmp = bar_w - bdtotal; +//fprintf(stderr,"TMPST:%i barw:%i bdt:%i\n",tmp,bar_w,bdtotal); + + curw=0; + n=m; + + while (n>0) { + nextw=(uint)-1;/*FIXME: MAXINT*/ + if ((signed)curw*n >= tmp) { + /*Remainig tabs are too large => equal width.*/ + *maxw=tmp/n; + *elastic=tmp-(*maxw)*n; +//fprintf(stderr,"TRUNC maxw:%i elastic:%i tmp:%i n:%i\n",*maxw,*elastic,tmp,n); + return; + } + FRAME_MX_FOR_ALL(sub, frame, itmp){ + p=region_displayname(sub); + if(p==NULL) + continue; + + textw=grbrush_get_text_width(frame->bar_brush, + p, strlen(p)); + if (textwcurw){ + if ((unsigned)textwbar_brush, + p, strlen(p)); + if (textwcurw){ + if ((unsigned)textw(unsigned)frame->float_tab_min_w) + nextw=frame->float_tab_min_w; +//fprintf(stderr,"TMP --- tmp:%i n:%i curw:%i nextw:%i min:%i\n",tmp,n,curw,nextw,*minw); + if (n*(nextw-curw)<(unsigned)tmp) { + /*we can extend small tabs to 'nextw'*/ + *minw=nextw; + tmp-=n*(nextw-curw); +//fprintf(stderr,"TMPSUBGO tmp:%i n:%i curw:%i nextw:%i min:%i\n",tmp,n,curw,nextw,*minw); + } else { + /*we can extend small tabs only to 'curw+tmp/n'*/ + *minw+=tmp/n; + tmp-=(*minw-curw)*n; +//fprintf(stderr,"TMPSUBBRK tmp:%i n:%i curw:%i nextw:%i min:%i\n",tmp,n,curw,nextw,*minw); + break; + } + if (nextw==(unsigned)frame->float_tab_min_w) + break; + curw=nextw; + } + +//fprintf(stderr,"TMP elastic:%i min:%i\n",tmp,*minw); + *elastic=tmp; + } else { + *elastic=0; + } + *maxw=-1; +} + void frame_recalc_bar(WFrame *frame, bool complete) { - int textw, i; + int textw, i, maxw, padding; WLListIterTmp tmp; WRegion *sub; char *title; @@ -357,7 +480,8 @@ void frame_draw_bar(const WFrame *frame, grbrush_init_attr(frame->bar_brush, &frame->baseattr); grbrush_draw_textboxes(frame->bar_brush, &geom, frame->titles_n, - frame->titles, complete); + //frame->titles, complete); + frame->titles, TRUE); grbrush_end(frame->bar_brush); } @@ -427,14 +551,17 @@ void frame_brushes_updated(WFrame *frame frame->bar_h=bdw.top+bdw.bottom+fnte.max_height; } + //FIXME + frame->propor_tab_min_w=30; + /* shaped mode stuff */ - frame->tab_min_w=100; + frame->float_tab_min_w=100; frame->bar_max_width_q=0.95; if(grbrush_get_extra(frame->brush, "floatframe_tab_min_w", - 'i', &(frame->tab_min_w))){ - if(frame->tab_min_w<=0) - frame->tab_min_w=1; + 'i', &(frame->float_tab_min_w))){ + if(frame->float_tab_min_w<=0) + frame->float_tab_min_w=1; } if(grbrush_get_extra(frame->brush, "floatframe_bar_max_w_q", diff -rN -ubp old-ion-3plus/ioncore/frame.h new-ion-3plus/ioncore/frame.h --- old-ion-3plus/ioncore/frame.h 2009-03-15 11:57:04.000000000 +0100 +++ new-ion-3plus/ioncore/frame.h 2009-03-15 11:57:04.000000000 +0100 @@ -76,7 +76,8 @@ DECLCLASS(WFrame){ WFrameBarMode barmode; int bar_w, bar_h; double bar_max_width_q; - int tab_min_w; + int float_tab_min_w; + int propor_tab_min_w; };