Revert "Declaration on top"
[notion.git] / ioncore / framedpholder.c
blob2357b1550f942cecbba0aa2a16a1ca834f1e93c8
1 /*
2 * notion/ioncore/framedpholder.c
4 * Copyright (c) the Notion team 2013.
5 * Copyright (c) Tuomo Valkonen 2005-2009.
7 * See the included file LICENSE for details.
8 */
10 #include <libtu/objp.h>
11 #include <libtu/obj.h>
12 #include <libtu/minmax.h>
14 #include "frame.h"
15 #include "framedpholder.h"
16 #include "sizehint.h"
17 #include "resize.h"
20 /*{{{ Init/deinit */
23 bool framedpholder_init(WFramedPHolder *ph, WPHolder *cont,
24 const WFramedParam *param)
26 assert(cont!=NULL);
28 pholder_init(&(ph->ph));
30 ph->cont=cont;
31 ph->param=*param;
33 watch_init(&ph->frame_watch);
35 return TRUE;
39 WFramedPHolder *create_framedpholder(WPHolder *cont,
40 const WFramedParam *param)
42 CREATEOBJ_IMPL(WFramedPHolder, framedpholder, (p, cont, param));
46 void framedpholder_deinit(WFramedPHolder *ph)
48 if(ph->cont!=NULL){
49 destroy_obj((Obj*)ph->cont);
50 ph->cont=NULL;
53 pholder_deinit(&(ph->ph));
54 watch_reset(&ph->frame_watch);
58 /*}}}*/
61 /*{{{ Attach */
64 typedef struct{
65 WRegionAttachData *data;
66 WFramedParam *param;
67 WRegion *reg_ret;
68 } AP;
71 void frame_adjust_to_initial(WFrame *frame, const WFitParams *fp,
72 const WFramedParam *param, WRegion *reg)
74 WRectangle rqg, mg;
75 WSizeHints szh;
76 int iw, ih;
78 if(!(fp->mode&(REGION_FIT_BOUNDS|REGION_FIT_WHATEVER)))
79 return;
81 mplex_managed_geom((WMPlex*)frame, &mg);
83 /* Adjust geometry */
84 if(!param->inner_geom_gravity_set){
85 iw=REGION_GEOM(reg).w;
86 ih=REGION_GEOM(reg).h;
87 rqg.x=REGION_GEOM(frame).x;
88 rqg.y=REGION_GEOM(frame).y;
89 }else{
90 int bl=mg.x;
91 int br=REGION_GEOM(frame).w-(mg.x+mg.w);
92 int bt=mg.y;
93 int bb=REGION_GEOM(frame).h-(mg.y+mg.h);
95 iw=param->inner_geom.w;
96 ih=param->inner_geom.h;
98 rqg.x=(/*fp->g.x+*/param->inner_geom.x+
99 xgravity_deltax(param->gravity, bl, br));
100 rqg.y=(/*fp->g.y+*/param->inner_geom.y+
101 xgravity_deltay(param->gravity, bt, bb));
104 /* Some apps seem to request geometries inconsistent with their size hints,
105 * so correct for that here.
106 * Because WGroup(CW) sets no_constrain on the size hints, we have
107 * to set override_no_constrain to force the frame to have the size
108 * of the 'bottom' of the group.
110 region_size_hints(reg, &szh);
111 sizehints_correct(&szh, &iw, &ih, TRUE, TRUE);
112 rqg.w=maxof(1, iw+(REGION_GEOM(frame).w-mg.w));
113 rqg.h=maxof(1, ih+(REGION_GEOM(frame).h-mg.h));
115 if(!(fp->mode&REGION_FIT_WHATEVER))
116 rectangle_constrain(&rqg, &fp->g);
118 region_fit((WRegion*)frame, &rqg, REGION_FIT_EXACT);
122 WRegion *framed_handler(WWindow *par,
123 const WFitParams *fp,
124 void *ap_)
126 AP *ap=(AP*)ap_;
127 WMPlexAttachParams mp=MPLEXATTACHPARAMS_INIT;
128 WFramedParam *param=ap->param;
129 WFrame *frame;
130 WRegion *reg;
132 frame=create_frame(par, fp, param->mode, "Framed PHolder Frame");
134 if(frame==NULL)
135 return NULL;
137 if(fp->mode&(REGION_FIT_BOUNDS|REGION_FIT_WHATEVER))
138 mp.flags|=MPLEX_ATTACH_WHATEVER;
140 reg=mplex_do_attach(&frame->mplex, &mp, ap->data);
142 ap->reg_ret=reg;
144 if(reg==NULL){
145 destroy_obj((Obj*)frame);
146 return NULL;
149 frame_adjust_to_initial(frame, fp, param, reg);
151 return (WRegion*)frame;
155 WRegion *region_attach_framed(WRegion *reg, WFramedParam *param,
156 WRegionAttachFn *fn, void *fn_param,
157 WRegionAttachData *data)
159 WRegionAttachData data2;
160 AP ap;
162 data2.type=REGION_ATTACH_NEW;
163 data2.u.n.fn=framed_handler;
164 data2.u.n.param=&ap;
166 ap.data=data;
167 ap.param=param;
168 ap.reg_ret=NULL;
170 return fn(reg, fn_param, &data2);
174 WRegion *framedpholder_do_attach(WFramedPHolder *ph, int flags,
175 WRegionAttachData *data)
177 WRegionAttachData data2;
178 WFrame *frame;
179 AP ap;
181 frame=(WFrame*)ph->frame_watch.obj;
183 if(frame!=NULL){
184 WMPlexAttachParams mp=MPLEXATTACHPARAMS_INIT;
185 return mplex_do_attach(&frame->mplex, &mp, data);
188 if(ph->cont==NULL)
189 return FALSE;
191 data2.type=REGION_ATTACH_NEW;
192 data2.u.n.fn=framed_handler;
193 data2.u.n.param=&ap;
195 ap.data=data;
196 ap.param=&ph->param;
197 ap.reg_ret=NULL;
199 frame=(WFrame*)pholder_do_attach(ph->cont, flags, &data2);
201 if(frame!=NULL){
202 assert(OBJ_IS(frame, WFrame));
203 watch_setup(&ph->frame_watch, (Obj*)frame, NULL);
206 return (flags&PHOLDER_ATTACH_RETURN_CREATEROOT
207 ? (WRegion*)frame
208 : ap.reg_ret);
212 /*}}}*/
215 /*{{{ Other dynfuns */
218 bool framedpholder_do_goto(WFramedPHolder *ph)
220 WRegion *frame=(WRegion*)ph->frame_watch.obj;
222 if(frame!=NULL)
223 return region_goto((WRegion*)frame);
224 else if(ph->cont!=NULL)
225 return pholder_goto(ph->cont);
226 else
227 return FALSE;
231 WRegion *framedpholder_do_target(WFramedPHolder *ph)
233 WRegion *frame=(WRegion*)ph->frame_watch.obj;
235 return (frame!=NULL
236 ? frame
237 : (ph->cont!=NULL
238 ? pholder_target(ph->cont)
239 : NULL));
243 bool framedpholder_stale(WFramedPHolder *ph)
245 WRegion *frame=(WRegion*)ph->frame_watch.obj;
247 return (frame==NULL && (ph->cont==NULL || pholder_stale(ph->cont)));
251 /*}}}*/
254 /*{{{ Class information */
257 static DynFunTab framedpholder_dynfuntab[]={
258 {(DynFun*)pholder_do_attach,
259 (DynFun*)framedpholder_do_attach},
261 {(DynFun*)pholder_do_goto,
262 (DynFun*)framedpholder_do_goto},
264 {(DynFun*)pholder_do_target,
265 (DynFun*)framedpholder_do_target},
267 {(DynFun*)pholder_stale,
268 (DynFun*)framedpholder_stale},
270 END_DYNFUNTAB
273 IMPLCLASS(WFramedPHolder, WPHolder, framedpholder_deinit,
274 framedpholder_dynfuntab);
277 /*}}}*/