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 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* 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* 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* 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 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 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* 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