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