xref: /inferno-os/libtk/cimag.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 #include "lib9.h"
2 #include "draw.h"
3 #include "tk.h"
4 #include "canvs.h"
5 
6 #define	O(t, e)		((long)(&((t*)0)->e))
7 
8 /* Image Options (+ means implemented)
9 	+anchor
10 	+image
11 */
12 
13 typedef struct TkCimag TkCimag;
14 struct TkCimag
15 {
16 	int	anchor;
17 	Point	anchorp;
18 	TkImg*	tki;
19 };
20 
21 static
22 TkOption imgopts[] =
23 {
24 	"anchor",	OPTstab,	O(TkCimag, anchor),	tkanchor,
25 	"image",	OPTimag,	O(TkCimag, tki),	nil,
26 	nil
27 };
28 
29 static
30 TkOption itemopts[] =
31 {
32 	"tags",		OPTctag,	O(TkCitem, tags),	nil,
33 	nil
34 };
35 
36 void
tkcvsimgsize(TkCitem * i)37 tkcvsimgsize(TkCitem *i)
38 {
39 	Point o;
40 	int dx, dy;
41 	TkCimag *t;
42 
43 	t = TKobj(TkCimag, i);
44 	i->p.bb = bbnil;
45 	if(t->tki == nil)
46 		return;
47 
48 	dx = t->tki->w;
49 	dy = t->tki->h;
50 
51 	o = tkcvsanchor(i->p.drawpt[0], dx, dy, t->anchor);
52 
53 	i->p.bb.min.x = o.x;
54 	i->p.bb.min.y = o.y;
55 	i->p.bb.max.x = o.x + dx;
56 	i->p.bb.max.y = o.y + dy;
57 	t->anchorp = subpt(o, i->p.drawpt[0]);
58 }
59 
60 char*
tkcvsimgcreat(Tk * tk,char * arg,char ** val)61 tkcvsimgcreat(Tk* tk, char *arg, char **val)
62 {
63 	char *e;
64 	TkCimag *t;
65 	TkCitem *i;
66 	TkCanvas *c;
67 	TkOptab tko[3];
68 
69 	c = TKobj(TkCanvas, tk);
70 
71 	i = tkcnewitem(tk, TkCVimage, sizeof(TkCitem)+sizeof(TkCimag));
72 	if(i == nil)
73 		return TkNomem;
74 
75 	t = TKobj(TkCimag, i);
76 
77 	e = tkparsepts(tk->env->top, &i->p, &arg, 0);
78 	if(e != nil) {
79 		tkcvsfreeitem(i);
80 		return e;
81 	}
82 	if(i->p.npoint != 1) {
83 		tkcvsfreeitem(i);
84 		return TkFewpt;
85 	}
86 
87 	tko[0].ptr = t;
88 	tko[0].optab = imgopts;
89 	tko[1].ptr = i;
90 	tko[1].optab = itemopts;
91 	tko[2].ptr = nil;
92 	e = tkparse(tk->env->top, arg, tko, nil);
93 	if(e != nil) {
94 		tkcvsfreeitem(i);
95 		return e;
96 	}
97 
98 	e = tkcaddtag(tk, i, 1);
99 	if(e != nil) {
100 		tkcvsfreeitem(i);
101 		return e;
102 	}
103 
104 	tkcvsimgsize(i);
105 
106 	e = tkvalue(val, "%d", i->id);
107 	if(e != nil) {
108 		tkcvsfreeitem(i);
109 		return e;
110 	}
111 
112 	tkcvsappend(c, i);
113 	tkbbmax(&c->update, &i->p.bb);
114 	tkcvssetdirty(tk);
115 	return nil;
116 }
117 
118 char*
tkcvsimgcget(TkCitem * i,char * arg,char ** val)119 tkcvsimgcget(TkCitem *i, char *arg, char **val)
120 {
121 	TkOptab tko[3];
122 	TkCimag *t = TKobj(TkCimag, i);
123 
124 	tko[0].ptr = t;
125 	tko[0].optab = imgopts;
126 	tko[1].ptr = i;
127 	tko[1].optab = itemopts;
128 	tko[2].ptr = nil;
129 
130 	return tkgencget(tko, arg, val, i->env->top);
131 }
132 
133 char*
tkcvsimgconf(Tk * tk,TkCitem * i,char * arg)134 tkcvsimgconf(Tk *tk, TkCitem *i, char *arg)
135 {
136 	char *e;
137 	TkOptab tko[3];
138 	TkCimag *t = TKobj(TkCimag, i);
139 
140 	tko[0].ptr = t;
141 	tko[0].optab = imgopts;
142 	tko[1].ptr = i;
143 	tko[1].optab = itemopts;
144 	tko[2].ptr = nil;
145 
146 	e = tkparse(tk->env->top, arg, tko, nil);
147 	tkcvsimgsize(i);
148 	return e;
149 }
150 
151 void
tkcvsimgfree(TkCitem * i)152 tkcvsimgfree(TkCitem *i)
153 {
154 	TkCimag *t;
155 
156 	t = TKobj(TkCimag, i);
157 	if(t->tki)
158 		tkimgput(t->tki);
159 }
160 
161 void
tkcvsimgdraw(Image * img,TkCitem * i,TkEnv * pe)162 tkcvsimgdraw(Image *img, TkCitem *i, TkEnv *pe)
163 {
164 	TkCimag *t;
165 	TkImg *tki;
166 	Rectangle r;
167 	Image *fg;
168 
169 	USED(pe);
170 
171 	t = TKobj(TkCimag, i);
172 	tki = t->tki;
173 	if(tki == nil)
174 		return;
175 	fg = tki->img;
176 	if(fg == nil)
177 		return;
178 
179 	r.min = addpt(t->anchorp, i->p.drawpt[0]);
180 	r.max = r.min;
181 	r.max.x += tki->w;
182 	r.max.y += tki->h;
183 
184 	draw(img, r, fg, nil, ZP);
185 }
186 
187 char*
tkcvsimgcoord(TkCitem * i,char * arg,int x,int y)188 tkcvsimgcoord(TkCitem *i, char *arg, int x, int y)
189 {
190 	char *e;
191 	TkCpoints p;
192 
193 	if(arg == nil) {
194 		tkxlatepts(i->p.parampt, i->p.npoint, x, y);
195 		tkxlatepts(i->p.drawpt, i->p.npoint, TKF2I(x), TKF2I(y));
196 		i->p.bb = rectaddpt(i->p.bb, Pt(TKF2I(x), TKF2I(y)));
197 	}
198 	else {
199 		e = tkparsepts(i->env->top, &p, &arg, 0);
200 		if(e != nil)
201 			return e;
202 		if(p.npoint != 1) {
203 			tkfreepoint(&p);
204 			return TkFewpt;
205 		}
206 		tkfreepoint(&i->p);
207 		i->p = p;
208 		tkcvsimgsize(i);
209 	}
210 	return nil;
211 }
212