Also log the loglevel
[notion/jeffpc.git] / ioncore / framedpholder.c
blob60c6291ba6c894a58520427b742c2778993cdab1
1 /*
2 * ion/ioncore/framedpholder.c
4 * Copyright (c) Tuomo Valkonen 2005-2009.
6 * See the included file LICENSE for details.
7 */
9 #include <libtu/objp.h>
10 #include <libtu/obj.h>
11 #include <libtu/minmax.h>
13 #include "frame.h"
14 #include "framedpholder.h"
15 #include "sizehint.h"
16 #include "resize.h"
19 /*{{{ Init/deinit */
22 bool framedpholder_init(WFramedPHolder *ph, WPHolder *cont,
23 const WFramedParam *param)
25 assert(cont!=NULL);
27 pholder_init(&(ph->ph));
29 ph->cont=cont;
30 ph->param=*param;
32 watch_init(&ph->frame_watch);
34 return TRUE;
38 WFramedPHolder *create_framedpholder(WPHolder *cont,
39 const WFramedParam *param)
41 CREATEOBJ_IMPL(WFramedPHolder, framedpholder, (p, cont, param));
45 void framedpholder_deinit(WFramedPHolder *ph)
47 if(ph->cont!=NULL){
48 destroy_obj((Obj*)ph->cont);
49 ph->cont=NULL;
52 pholder_deinit(&(ph->ph));
53 watch_reset(&ph->frame_watch);
57 /*}}}*/
60 /*{{{ Attach */
63 typedef struct{
64 WRegionAttachData *data;
65 WFramedParam *param;
66 WRegion *reg_ret;
67 } AP;
70 void frame_adjust_to_initial(WFrame *frame, const WFitParams *fp,
71 const WFramedParam *param, WRegion *reg)
73 WRectangle rqg, mg;
74 WSizeHints szh;
75 int iw, ih;
77 if(!(fp->mode&(REGION_FIT_BOUNDS|REGION_FIT_WHATEVER)))
78 return;
80 mplex_managed_geom((WMPlex*)frame, &mg);
82 /* Adjust geometry */
83 if(!param->inner_geom_gravity_set){
84 iw=REGION_GEOM(reg).w;
85 ih=REGION_GEOM(reg).h;
86 rqg.x=REGION_GEOM(frame).x;
87 rqg.y=REGION_GEOM(frame).y;
88 }else{
89 int bl=mg.x;
90 int br=REGION_GEOM(frame).w-(mg.x+mg.w);
91 int bt=mg.y;
92 int bb=REGION_GEOM(frame).h-(mg.y+mg.h);
94 iw=param->inner_geom.w;
95 ih=param->inner_geom.h;
97 rqg.x=(/*fp->g.x+*/param->inner_geom.x+
98 xgravity_deltax(param->gravity, bl, br));
99 rqg.y=(/*fp->g.y+*/param->inner_geom.y+
100 xgravity_deltay(param->gravity, bt, bb));
103 /* Some apps seem to request geometries inconsistent with their size hints,
104 * so correct for that here.
105 * Because WGroup(CW) sets no_constrain on the size hints, we have
106 * to set override_no_constrain to force the frame to have the size
107 * of the 'bottom' of the group.
109 region_size_hints(reg, &szh);
110 sizehints_correct(&szh, &iw, &ih, TRUE, TRUE);
111 rqg.w=maxof(1, iw+(REGION_GEOM(frame).w-mg.w));
112 rqg.h=maxof(1, ih+(REGION_GEOM(frame).h-mg.h));
114 if(!(fp->mode&REGION_FIT_WHATEVER))
115 rectangle_constrain(&rqg, &fp->g);
117 region_fit((WRegion*)frame, &rqg, REGION_FIT_EXACT);
121 WRegion *framed_handler(WWindow *par,
122 const WFitParams *fp,
123 void *ap_)
125 AP *ap=(AP*)ap_;
126 WMPlexAttachParams mp=MPLEXATTACHPARAMS_INIT;
127 WFramedParam *param=ap->param;
128 WFrame *frame;
129 WRegion *reg;
131 frame=create_frame(par, fp, param->mode);
133 if(frame==NULL)
134 return NULL;
136 if(fp->mode&(REGION_FIT_BOUNDS|REGION_FIT_WHATEVER))
137 mp.flags|=MPLEX_ATTACH_WHATEVER;
139 reg=mplex_do_attach(&frame->mplex, &mp, ap->data);
141 ap->reg_ret=reg;
143 if(reg==NULL){
144 destroy_obj((Obj*)frame);
145 return NULL;
148 frame_adjust_to_initial(frame, fp, param, reg);
150 return (WRegion*)frame;
154 WRegion *region_attach_framed(WRegion *reg, WFramedParam *param,
155 WRegionAttachFn *fn, void *fn_param,
156 WRegionAttachData *data)
158 WRegionAttachData data2;
159 AP ap;
161 data2.type=REGION_ATTACH_NEW;
162 data2.u.n.fn=framed_handler;
163 data2.u.n.param=&ap;
165 ap.data=data;
166 ap.param=param;
167 ap.reg_ret=NULL;
169 return fn(reg, fn_param, &data2);
173 WRegion *framedpholder_do_attach(WFramedPHolder *ph, int flags,
174 WRegionAttachData *data)
176 WRegionAttachData data2;
177 WFrame *frame;
178 AP ap;
180 frame=(WFrame*)ph->frame_watch.obj;
182 if(frame!=NULL){
183 WMPlexAttachParams mp=MPLEXATTACHPARAMS_INIT;
184 return mplex_do_attach(&frame->mplex, &mp, data);
187 if(ph->cont==NULL)
188 return FALSE;
190 data2.type=REGION_ATTACH_NEW;
191 data2.u.n.fn=framed_handler;
192 data2.u.n.param=&ap;
194 ap.data=data;
195 ap.param=&ph->param;
196 ap.reg_ret=NULL;
198 frame=(WFrame*)pholder_do_attach(ph->cont, flags, &data2);
200 if(frame!=NULL){
201 assert(OBJ_IS(frame, WFrame));
202 watch_setup(&ph->frame_watch, (Obj*)frame, NULL);
205 return (flags&PHOLDER_ATTACH_RETURN_CREATEROOT
206 ? (WRegion*)frame
207 : ap.reg_ret);
211 /*}}}*/
214 /*{{{ Other dynfuns */
217 bool framedpholder_do_goto(WFramedPHolder *ph)
219 WRegion *frame=(WRegion*)ph->frame_watch.obj;
221 if(frame!=NULL)
222 return region_goto((WRegion*)frame);
223 else if(ph->cont!=NULL)
224 return pholder_goto(ph->cont);
225 else
226 return FALSE;
230 WRegion *framedpholder_do_target(WFramedPHolder *ph)
232 WRegion *frame=(WRegion*)ph->frame_watch.obj;
234 return (frame!=NULL
235 ? frame
236 : (ph->cont!=NULL
237 ? pholder_target(ph->cont)
238 : NULL));
242 bool framedpholder_stale(WFramedPHolder *ph)
244 WRegion *frame=(WRegion*)ph->frame_watch.obj;
246 return (frame==NULL && (ph->cont==NULL || pholder_stale(ph->cont)));
250 /*}}}*/
253 /*{{{ Class information */
256 static DynFunTab framedpholder_dynfuntab[]={
257 {(DynFun*)pholder_do_attach,
258 (DynFun*)framedpholder_do_attach},
260 {(DynFun*)pholder_do_goto,
261 (DynFun*)framedpholder_do_goto},
263 {(DynFun*)pholder_do_target,
264 (DynFun*)framedpholder_do_target},
266 {(DynFun*)pholder_stale,
267 (DynFun*)framedpholder_stale},
269 END_DYNFUNTAB
272 IMPLCLASS(WFramedPHolder, WPHolder, framedpholder_deinit,
273 framedpholder_dynfuntab);
276 /*}}}*/