cimag.c 3.2 KB

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