2 * ion/mod_tiling/splitext.c
4 * Copyright (c) Tuomo Valkonen 1999-2007.
6 * See the included file LICENSE for details.
11 #include <libtu/objp.h>
12 #include <libtu/minmax.h>
13 #include <ioncore/common.h>
14 #include <ioncore/global.h>
15 #include <ioncore/rootwin.h>
16 #include <ioncore/xwindow.h>
17 #include <ioncore/window.h>
21 #include "splitfloat.h"
22 #include "panehandle.h"
25 #define GEOM(X) (((WSplit*)(X))->geom)
31 static void splitfloat_set_borderlines(WSplitFloat *split)
33 int dir=split->ssplit.dir;
35 split->tlpwin->bline=(dir==SPLIT_HORIZONTAL
37 : GR_BORDERLINE_BOTTOM);
39 split->brpwin->bline=(dir==SPLIT_HORIZONTAL
45 bool splitfloat_init(WSplitFloat *split, const WRectangle *geom,
49 WWindow *par=REGION_PARENT(ws);
54 fp.mode=REGION_FIT_EXACT;
55 split->tlpwin=create_panehandle(par, &fp);
56 if(split->tlpwin==NULL)
60 fp.mode=REGION_FIT_EXACT;
61 split->brpwin=create_panehandle(par, &fp);
62 if(split->brpwin==NULL){
63 destroy_obj((Obj*)split->tlpwin);
67 if(!splitsplit_init(&(split->ssplit), geom, dir)){
68 destroy_obj((Obj*)split->brpwin);
69 destroy_obj((Obj*)split->tlpwin);
73 split->tlpwin->splitfloat=split;
74 split->brpwin->splitfloat=split;
76 splitfloat_set_borderlines(split);
78 if(REGION_IS_MAPPED(ws)){
79 region_map((WRegion*)(split->tlpwin));
80 region_map((WRegion*)(split->brpwin));
87 WSplitFloat *create_splitfloat(const WRectangle *geom, WTiling *ws, int dir)
89 CREATEOBJ_IMPL(WSplitFloat, splitfloat, (p, geom, ws, dir));
93 void splitfloat_deinit(WSplitFloat *split)
95 if(split->tlpwin!=NULL){
96 WPaneHandle *tmp=split->tlpwin;
99 destroy_obj((Obj*)tmp);
102 if(split->brpwin!=NULL){
103 WPaneHandle *tmp=split->brpwin;
105 tmp->splitfloat=NULL;
106 destroy_obj((Obj*)tmp);
109 splitsplit_deinit(&(split->ssplit));
116 /*{{{ X window handling */
119 static void stack_stacking_reg(WRegion *reg,
120 Window *bottomret, Window *topret)
122 Window b=None, t=None;
125 region_stacking(reg, &b, &t);
134 static void stack_stacking_split(WSplit *split,
135 Window *bottomret, Window *topret)
137 Window b=None, t=None;
140 split_stacking(split, &b, &t);
149 static void splitfloat_stacking(WSplitFloat *split,
150 Window *bottomret, Window *topret)
155 if(split->ssplit.current!=SPLIT_CURRENT_TL){
156 stack_stacking_reg((WRegion*)split->tlpwin, bottomret, topret);
157 stack_stacking_split(split->ssplit.tl, bottomret, topret);
158 stack_stacking_reg((WRegion*)split->brpwin, bottomret, topret);
159 stack_stacking_split(split->ssplit.br, bottomret, topret);
161 stack_stacking_reg((WRegion*)split->brpwin, bottomret, topret);
162 stack_stacking_split(split->ssplit.br, bottomret, topret);
163 stack_stacking_reg((WRegion*)split->tlpwin, bottomret, topret);
164 stack_stacking_split(split->ssplit.tl, bottomret, topret);
169 static void stack_restack_reg(WRegion *reg, Window *other, int *mode)
171 Window b=None, t=None;
174 region_restack(reg, *other, *mode);
175 region_stacking(reg, &b, &t);
184 static void stack_restack_split(WSplit *split, Window *other, int *mode)
186 Window b=None, t=None;
189 split_restack(split, *other, *mode);
190 split_stacking(split, &b, &t);
200 static void splitfloat_restack(WSplitFloat *split, Window other, int mode)
202 if(split->ssplit.current!=SPLIT_CURRENT_TL){
203 stack_restack_reg((WRegion*)split->tlpwin, &other, &mode);
204 stack_restack_split(split->ssplit.tl, &other, &mode);
205 stack_restack_reg((WRegion*)split->brpwin, &other, &mode);
206 stack_restack_split(split->ssplit.br, &other, &mode);
208 stack_restack_reg((WRegion*)split->brpwin, &other, &mode);
209 stack_restack_split(split->ssplit.br, &other, &mode);
210 stack_restack_reg((WRegion*)split->tlpwin, &other, &mode);
211 stack_restack_split(split->ssplit.tl, &other, &mode);
216 static void splitfloat_map(WSplitFloat *split)
218 region_map((WRegion*)(split->tlpwin));
219 region_map((WRegion*)(split->brpwin));
220 splitinner_forall((WSplitInner*)split, split_map);
224 static void splitfloat_unmap(WSplitFloat *split)
226 region_unmap((WRegion*)(split->tlpwin));
227 region_unmap((WRegion*)(split->brpwin));
228 splitinner_forall((WSplitInner*)split, split_unmap);
232 static void reparentreg(WRegion *reg, WWindow *target)
234 WRectangle g=REGION_GEOM(reg);
235 region_reparent(reg, target, &g, REGION_FIT_EXACT);
239 static void splitfloat_reparent(WSplitFloat *split, WWindow *target)
241 if(split->ssplit.current!=SPLIT_CURRENT_TL){
242 reparentreg((WRegion*)split->tlpwin, target);
243 split_reparent(split->ssplit.tl, target);
244 reparentreg((WRegion*)split->brpwin, target);
245 split_reparent(split->ssplit.br, target);
247 reparentreg((WRegion*)split->brpwin, target);
248 split_reparent(split->ssplit.br, target);
249 reparentreg((WRegion*)split->tlpwin, target);
250 split_reparent(split->ssplit.tl, target);
261 #define TL_BORDER(SF) ((SF)->ssplit.dir==SPLIT_VERTICAL \
262 ? (SF)->tlpwin->bdw.bottom \
263 : (SF)->tlpwin->bdw.right)
265 #define BR_BORDER(SF) ((SF)->ssplit.dir==SPLIT_VERTICAL \
266 ? (SF)->brpwin->bdw.top \
267 : (SF)->brpwin->bdw.left)
270 void splitfloat_tl_pwin_to_cnt(WSplitFloat *split, WRectangle *g)
272 if(split->ssplit.dir==SPLIT_HORIZONTAL)
273 g->w=maxof(1, g->w-split->tlpwin->bdw.right);
275 g->h=maxof(1, g->h-split->tlpwin->bdw.bottom);
279 void splitfloat_br_pwin_to_cnt(WSplitFloat *split, WRectangle *g)
281 if(split->ssplit.dir==SPLIT_HORIZONTAL){
282 int delta=split->tlpwin->bdw.left;
283 g->w=maxof(1, g->w-delta);
286 int delta=split->tlpwin->bdw.top;
287 g->h=maxof(1, g->h-delta);
293 void splitfloat_tl_cnt_to_pwin(WSplitFloat *split, WRectangle *g)
295 if(split->ssplit.dir==SPLIT_HORIZONTAL)
296 g->w=maxof(1, g->w+split->tlpwin->bdw.right);
298 g->h=maxof(1, g->h+split->tlpwin->bdw.bottom);
302 void splitfloat_br_cnt_to_pwin(WSplitFloat *split, WRectangle *g)
304 if(split->ssplit.dir==SPLIT_HORIZONTAL){
305 int delta=split->tlpwin->bdw.left;
306 g->w=maxof(1, g->w+delta);
309 int delta=split->tlpwin->bdw.top;
310 g->h=maxof(1, g->h+delta);
316 static int infadd(int x, int y)
318 return ((x==INT_MAX || y==INT_MAX) ? INT_MAX : (x+y));
322 static int splitfloat_get_handle(WSplitFloat *split, int dir,
325 assert(other==split->ssplit.tl || other==split->ssplit.br);
327 if(dir!=split->ssplit.dir)
330 if(dir==SPLIT_VERTICAL){
331 if(other==split->ssplit.tl)
332 return split->tlpwin->bdw.right;
333 else if(other==split->ssplit.br)
334 return split->tlpwin->bdw.left;
336 if(other==split->ssplit.tl)
337 return split->tlpwin->bdw.bottom;
338 else if(other==split->ssplit.br)
339 return split->tlpwin->bdw.top;
346 static int splitfloat_get_max(WSplitFloat *split, int dir, WSplit *other)
348 return infadd((dir==SPLIT_VERTICAL ? other->max_h : other->max_w),
349 splitfloat_get_handle(split, dir, other));
353 static int splitfloat_get_min(WSplitFloat *split, int dir, WSplit *other)
355 return ((dir==SPLIT_VERTICAL ? other->min_h : other->min_w)
356 +splitfloat_get_handle(split, dir, other));
360 static void splitfloat_update_bounds(WSplitFloat *split, bool recursive)
362 WSplit *tl=split->ssplit.tl, *br=split->ssplit.br;
363 WSplit *node=(WSplit*)split;
364 int tl_max_w, br_max_w, tl_max_h, br_max_h;
365 int tl_min_w, br_min_w, tl_min_h, br_min_h;
368 split_update_bounds(tl, recursive);
369 split_update_bounds(br, recursive);
372 tl_max_w=splitfloat_get_max(split, SPLIT_HORIZONTAL, tl);
373 br_max_w=splitfloat_get_max(split, SPLIT_HORIZONTAL, br);
374 tl_max_h=splitfloat_get_max(split, SPLIT_VERTICAL, tl);
375 br_max_h=splitfloat_get_max(split, SPLIT_VERTICAL, br);
376 tl_min_w=splitfloat_get_min(split, SPLIT_HORIZONTAL, tl);
377 br_min_w=splitfloat_get_min(split, SPLIT_HORIZONTAL, br);
378 tl_min_h=splitfloat_get_min(split, SPLIT_VERTICAL, tl);
379 br_min_h=splitfloat_get_min(split, SPLIT_VERTICAL, br);
381 if(split->ssplit.dir==SPLIT_HORIZONTAL){
382 node->max_w=infadd(tl_max_w, br_max_w);
383 node->min_w=minof(tl_min_w, br_min_w);
385 node->min_h=maxof(tl_min_h, br_min_h);
386 node->max_h=maxof(minof(tl_max_h, br_max_h), node->min_h);
387 node->unused_h=minof(tl->unused_h, br->unused_h);
389 node->max_h=infadd(tl_max_h, br_max_h);
390 node->min_h=minof(tl_min_h, br_min_h);
392 node->min_w=maxof(tl_min_w, br_min_w);
393 node->max_w=maxof(minof(tl_max_w, br_max_w), node->min_w);
394 node->unused_w=minof(tl->unused_w, br->unused_w);
399 void splitfloat_update_handles(WSplitFloat *split, const WRectangle *tlg_,
400 const WRectangle *brg_)
402 WRectangle tlg=*tlg_, brg=*brg_;
404 if(split->ssplit.dir==SPLIT_HORIZONTAL){
405 tlg.w=split->tlpwin->bdw.right;
406 tlg.x=tlg_->x+tlg_->w-tlg.w;
407 brg.w=split->brpwin->bdw.left;
409 tlg.h=split->tlpwin->bdw.bottom;
410 tlg.y=tlg_->y+tlg_->h-tlg.h;
411 brg.h=split->brpwin->bdw.top;
414 region_fit((WRegion*)split->tlpwin, &tlg, REGION_FIT_EXACT);
415 region_fit((WRegion*)split->brpwin, &brg, REGION_FIT_EXACT);
419 static void bound(int *what, int min, int max)
428 static void adjust_sizes(int *tls_, int *brs_, int nsize,
429 int tlmin, int brmin, int tlmax, int brmax,
432 int tls=maxof(0, *tls_);
433 int brs=maxof(0, *brs_);
434 nsize=maxof(1, nsize);
437 tls=maxof(1, nsize-brs);
438 bound(&tls, tlmin, tlmax);
440 bound(&brs, brmin, brmax);
442 bound(&tls, tlmin, tlmax);
443 }else if(primn==PRIMN_BR){
444 brs=maxof(1, nsize-tls);
445 bound(&brs, brmin, brmax);
447 bound(&tls, tlmin, tlmax);
449 bound(&brs, brmin, brmax);
450 }else{ /* && PRIMN_ANY */
451 tls=tls*nsize/maxof(2, tls+brs);
452 bound(&tls, tlmin, tlmax);
454 bound(&brs, brmin, brmax);
456 bound(&tls, tlmin, tlmax);
464 static void adjust_size(int *sz, int dir, WSplitFloat *f, WSplit *s)
466 int mi=splitfloat_get_min(f, dir, s);
467 int ma=splitfloat_get_max(f, dir, s);
468 *sz=maxof(mi, minof(*sz, ma));
472 static void splitfloat_do_resize(WSplitFloat *split, const WRectangle *ng,
473 int hprimn, int vprimn, bool transpose)
475 WRectangle tlg=GEOM(split->ssplit.tl);
476 WRectangle brg=GEOM(split->ssplit.br);
477 WRectangle ntlg=*ng, nbrg=*ng;
478 WRectangle *og=&((WSplit*)split)->geom;
479 int dir=split->ssplit.dir;
482 splitfloat_tl_cnt_to_pwin(split, &tlg);
483 splitfloat_br_cnt_to_pwin(split, &brg);
486 if(dir==SPLIT_VERTICAL){
487 dir=SPLIT_HORIZONTAL;
488 split->tlpwin->bline=GR_BORDERLINE_RIGHT;
489 split->brpwin->bline=GR_BORDERLINE_LEFT;
492 split->tlpwin->bline=GR_BORDERLINE_BOTTOM;
493 split->brpwin->bline=GR_BORDERLINE_TOP;
495 split->ssplit.dir=dir;
498 if(dir==SPLIT_VERTICAL){
499 if(ng->h<=tlg.h+brg.h){
501 ntlg.h=minof(tlg.w, ng->h*2/3);
502 nbrg.h=minof(brg.w, ng->h*2/3);
503 adjust_size(&ntlg.h, dir, split, split->ssplit.tl);
504 adjust_size(&nbrg.h, dir, split, split->ssplit.br);
505 adjust=(ng->h>ntlg.h+nbrg.h);
507 ntlg.h=minof(ng->h, tlg.h);
508 nbrg.h=minof(ng->h, brg.h);
517 adjust_sizes(&ntlg.h, &nbrg.h, ng->h,
518 splitfloat_get_min(split, dir, split->ssplit.tl),
519 splitfloat_get_min(split, dir, split->ssplit.br),
520 splitfloat_get_max(split, dir, split->ssplit.tl),
521 splitfloat_get_max(split, dir, split->ssplit.br),
525 nbrg.y=ng->y+ng->h-nbrg.h;
527 if(ng->w<=tlg.w+brg.w){
529 ntlg.w=minof(tlg.h, ng->w*2/3);
530 nbrg.w=minof(brg.h, ng->w*2/3);
531 adjust_size(&ntlg.w, dir, split, split->ssplit.tl);
532 adjust_size(&nbrg.w, dir, split, split->ssplit.br);
533 adjust=(ng->w>ntlg.w+nbrg.w);
535 ntlg.w=minof(ng->w, tlg.w);
536 nbrg.w=minof(ng->w, brg.w);
545 adjust_sizes(&ntlg.w, &nbrg.w, ng->w,
546 splitfloat_get_min(split, dir, split->ssplit.tl),
547 splitfloat_get_min(split, dir, split->ssplit.br),
548 splitfloat_get_max(split, dir, split->ssplit.tl),
549 splitfloat_get_max(split, dir, split->ssplit.br),
553 nbrg.x=ng->x+ng->w-nbrg.w;
558 splitfloat_update_handles(split, &ntlg, &nbrg);
560 splitfloat_tl_pwin_to_cnt(split, &ntlg);
561 split_do_resize(split->ssplit.tl, &ntlg, hprimn, vprimn, transpose);
562 splitfloat_br_pwin_to_cnt(split, &nbrg);
563 split_do_resize(split->ssplit.br, &nbrg, hprimn, vprimn, transpose);
567 static void calc_amount(int *amount, int *oamount,
568 int rs, WSplitSplit *p, int omax,
569 const WRectangle *ng, const WRectangle *og)
574 if(p->dir==SPLIT_VERTICAL)
575 *amount=maxof(0, minof(rs, GEOM(p).h-ng->h));
577 *amount=maxof(0, minof(rs, GEOM(p).w-ng->w));
579 if(p->dir==SPLIT_VERTICAL){
580 int overlap=maxof(0, og->h-(GEOM(p).h-ng->h));
581 *amount=-minof(-rs, overlap);
582 *oamount=maxof(0, minof(*amount-rs, omax-og->h));
585 int overlap=maxof(0, og->w-(GEOM(p).w-ng->w));
586 *amount=-minof(-rs, overlap);
587 *oamount=maxof(0, minof(*amount-rs, omax-og->w));
594 static void splitfloat_do_rqsize(WSplitFloat *split, WSplit *node,
595 RootwardAmount *ha, RootwardAmount *va,
596 WRectangle *rg, bool tryonly)
598 int hprimn=PRIMN_ANY, vprimn=PRIMN_ANY;
599 WRectangle pg, og, ng, nog, nng;
602 int amount=0, oamount=0, omax;
604 WSplitSplit *p=&(split->ssplit);
606 assert(!ha->any || ha->tl==0);
607 assert(!va->any || va->tl==0);
608 assert(p->tl==node || p->br==node);
621 if(thisnode==PRIMN_TL){
622 splitfloat_tl_cnt_to_pwin(split, &ng);
623 splitfloat_br_cnt_to_pwin(split, &og);
625 splitfloat_br_cnt_to_pwin(split, &ng);
626 splitfloat_tl_cnt_to_pwin(split, &og);
629 ca=(p->dir==SPLIT_VERTICAL ? va : ha);
631 omax=splitfloat_get_max(split, p->dir, other);
633 if(thisnode==PRIMN_TL || ca->any){
634 calc_amount(&amount, &oamount, ca->br, p, omax, &ng, &og);
636 }else/*if(thisnode==PRIMN_BR)*/{
637 calc_amount(&amount, &oamount, ca->tl, p, omax, &ng, &og);
641 if(((WSplit*)p)->parent==NULL /*||
642 (ha->tl==0 && ha->br==0 && va->tl==0 && va->br==0)*/){
643 pg=((WSplit*)p)->geom;
645 splitinner_do_rqsize(((WSplit*)p)->parent, (WSplit*)p, ha, va,
649 assert(pg.w>=0 && pg.h>=0);
654 if(p->dir==SPLIT_VERTICAL){
655 nog.h=minof(pg.h, maxof(0, og.h+oamount));
656 nng.h=minof(pg.h, maxof(0, ng.h+amount+pg.h-GEOM(p).h));
657 if(thisnode==PRIMN_TL)
658 nog.y=pg.y+pg.h-nog.h;
660 nng.y=pg.y+pg.h-nng.h;
663 nog.w=minof(pg.w, maxof(0, og.w+oamount));
664 nng.w=minof(pg.w, maxof(0, ng.w+amount+pg.w-GEOM(p).w));
665 if(thisnode==PRIMN_TL)
666 nog.x=pg.x+pg.w-nog.w;
668 nng.x=pg.x+pg.w-nng.w;
675 if(thisnode==PRIMN_TL){
676 splitfloat_update_handles(split, &nng, &nog);
677 splitfloat_br_pwin_to_cnt(split, &nog);
679 splitfloat_update_handles(split, &nog, &nng);
680 splitfloat_tl_pwin_to_cnt(split, &nog);
683 /* Entä jos 'other' on stdisp? */
684 split_do_resize(other, &nog, hprimn, vprimn, FALSE);
688 if(thisnode==PRIMN_TL)
689 splitfloat_tl_pwin_to_cnt(split, rg);
691 splitfloat_br_pwin_to_cnt(split, rg);
695 void splitfloat_flip(WSplitFloat *split)
699 splitsplit_flip_default(&split->ssplit);
701 tlg=split->ssplit.tl->geom;
702 brg=split->ssplit.br->geom;
704 splitfloat_tl_cnt_to_pwin(split, &tlg);
705 splitfloat_br_cnt_to_pwin(split, &brg);
706 splitfloat_update_handles(split, &tlg, &brg);
713 /*{{{ Loading code */
718 static void adjust_tls_brs(int *tls, int *brs, int total)
726 *tls=total*(*tls)/(*tls+*brs);
730 *tls=minof(maxof(MINS, *tls), total);
731 *brs=minof(maxof(MINS, *brs), total);
735 static void calc_tlg_brg(const WRectangle *geom, int tls, int brs, int dir,
736 WRectangle *tlg, WRectangle *brg)
741 if(dir==SPLIT_HORIZONTAL){
742 adjust_tls_brs(&tls, &brs, geom->w);
745 brg->x=geom->x+geom->w-brs;
747 adjust_tls_brs(&tls, &brs, geom->h);
750 brg->y=geom->y+geom->h-brs;
755 WSplit *load_splitfloat(WTiling *ws, const WRectangle *geom, ExtlTab tab)
757 WSplit *tl=NULL, *br=NULL;
765 set+=(extl_table_gets_i(tab, "tls", &tls)==TRUE);
766 set+=(extl_table_gets_i(tab, "brs", &brs)==TRUE);
767 set+=(extl_table_gets_s(tab, "dir", &dir_str)==TRUE);
772 if(strcmp(dir_str, "vertical")==0){
774 }else if(strcmp(dir_str, "horizontal")==0){
775 dir=SPLIT_HORIZONTAL;
777 warn(TR("Invalid direction."));
783 split=create_splitfloat(geom, ws, dir);
787 if(!extl_table_is_bool_set(tab, "tls_brs_incl_handles")){
788 if(split->ssplit.dir==SPLIT_HORIZONTAL){
789 tls+=split->tlpwin->bdw.right;
790 brs+=split->brpwin->bdw.left;
792 tls+=split->tlpwin->bdw.bottom;
793 brs+=split->brpwin->bdw.top;
797 calc_tlg_brg(geom, tls, brs, dir, &tlg, &brg);
799 splitfloat_update_handles(split, &tlg, &brg);
801 if(extl_table_gets_t(tab, "tl", &subtab)){
803 splitfloat_tl_pwin_to_cnt(split, &g);
804 tl=tiling_load_node(ws, &g, subtab);
805 extl_unref_table(subtab);
808 if(extl_table_gets_t(tab, "br", &subtab)){
814 splitfloat_br_pwin_to_cnt(split, &g);
816 br=tiling_load_node(ws, &g, subtab);
817 extl_unref_table(subtab);
820 if(tl==NULL || br==NULL){
821 destroy_obj((Obj*)split);
823 split_do_resize(tl, geom, PRIMN_ANY, PRIMN_ANY, FALSE);
827 split_do_resize(br, geom, PRIMN_ANY, PRIMN_ANY, FALSE);
833 tl->parent=(WSplitInner*)split;
834 br->parent=(WSplitInner*)split;
839 return (WSplit*)split;
849 WSplitRegion *splittree_split_floating(WSplit *node, int dir, int primn,
850 int nmins, WRegionSimpleCreateFn *fn,
857 WRectangle gn, go, gnc, goc;
863 if(primn!=PRIMN_TL && primn!=PRIMN_BR)
866 split_update_bounds(split_find_root(node), TRUE);
868 sf=create_splitfloat(&node->geom, ws, dir);
873 omins=(dir==SPLIT_VERTICAL ? node->min_h : node->min_w);
874 s=split_size(node, dir);
884 mins=maxof(omins+bo, nmins+bn);
886 /* Potentially resize old node. */
888 splittree_begin_resize();
891 WRectangle ng=node->geom, rg;
892 if(dir==SPLIT_VERTICAL)
897 split_do_rqgeom_(node, &ng, TRUE, TRUE, &rg, TRUE);
898 rs=(dir==SPLIT_VERTICAL ? rg.h : rg.w);
900 warn(TR("Unable to split: not enough free space."));
901 destroy_obj((Obj*)sf);
904 split_do_rqgeom_(node, &ng, TRUE, TRUE, &rg, FALSE);
905 s=split_size(node, dir);
907 splittree_scan_stdisp_rootward(node);
910 /* Calculate geometries. */
912 sn=maxof(nmins+bn, s/2);
913 so=maxof(omins+bo, s-s/2);
915 ((WSplit*)sf)->geom=node->geom;
918 calc_tlg_brg(&(node->geom), sn, so, dir, &gn, &go);
919 splitfloat_update_handles(sf, &gn, &go);
920 gnc=gn; splitfloat_tl_pwin_to_cnt(sf, &gnc);
921 goc=go; splitfloat_br_pwin_to_cnt(sf, &goc);
923 calc_tlg_brg(&(node->geom), so, sn, dir, &go, &gn);
924 splitfloat_update_handles(sf, &go, &gn);
925 goc=go; splitfloat_tl_pwin_to_cnt(sf, &goc);
926 gnc=gn; splitfloat_br_pwin_to_cnt(sf, &gnc);
929 /* Create the region. */
931 fp.mode=REGION_FIT_EXACT;
934 nreg=fn(REGION_PARENT(ws), &fp);
937 destroy_obj((Obj*)sf);
941 nnode=create_splitregion(&(fp.g), nreg);
943 destroy_obj((Obj*)nreg);
944 destroy_obj((Obj*)sf);
948 /* Now that everything's ok, resize and move original node. */
950 split_do_resize(node, &goc,
951 (dir==SPLIT_HORIZONTAL ? primn : PRIMN_ANY),
952 (dir==SPLIT_VERTICAL ? primn : PRIMN_ANY),
955 /* Set up split structure. */
960 splitinner_replace(psplit, node, (WSplit*)sf);
962 splittree_changeroot(node, (WSplit*)sf);
964 node->parent=(WSplitInner*)sf;
965 ((WSplit*)nnode)->parent=(WSplitInner*)sf;
969 sf->ssplit.br=(WSplit*)nnode;
971 sf->ssplit.tl=(WSplit*)nnode;
975 /*splittree_end_resize();*/
987 static DynFunTab splitfloat_dynfuntab[]={
988 {split_update_bounds, splitfloat_update_bounds},
989 {split_do_resize, splitfloat_do_resize},
990 {splitinner_do_rqsize, splitfloat_do_rqsize},
991 {split_stacking, splitfloat_stacking},
992 {split_restack, splitfloat_restack},
993 {split_reparent, splitfloat_reparent},
994 {split_map, splitfloat_map},
995 {split_unmap, splitfloat_unmap},
996 {splitsplit_flip, splitfloat_flip},
1002 IMPLCLASS(WSplitFloat, WSplitSplit, splitfloat_deinit, splitfloat_dynfuntab);