textbutton3.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /* use button 3 for a proper function to the application, that is not for plumber
  10. * as default control(2) supposes.
  11. * codes are mostly from /sys/src/libcontrol/textbutton.c
  12. */
  13. #include <u.h>
  14. #include <libc.h>
  15. #include <draw.h>
  16. #include <thread.h>
  17. #include <mouse.h>
  18. #include <keyboard.h>
  19. #include <control.h>
  20. typedef struct Textbutton3 Textbutton3;
  21. struct Textbutton3
  22. {
  23. Control Control;
  24. CFont *font;
  25. CImage *image;
  26. CImage *mask;
  27. CImage *light;
  28. CImage *bordercolor;
  29. CImage *textcolor;
  30. CImage *pressedtextcolor;
  31. int pressed;
  32. int lastbut;
  33. int lastshow;
  34. char **line;
  35. int nline;
  36. int align;
  37. int border;
  38. int left;
  39. int middle;
  40. int right;
  41. int toggle;
  42. int gettextflg;
  43. };
  44. enum{
  45. EAlign,
  46. EBorder,
  47. EBordercolor,
  48. EFocus,
  49. EFont,
  50. EFormat,
  51. EHide,
  52. EImage,
  53. ELight,
  54. EMask,
  55. EPressedtextcolor,
  56. ERect,
  57. EReveal,
  58. EShow,
  59. ESize,
  60. EText,
  61. ETextcolor,
  62. EEnable,
  63. EDisable,
  64. EToggle,
  65. EGettext,
  66. EValue,
  67. };
  68. static char *cmds[] = {
  69. [EAlign] = "align",
  70. [EBorder] = "border",
  71. [EBordercolor] = "bordercolor",
  72. [EFocus] = "focus",
  73. [EFont] = "font",
  74. [EFormat] = "format",
  75. [EHide] = "hide",
  76. [EImage] = "image",
  77. [ELight] = "light",
  78. [EMask] = "mask",
  79. [EPressedtextcolor] ="pressedtextcolor",
  80. [ERect] = "rect",
  81. [EReveal] = "reveal",
  82. [EShow] = "show",
  83. [ESize] = "size",
  84. [EText] = "text",
  85. [ETextcolor] = "textcolor",
  86. [EEnable] = "enable",
  87. [EDisable] = "disable",
  88. [EToggle] = "toggle",
  89. [EGettext] = "gettext",
  90. [EValue] = "value",
  91. nil
  92. };
  93. static void textbutton3show(Textbutton3 *);
  94. static void
  95. textbutton3mouse(Control *c, Mouse *m)
  96. {
  97. Textbutton3 *t;
  98. t = (Textbutton3 *)c;
  99. if(t->left == 1) {
  100. if((m->buttons&1) == 1 && (t->lastbut&1) == 0){
  101. t->pressed ^= 1;
  102. textbutton3show(t);
  103. t->lastbut = m->buttons & 1;
  104. }else if((m->buttons&1) == 0 && (t->lastbut&1) == 1){
  105. if(t->gettextflg == 0)
  106. chanprint(t->Control.event, t->Control.format, t->Control.name, t->pressed, m->xy.x, m->xy.y);
  107. else
  108. chanprint(t->Control.event, "%q: value %q", t->Control.name, t->line[0]);
  109. t->pressed ^= 1;
  110. textbutton3show(t);
  111. t->lastbut = m->buttons & 1;
  112. }
  113. }
  114. if(t->middle == 1) {
  115. if((m->buttons&2) == 2 && (t->lastbut&2) == 0){
  116. t->pressed ^= 2;
  117. textbutton3show(t);
  118. t->lastbut = m->buttons & 2;
  119. }else if((m->buttons&2) == 0 && (t->lastbut&2) == 2){
  120. if(t->gettextflg == 0)
  121. chanprint(t->Control.event, t->Control.format, t->Control.name, t->pressed, m->xy.x, m->xy.y);
  122. else
  123. chanprint(t->Control.event, "%q: value %q", t->Control.name, t->line[0]);
  124. t->pressed ^= 2;
  125. textbutton3show(t);
  126. t->lastbut = m->buttons & 2;
  127. }
  128. }
  129. if(t->right == 1) {
  130. if((m->buttons&4) == 4 && (t->lastbut&4) == 0){
  131. t->pressed ^= 4;
  132. textbutton3show(t);
  133. t->lastbut = m->buttons & 4;
  134. }else if((m->buttons&4) == 0 && (t->lastbut&4) == 4){
  135. if(t->gettextflg == 0)
  136. chanprint(t->Control.event, t->Control.format, t->Control.name, t->pressed, m->xy.x, m->xy.y);
  137. else
  138. chanprint(t->Control.event, "%q: value %q", t->Control.name, t->line[0]);
  139. t->pressed ^= 4;
  140. textbutton3show(t);
  141. t->lastbut = m->buttons & 4;
  142. }
  143. }
  144. }
  145. static void
  146. textbutton3free(Control *c)
  147. {
  148. int i;
  149. Textbutton3 *t;
  150. t = (Textbutton3*)c;
  151. _putctlfont(t->font);
  152. _putctlimage(t->image);
  153. _putctlimage(t->light);
  154. _putctlimage(t->mask);
  155. _putctlimage(t->textcolor);
  156. _putctlimage(t->bordercolor);
  157. _putctlimage(t->pressedtextcolor);
  158. for(i=0; i<t->nline; i++)
  159. free(t->line[i]);
  160. free(t->line);
  161. }
  162. static void
  163. textbutton3show(Textbutton3 *t)
  164. {
  165. Rectangle r, clipr;
  166. int i, dx, dy, w;
  167. Font *f;
  168. Point p, q;
  169. Image *im;
  170. if(t->Control.hidden || t->lastshow == t->pressed)
  171. return;
  172. f = t->font->font;
  173. draw(t->Control.screen, t->Control.rect, t->image->image, nil, t->image->image->r.min);
  174. if(t->pressed || t->toggle)
  175. draw(t->Control.screen, t->Control.rect, t->light->image, t->mask->image, t->mask->image->r.min);
  176. if(t->border > 0)
  177. border(t->Control.screen, t->Control.rect, t->border, t->bordercolor->image, ZP);
  178. /* text goes here */
  179. dx = 0;
  180. for(i=0; i<t->nline; i++){
  181. w = stringwidth(f, t->line[i]); /*****/
  182. if(dx < w)
  183. dx = w;
  184. }
  185. dy = t->nline*f->height;
  186. clipr = insetrect(t->Control.rect, t->border);
  187. p = _ctlalignpoint(clipr, dx, dy, t->align);
  188. im = t->textcolor->image;
  189. if(t->pressed)
  190. im = t->pressedtextcolor->image;
  191. for(i=0; i<t->nline; i++){
  192. r.min = p;
  193. r.max.x = p.x+dx;
  194. r.max.y = p.y+f->height;
  195. q = _ctlalignpoint(r, stringwidth(f, t->line[i]), f->height, t->align%3);
  196. _string(t->Control.screen, q, im,
  197. ZP, f, t->line[i], nil, strlen(t->line[i]),
  198. clipr, nil, ZP, SoverD);
  199. p.y += f->height;
  200. }
  201. t->lastshow = t->pressed;
  202. flushimage(display, 1);
  203. }
  204. static void
  205. textbutton3ctl(Control *c, CParse *cp)
  206. {
  207. int cmd, i;
  208. Rectangle r;
  209. Textbutton3 *t;
  210. t = (Textbutton3*)c;
  211. cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
  212. switch(cmd){
  213. default:
  214. ctlerror("%q: unrecognized message '%s'", t->Control.name, cp->str);
  215. break;
  216. case EAlign:
  217. _ctlargcount(&t->Control, cp, 2);
  218. t->align = _ctlalignment(cp->args[1]);
  219. t->lastshow = -1; /* force redraw */
  220. break;
  221. case EBorder:
  222. _ctlargcount(&t->Control, cp, 2);
  223. t->border = cp->iargs[1];
  224. t->lastshow = -1; /* force redraw */
  225. break;
  226. case EBordercolor:
  227. _ctlargcount(&t->Control, cp, 2);
  228. _setctlimage(&t->Control, &t->bordercolor, cp->args[1]);
  229. t->lastshow = -1; /* force redraw */
  230. break;
  231. case EFocus:
  232. break;
  233. case EFont:
  234. _ctlargcount(&t->Control, cp, 2);
  235. _setctlfont(&t->Control, &t->font, cp->args[1]);
  236. t->lastshow = -1; /* force redraw */
  237. break;
  238. case EFormat:
  239. _ctlargcount(&t->Control, cp, 2);
  240. t->Control.format = ctlstrdup(cp->args[1]);
  241. break;
  242. case EHide:
  243. _ctlargcount(&t->Control, cp, 1);
  244. t->Control.hidden = 1;
  245. break;
  246. case EImage:
  247. _ctlargcount(&t->Control, cp, 2);
  248. _setctlimage(&t->Control, &t->image, cp->args[1]);
  249. t->lastshow = -1; /* force redraw */
  250. break;
  251. case ELight:
  252. _ctlargcount(&t->Control, cp, 2);
  253. _setctlimage(&t->Control, &t->light, cp->args[1]);
  254. t->lastshow = -1; /* force redraw */
  255. break;
  256. case EMask:
  257. _ctlargcount(&t->Control, cp, 2);
  258. _setctlimage(&t->Control, &t->mask, cp->args[1]);
  259. t->lastshow = -1; /* force redraw */
  260. break;
  261. case EPressedtextcolor:
  262. _ctlargcount(&t->Control, cp, 2);
  263. _setctlimage(&t->Control, &t->pressedtextcolor, cp->args[1]);
  264. t->lastshow = -1; /* force redraw */
  265. break;
  266. case ERect:
  267. _ctlargcount(&t->Control, cp, 5);
  268. r.min.x = cp->iargs[1];
  269. r.min.y = cp->iargs[2];
  270. r.max.x = cp->iargs[3];
  271. r.max.y = cp->iargs[4];
  272. if(Dx(r)<=0 || Dy(r)<=0)
  273. ctlerror("%q: bad rectangle: %s", t->Control.name, cp->str);
  274. t->Control.rect = r;
  275. t->lastshow = -1; /* force redraw */
  276. break;
  277. case EReveal:
  278. _ctlargcount(&t->Control, cp, 1);
  279. t->Control.hidden = 0;
  280. t->lastshow = -1; /* force redraw */
  281. textbutton3show(t);
  282. break;
  283. case EShow:
  284. _ctlargcount(&t->Control, cp, 1);
  285. t->lastshow = -1; /* force redraw */
  286. textbutton3show(t);
  287. break;
  288. case ESize:
  289. if (cp->nargs == 3)
  290. r.max = Pt(0x7fffffff, 0x7fffffff);
  291. else{
  292. _ctlargcount(&t->Control, cp, 5);
  293. r.max.x = cp->iargs[3];
  294. r.max.y = cp->iargs[4];
  295. }
  296. r.min.x = cp->iargs[1];
  297. r.min.y = cp->iargs[2];
  298. if(r.min.x<=0 || r.min.y<=0 || r.max.x<=0 || r.max.y<=0 || r.max.x < r.min.x || r.max.y < r.min.y)
  299. ctlerror("%q: bad sizes: %s", t->Control.name, cp->str);
  300. t->Control.size.min = r.min;
  301. t->Control.size.max = r.max;
  302. break;
  303. case EText:
  304. /* free existing text */
  305. for(i=0; i<t->nline; i++)
  306. free(t->line[i]);
  307. t->nline = cp->nargs-1;
  308. t->line = ctlrealloc(t->line, t->nline*sizeof(char*));
  309. for(i=0; i<t->nline; i++)
  310. t->line[i] = ctlstrdup(cp->args[i+1]);
  311. t->lastshow = -1; /* force redraw */
  312. textbutton3show(t);
  313. break;
  314. case ETextcolor:
  315. _ctlargcount(&t->Control, cp, 2);
  316. _setctlimage(&t->Control, &t->textcolor, cp->args[1]);
  317. t->lastshow = -1; /* force redraw */
  318. break;
  319. case EEnable:
  320. _ctlargcount(&t->Control, cp, 2);
  321. if(strcmp(cp->args[1], "left") == 0)
  322. t->left = 1;
  323. else if(strcmp(cp->args[1], "middle") == 0)
  324. t->middle = 1;
  325. else if(strcmp(cp->args[1], "right") == 0)
  326. t->right = 1;
  327. break;
  328. case EDisable:
  329. _ctlargcount(&t->Control, cp, 2);
  330. if(strcmp(cp->args[1], "left") == 0)
  331. t->left = 0;
  332. else if(strcmp(cp->args[1], "middle") == 0)
  333. t->middle = 0;
  334. else if(strcmp(cp->args[1], "right") == 0)
  335. t->right = 0;
  336. break;
  337. case EToggle:
  338. _ctlargcount(&t->Control, cp, 2);
  339. if(strcmp(cp->args[1], "on") == 0)
  340. t->toggle = 1;
  341. else if(strcmp(cp->args[1], "off") == 0)
  342. t->toggle = 0;
  343. t->lastshow = -1; /* force redraw */
  344. break;
  345. case EGettext:
  346. _ctlargcount(&t->Control, cp, 2);
  347. if(strcmp(cp->args[1], "on") == 0)
  348. t->gettextflg = 1;
  349. else if(strcmp(cp->args[1], "off") == 0)
  350. t->gettextflg = 0;
  351. break;
  352. case EValue:
  353. _ctlargcount(&t->Control, cp, 2);
  354. if((cp->iargs[1]!=0) != t->pressed){
  355. t->pressed ^= 1;
  356. textbutton3show(t);
  357. }
  358. break;
  359. }
  360. }
  361. Control*
  362. createtextbutton3(Controlset *cs, char *name)
  363. {
  364. Textbutton3 *t;
  365. t = (Textbutton3 *)_createctl(cs, "textbutton3", sizeof(Textbutton3), name);
  366. t->line = ctlmalloc(sizeof(char*));
  367. t->nline = 0;
  368. t->image = _getctlimage("white");
  369. t->light = _getctlimage("yellow");
  370. t->mask = _getctlimage("opaque");
  371. t->bordercolor = _getctlimage("black");
  372. t->textcolor = _getctlimage("black");
  373. t->pressedtextcolor = _getctlimage("black");
  374. t->font = _getctlfont("font");
  375. t->Control.format = ctlstrdup("%q: value %d %d %d");
  376. t->lastshow = -1;
  377. t->Control.mouse = textbutton3mouse;
  378. t->Control.ctl = textbutton3ctl;
  379. t->Control.exit = textbutton3free;
  380. t->left = 1;
  381. t->middle = 1;
  382. t->right = 1;
  383. t->toggle = 0;
  384. t->gettextflg = 0;
  385. return (Control *)t;
  386. }