]> git.decadent.org.uk Git - ion3.git/blob - ioncore/framedpholder.c
[svn-inject] Installing original source of ion3
[ion3.git] / ioncore / framedpholder.c
1 /*
2  * ion/ioncore/framedpholder.c
3  *
4  * Copyright (c) Tuomo Valkonen 2005-2006. 
5  *
6  * Ion is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <libtu/objp.h>
13 #include <libtu/obj.h>
14 #include <libtu/minmax.h>
15
16 #include "frame.h"
17 #include "framedpholder.h"
18 #include "sizehint.h"
19
20
21 /*{{{ Init/deinit */
22
23
24 bool framedpholder_init(WFramedPHolder *ph, WPHolder *cont,
25                         const WFramedParam *param)
26 {
27     assert(cont!=NULL);
28     
29     pholder_init(&(ph->ph));
30
31     ph->cont=cont;
32     ph->param=*param;
33     
34     return TRUE;
35 }
36  
37
38 WFramedPHolder *create_framedpholder(WPHolder *cont,
39                                      const WFramedParam *param)
40 {
41     CREATEOBJ_IMPL(WFramedPHolder, framedpholder, (p, cont, param));
42 }
43
44
45 void framedpholder_deinit(WFramedPHolder *ph)
46 {
47     if(ph->cont!=NULL){
48         destroy_obj((Obj*)ph->cont);
49         ph->cont=NULL;
50     }
51     
52     pholder_deinit(&(ph->ph));
53 }
54
55
56 /*}}}*/
57
58
59 /*{{{ Attach */
60
61
62 typedef struct{
63     WRegionAttachData *data;
64     WFramedParam *param;
65 } AP;
66
67
68 WRegion *framed_handler(WWindow *par, 
69                         const WFitParams *fp, 
70                         void *ap_)
71 {
72     AP *ap=(AP*)ap_;
73     WMPlexAttachParams mp=MPLEXATTACHPARAMS_INIT;
74     WFramedParam *param=ap->param;
75     WRectangle rqg, mg;
76     WFrame *frame;
77     WRegion *reg;
78     
79     if(param->mkframe!=NULL)
80         frame=(WFrame*)(param->mkframe)(par, fp);
81     else
82         frame=create_frame(par, fp, FRAME_MODE_FLOATING);
83     
84     if(frame==NULL)
85         return NULL;
86     
87     if(fp->mode&(REGION_FIT_BOUNDS|REGION_FIT_WHATEVER))
88         mp.flags|=MPLEX_ATTACH_WHATEVER;
89
90     reg=mplex_do_attach(&frame->mplex, &mp, ap->data);
91     
92     if(reg==NULL){
93         destroy_obj((Obj*)frame);
94         return NULL;
95     }
96
97     if(!(fp->mode&(REGION_FIT_BOUNDS|REGION_FIT_WHATEVER)))
98         return (WRegion*)frame;
99
100     mplex_managed_geom((WMPlex*)frame, &mg);
101
102     /* Adjust geometry */
103     if(!param->inner_geom_gravity_set){
104         rqg.x=REGION_GEOM(frame).x;
105         rqg.y=REGION_GEOM(frame).y;
106         rqg.w=maxof(1, REGION_GEOM(reg).w+(REGION_GEOM(frame).w-mg.w));
107         rqg.h=maxof(1, REGION_GEOM(reg).h+(REGION_GEOM(frame).h-mg.h));
108     }else{
109         int bl=mg.x;
110         int br=REGION_GEOM(frame).w-(mg.x+mg.w);
111         int bt=mg.y;
112         int bb=REGION_GEOM(frame).h-(mg.y+mg.h);
113         
114         rqg.x=(fp->g.x+param->inner_geom.x+
115                xgravity_deltax(param->gravity, bl, br));
116         rqg.y=(fp->g.y+param->inner_geom.y+
117                xgravity_deltay(param->gravity, bt, bb));
118         rqg.w=maxof(1, param->inner_geom.w+(REGION_GEOM(frame).w-mg.w));
119         rqg.h=maxof(1, param->inner_geom.h+(REGION_GEOM(frame).h-mg.h));
120     }
121
122     if(!(fp->mode&REGION_FIT_WHATEVER))
123         rectangle_constrain(&rqg, &fp->g);
124     
125     region_fit((WRegion*)frame, &rqg, REGION_FIT_EXACT);
126     
127     return (WRegion*)frame;
128 }
129
130
131 WRegion *region_attach_framed(WRegion *reg, WFramedParam *param,
132                               WRegionAttachFn *fn, void *fn_param,
133                               WRegionAttachData *data)
134 {
135     WRegionAttachData data2;
136     AP ap;
137
138     data2.type=REGION_ATTACH_NEW;
139     data2.u.n.fn=framed_handler;
140     data2.u.n.param=&ap;
141     
142     ap.data=data;
143     ap.param=param;
144     
145     return fn(reg, fn_param, &data2);
146 }
147
148
149 WRegion *framedpholder_do_attach(WFramedPHolder *ph, int flags,
150                                  WRegionAttachData *data)
151 {
152     WRegionAttachData data2;
153     AP ap;
154     
155     if(ph->cont==NULL)
156         return FALSE;
157
158     data2.type=REGION_ATTACH_NEW;
159     data2.u.n.fn=framed_handler;
160     data2.u.n.param=&ap;
161     
162     ap.data=data;
163     ap.param=&ph->param;
164         
165     return pholder_attach_(ph->cont, flags, &data2);
166 }
167
168
169 /*}}}*/
170
171
172 /*{{{ Other dynfuns */
173
174
175 bool framedpholder_do_goto(WFramedPHolder *ph)
176 {
177     if(ph->cont!=NULL)
178         return pholder_goto(ph->cont);
179     
180     return FALSE;
181 }
182
183
184 WRegion *framedpholder_do_target(WFramedPHolder *ph)
185 {
186     if(ph->cont!=NULL)
187         return pholder_target(ph->cont);
188     
189     return NULL;
190 }
191
192
193 /*}}}*/
194
195
196 /*{{{ Class information */
197
198
199 static DynFunTab framedpholder_dynfuntab[]={
200     {(DynFun*)pholder_do_attach, 
201      (DynFun*)framedpholder_do_attach},
202
203     {(DynFun*)pholder_do_goto, 
204      (DynFun*)framedpholder_do_goto},
205
206     {(DynFun*)pholder_do_target, 
207      (DynFun*)framedpholder_do_target},
208     
209     END_DYNFUNTAB
210 };
211
212 IMPLCLASS(WFramedPHolder, WPHolder, framedpholder_deinit, 
213           framedpholder_dynfuntab);
214
215
216 /*}}}*/
217