2 * ion/ioncore/float-placement.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
13 #include "float-placement.h"
16 WFloatPlacement ioncore_placement_method
=PLACEMENT_LRUD
;
17 int ioncore_placement_padding
=1;
20 static void random_placement(WRectangle box
, WRectangle
*g
)
24 g
->x
=box
.x
+(box
.w
<=0 ? 0 : rand()%box
.w
);
25 g
->y
=box
.y
+(box
.h
<=0 ? 0 : rand()%box
.h
);
29 static void ggeom(WRegion
*reg
, WRectangle
*geom
)
31 *geom
=REGION_GEOM(reg
);
35 static bool st_filt(WStacking
*st
, void *lvl
)
37 uint level
=*(uint
*)lvl
;
39 return (st
->reg
!=NULL
&&
40 REGION_IS_MAPPED(st
->reg
) &&
45 #define FOR_ALL_STACKING_NODES(VAR, WS, LVL, TMP) \
46 for(stacking_iter_init(&(TMP), group_get_stacking(ws), \
48 VAR=stacking_iter_nodes(&(TMP)); \
50 VAR=stacking_iter_nodes(&(TMP)))
53 #define IGNORE_ST(ST, WS) ((ST)->reg==NULL || (ST)==(WS)->bottom)
56 static WRegion
* is_occupied(WGroup
*ws
, uint level
, const WRectangle
*r
)
62 FOR_ALL_STACKING_NODES(st
, ws
, level
, tmp
){
80 static int next_least_x(WGroup
*ws
, uint level
, int x
)
83 int retx
=REGION_GEOM(ws
).x
+REGION_GEOM(ws
).w
;
87 FOR_ALL_STACKING_NODES(st
, ws
, level
, tmp
){
90 if(p
.x
+p
.w
>x
&& p
.x
+p
.w
<retx
)
99 static int next_least_y(WGroup
*ws
, uint level
, int y
)
102 int rety
=REGION_GEOM(ws
).y
+REGION_GEOM(ws
).h
;
103 WStackingIterTmp tmp
;
106 FOR_ALL_STACKING_NODES(st
, ws
, level
, tmp
){
109 if(p
.y
+p
.h
>y
&& p
.y
+p
.h
<rety
)
117 static bool tiling_placement(WGroup
*ws
, uint level
, WRectangle
*g
)
127 maxx
=REGION_GEOM(ws
).x
+REGION_GEOM(ws
).w
;
128 maxy
=REGION_GEOM(ws
).y
+REGION_GEOM(ws
).h
;
130 if(ioncore_placement_method
==PLACEMENT_UDLR
){
132 p
=is_occupied(ws
, level
, &r
);
133 while(p
!=NULL
&& r
.y
+r
.h
<maxy
){
135 r
.y
=r2
.y
+r2
.h
+ioncore_placement_padding
;
136 p
=is_occupied(ws
, level
, &r
);
138 if(r
.y
+r
.h
<maxy
&& r
.x
+r
.w
<maxx
){
143 r
.x
=next_least_x(ws
, level
, r
.x
)+ioncore_placement_padding
;
149 p
=is_occupied(ws
, level
, &r
);
150 while(p
!=NULL
&& r
.x
+r
.w
<maxx
){
152 r
.x
=r2
.x
+r2
.w
+ioncore_placement_padding
;
153 p
=is_occupied(ws
, level
, &r
);
155 if(r
.y
+r
.h
<maxy
&& r
.x
+r
.w
<maxx
){
160 r
.y
=next_least_y(ws
, level
, r
.y
)+ioncore_placement_padding
;
171 void group_calc_placement(WGroup
*ws
, uint level
, WRectangle
*geom
)
173 if(ioncore_placement_method
!=PLACEMENT_RANDOM
){
174 if(tiling_placement(ws
, level
, geom
))
177 random_placement(REGION_GEOM(ws
), geom
);