m_glyphs.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. /*
  2. * sfnedit/m_glyphs.c
  3. *
  4. * Copyright (C) 2020 bzt (bztsrc@gitlab)
  5. *
  6. * Permission is hereby granted, free of charge, to any person
  7. * obtaining a copy of this software and associated documentation
  8. * files (the "Software"), to deal in the Software without
  9. * restriction, including without limitation the rights to use, copy,
  10. * modify, merge, publish, distribute, sublicense, and/or sell copies
  11. * of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be
  15. * included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  21. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  22. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  24. * DEALINGS IN THE SOFTWARE.
  25. *
  26. * @brief Main window glyphs table
  27. *
  28. */
  29. #include <stdint.h>
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include "libsfn.h"
  33. #include "ui.h"
  34. #include "lang.h"
  35. #include "util.h"
  36. int scrollglyphs = 0, numglyphs = 0, pageglyphs = 0, selstart = -1, selend = -1, rastsize = 64, greset = 1, gres[0x110000];
  37. int gsize, glast = -1;
  38. char gsearch[32] = { 0 }, gstat[256] = { 0 }, gdef[0x110000];
  39. /**
  40. * Character table with glyphs window
  41. */
  42. void view_glyphs()
  43. {
  44. int i, j, k, l, x, y, n;
  45. ui_win_t *win = &wins[0];
  46. char cp[8], *s = NULL;
  47. ssfn_dst.ptr = (uint8_t*)win->data;
  48. ssfn_dst.p = win->p*4;
  49. ssfn_dst.w = win->w - 150; if(ssfn_dst.w < 1) ssfn_dst.w = 1;
  50. ssfn_dst.h = win->h;
  51. ui_box(win, 8, 29, 20, 20, theme[wins[0].field == 7 ? THEME_CURSOR : (!selfield ? THEME_DARKER : THEME_LIGHT)],
  52. theme[wins[0].field == 7 ? THEME_LIGHT : THEME_BG],
  53. theme[wins[0].field == 7 ? THEME_CURSOR : (!selfield ? THEME_LIGHT : THEME_DARKER)]);
  54. ui_icon(win, 10, 31, ICON_VECTOR, 0);
  55. if(rastsize < 8) rastsize = 8;
  56. if(rastsize > SSFN_SIZE_MAX) rastsize = SSFN_SIZE_MAX;
  57. ui_num(win, 32, 29, rastsize, wins[0].field == 8, selfield - 1);
  58. ui_rect(win, 32, 29, 72, 20, theme[wins[0].field == 8 ? THEME_CURSOR : THEME_DARKER],
  59. theme[wins[0].field == 8 ? THEME_CURSOR : THEME_LIGHT]);
  60. ui_box(win, 83, 30, 20, 18, theme[wins[0].field == 8 ? THEME_LIGHT : (selfield == 3 ? THEME_DARKER : THEME_LIGHT)],
  61. theme[wins[0].field == 8 ? THEME_LIGHT : THEME_BG], theme[wins[0].field == 8 ? THEME_LIGHT :
  62. (selfield == 3 ? THEME_LIGHT : THEME_DARKER)]);
  63. ui_icon(win, 85, 31, ICON_BITMAP, 0);
  64. ui_box(win, 117, 29, 20, 20, theme[wins[0].field == 9 ? THEME_CURSOR : (selfield == 4 ? THEME_DARKER : THEME_LIGHT)],
  65. theme[wins[0].field == 9 ? THEME_LIGHT : THEME_BG], theme[wins[0].field == 9 ? THEME_CURSOR :
  66. (selfield == 4 ? THEME_LIGHT : THEME_DARKER)]);
  67. ui_icon(win, 119, 31, ICON_ZOOMOUT, 0);
  68. ui_box(win, 139, 29, 20, 20, theme[wins[0].field == 10 ? THEME_CURSOR : (selfield == 5 ? THEME_DARKER : THEME_LIGHT)],
  69. theme[wins[0].field == 10 ? THEME_LIGHT : THEME_BG], theme[wins[0].field == 10 ? THEME_CURSOR :
  70. (selfield == 5 ? THEME_LIGHT : THEME_DARKER)]);
  71. ui_icon(win, 141, 31, ICON_ZOOMIN, 0);
  72. ui_box(win, 172, 29, 20, 20, theme[wins[0].field == 11 ? THEME_CURSOR : (selfield == 6 ? THEME_DARKER : THEME_LIGHT)],
  73. theme[wins[0].field == 11 ? THEME_LIGHT : THEME_BG], theme[wins[0].field == 11 ? THEME_CURSOR :
  74. (selfield == 6 ? THEME_LIGHT : THEME_DARKER)]);
  75. ui_icon(win, 175, 31, ICON_CUT, 0);
  76. ui_box(win, 194, 29, 20, 20, theme[wins[0].field == 12 ? THEME_CURSOR : (selfield == 7 ? THEME_DARKER : THEME_LIGHT)],
  77. theme[wins[0].field == 12 ? THEME_LIGHT : THEME_BG], theme[wins[0].field == 12 ? THEME_CURSOR :
  78. (selfield == 7 ? THEME_LIGHT : THEME_DARKER)]);
  79. ui_icon(win, 197, 31, ICON_COPY, 0);
  80. ui_box(win, 216, 29, 20, 20, theme[wins[0].field == 13 ? THEME_CURSOR : (selfield == 8 ? THEME_DARKER : THEME_LIGHT)],
  81. theme[wins[0].field == 13 ? THEME_LIGHT : THEME_BG], theme[wins[0].field == 13 ? THEME_CURSOR :
  82. (selfield == 8 ? THEME_LIGHT : THEME_DARKER)]);
  83. ui_icon(win, 219, 31, ICON_PASTE, 0);
  84. ui_box(win, 250, 29, 20, 20, theme[wins[0].field == 14 ? THEME_CURSOR : (selfield == 9 ? THEME_DARKER : THEME_LIGHT)],
  85. theme[wins[0].field == 14 ? THEME_LIGHT : THEME_BG], theme[wins[0].field == 14 ? THEME_CURSOR :
  86. (selfield == 9 ? THEME_LIGHT : THEME_DARKER)]);
  87. ui_icon(win, 252, 31, ICON_DELETE, 0);
  88. ssfn_dst.w = win->w - 8; if(ssfn_dst.w < 1) ssfn_dst.w = 1;
  89. ui_box(win, 284, 29, win->w - 150 - 284, 18, theme[THEME_BG], theme[THEME_BG], theme[THEME_BG]);
  90. if(!gsearch[0]) {
  91. for(i = 0; i < UNICODE_NUMBLOCKS && (scrollglyphs < ublocks[i].start || scrollglyphs > ublocks[i].end); i++);
  92. if(i < UNICODE_NUMBLOCKS) s = ublocks[i].name;
  93. } else
  94. s = lang[GLYPHS_RESULTS];
  95. if(s) {
  96. ssfn_dst.fg = theme[THEME_LIGHTER];
  97. ui_text(win, 284, 30, s);
  98. ssfn_dst.fg = theme[THEME_DARKER];
  99. ui_text(win, 283, 29, s);
  100. ssfn_dst.fg = theme[THEME_FG];
  101. }
  102. ui_icon(win, win->w - 134 - 16, 30, ICON_SEARCH, 0);
  103. ui_input(win, win->w - 132, 29, 120, gsearch, wins[0].field == 15, 31, 0);
  104. gsize = (win->w - 20) / (1<<wins[0].zoom);
  105. i = gsize * (1<<wins[0].zoom); x = (win->w - i - 12) / 2 + 1;
  106. pageglyphs = ((win->h - 26 - 53) / gsize - 1) * (1<<wins[0].zoom); if(pageglyphs < (1<<wins[0].zoom)) pageglyphs = (1<<wins[0].zoom);
  107. scrollglyphs &= ~((1 << wins[0].zoom) - 1);
  108. ui_rect(win, x - 1, 51, i + 1, win->h - 26 - 51, theme[THEME_DARKER], theme[THEME_LIGHT]);
  109. ssfn_dst.w = x + i;
  110. ssfn_dst.bg = 0;
  111. if(greset || (input_refresh && !gsearch[0])) {
  112. gsearch[0] = 0;
  113. for(i = 0; i < 0x110000; i++) gres[i] = i;
  114. memset(gdef, 0, sizeof(gdef));
  115. for(i = 0; i < UNICODE_NUMNAMES; i++) gdef[uninames[i].unicode] = 1;
  116. numglyphs = 0x110000;
  117. } else
  118. if(input_refresh) {
  119. numglyphs = scrollglyphs = 0; selstart = selend = -1;
  120. l = strlen(gsearch);
  121. n = (gsearch[0] == 'U' || gsearch[0] == 'u') && gsearch[1] == '+' ? (int)gethex(gsearch + 2, 6) : -1;
  122. /* exact matches first */
  123. for(i = 0; i < UNICODE_NUMNAMES; i++) {
  124. if(!strcmp(utf8(uninames[i].unicode), gsearch) || uninames[i].unicode == n)
  125. gres[numglyphs++] = uninames[i].unicode;
  126. }
  127. /* name matches after */
  128. for(i = 0; i < UNICODE_NUMNAMES; i++) {
  129. if(strcmp(utf8(uninames[i].unicode), gsearch) && uninames[i].unicode != n) {
  130. k = strlen(uninames[i].name);
  131. if(k < l) continue;
  132. k -= l;
  133. for(j = 0; j <= k && ui_casecmp(uninames[i].name + j, gsearch, l); j++);
  134. if(j > k) continue;
  135. gres[numglyphs++] = uninames[i].unicode;
  136. }
  137. }
  138. }
  139. greset = input_refresh = 0;
  140. ssfn_dst.h = win->h - 27;
  141. for(i = scrollglyphs, j = 0, y = 52; i < numglyphs && y < ssfn_dst.h; i++, j++) {
  142. if(j == (1<<wins[0].zoom)) { j = 0; y += gsize; }
  143. if(ctx.glyphs[gres[i]].numlayer || (iswhitespace(gres[i]) && ctx.glyphs[gres[i]].adv_x+ctx.glyphs[gres[i]].adv_y > 0)) {
  144. ui_box(win, x + j * gsize, y, gsize - 1, gsize - 1, theme[THEME_DARKER],
  145. theme[i >= selstart && i <= selend ? THEME_SELBG : THEME_DARKER], theme[THEME_DARKER]);
  146. ssfn_dst.fg = theme[i >= selstart && i <= selend ? THEME_SELFG : THEME_FG];
  147. ui_glyph(win, x + j * gsize, y, gsize - 1, gres[i], -1, 1);
  148. } else if(gdef[gres[i]]) {
  149. ui_box(win, x + j * gsize, y, gsize - 1, gsize - 1, theme[THEME_DARK],
  150. theme[i >= selstart && i <= selend ? THEME_SELBG : THEME_UNDEF], theme[THEME_LIGHT]);
  151. ssfn_dst.x = k = x + j * gsize + 3;
  152. ssfn_dst.y = y + 3;
  153. ssfn_dst.fg = theme[THEME_DARKER];
  154. if(ssfn_putc(gres[i])) {
  155. sprintf(cp, "%06X", gres[i]);
  156. ssfn_dst.x = k;
  157. ssfn_dst.y = y + 3;
  158. ui_hex(win, cp[0]);
  159. ui_hex(win, cp[1]);
  160. ui_hex(win, cp[2]);
  161. ssfn_dst.x = k;
  162. ssfn_dst.y = y + 9;
  163. ui_hex(win, cp[3]);
  164. ui_hex(win, cp[4]);
  165. ui_hex(win, cp[5]);
  166. }
  167. } else
  168. ui_box(win, x + j * gsize, y, gsize - 1, gsize - 1, theme[THEME_DARK],
  169. theme[i >= selstart && i <= selend ? THEME_LIGHT : THEME_BG], theme[THEME_LIGHT]);
  170. }
  171. if(i == numglyphs)
  172. for(; y < ssfn_dst.h; i++, j++) {
  173. if(j == (1<<wins[0].zoom)) { j = 0; y += gsize; }
  174. ui_box(win, x + j * gsize, y, gsize - 1, gsize - 1, theme[THEME_BG], theme[THEME_BG], theme[THEME_BG]);
  175. }
  176. ssfn_dst.fg = theme[THEME_FG];
  177. ssfn_dst.w = win->w;
  178. ssfn_dst.h = win->h;
  179. ui_hscrbar(win, x + 1 + (1<<wins[0].zoom) * gsize, 52, 12, win->h - 79, scrollglyphs, pageglyphs, numglyphs, selfield == 15);
  180. }
  181. /**
  182. * Copy and cut controller
  183. */
  184. void ctrl_glyphs_copy(int cut)
  185. {
  186. int i, j, n;
  187. if(selend > -1) {
  188. ui_cursorwin(&wins[0], CURSOR_LOADING);
  189. for(n = 0, j = 0x110000, i = selstart; i <= selend; i++) {
  190. if(gres[i] < j) j = gres[i];
  191. if(ctx.glyphs[gres[i]].numlayer) n++;
  192. }
  193. copypaste_start(j);
  194. for(i = selstart; i <= selend; i++) {
  195. if(n > 1024) ui_pb(0, 0, i, selend - selstart + 1, PBAR_COPY);
  196. copypaste_copy(gres[i], -1);
  197. if(cut) sfn_chardel(gres[i]);
  198. }
  199. ui_cursorwin(&wins[0], CURSOR_PTR);
  200. if(cut) ui_refreshall();
  201. }
  202. }
  203. /**
  204. * On enter handler
  205. */
  206. void ctrl_glyphs_onenter()
  207. {
  208. int i;
  209. switch(wins[0].field) {
  210. case 7:
  211. wins[0].field = -1;
  212. selfield = 0;
  213. ui_cursorwin(&wins[0], CURSOR_LOADING);
  214. ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h);
  215. sfn_vectorize();
  216. ui_cursorwin(&wins[0], CURSOR_PTR);
  217. selfield = -1;
  218. ui_refreshall();
  219. modified++;
  220. break;
  221. case 8:
  222. wins[0].field = -1;
  223. selfield = 3;
  224. ui_cursorwin(&wins[0], CURSOR_LOADING);
  225. ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h);
  226. sfn_rasterize(rastsize);
  227. ui_cursorwin(&wins[0], CURSOR_PTR);
  228. selfield = -1;
  229. ui_refreshall();
  230. modified++;
  231. break;
  232. case 9:
  233. if(wins[0].zoom < 6) wins[0].zoom++;
  234. break;
  235. case 10:
  236. if(wins[0].zoom > 2) wins[0].zoom--;
  237. break;
  238. case 11:
  239. ctrl_glyphs_copy(1);
  240. break;
  241. case 12:
  242. ctrl_glyphs_copy(0);
  243. break;
  244. case 13:
  245. ui_cursorwin(&wins[0], CURSOR_LOADING);
  246. copypaste_paste(selstart >= 0 ? gres[selstart] : 0, 0);
  247. selstart = selend = glast = -1;
  248. ui_cursorwin(&wins[0], CURSOR_PTR);
  249. ui_refreshall();
  250. modified++;
  251. break;
  252. case 14:
  253. if(selend == -1)
  254. wins[0].tool = MAIN_TOOL_NEW;
  255. else {
  256. for(i = selstart; i <= selend; i++)
  257. sfn_chardel(gres[i]);
  258. ui_refreshall();
  259. modified++;
  260. }
  261. break;
  262. }
  263. }
  264. /**
  265. * On key handler
  266. */
  267. void ctrl_glyphs_onkey()
  268. {
  269. switch(event.x) {
  270. case K_UP:
  271. if(wins[0].field == 8) rastsize++;
  272. else {
  273. if(scrollglyphs > 0) scrollglyphs -= (1<<wins[0].zoom);
  274. wins[0].field = 16;
  275. }
  276. break;
  277. case K_DOWN:
  278. if(wins[0].field == 8) rastsize--;
  279. else {
  280. if(scrollglyphs + pageglyphs + (1<<wins[0].zoom) < numglyphs) scrollglyphs += (1<<wins[0].zoom);
  281. wins[0].field = 16;
  282. }
  283. break;
  284. case K_PGUP:
  285. if(scrollglyphs > pageglyphs) scrollglyphs -= pageglyphs; else scrollglyphs = 0;
  286. wins[0].field = 16;
  287. break;
  288. case K_PGDN:
  289. if(scrollglyphs + pageglyphs + (1<<wins[0].zoom) < numglyphs) scrollglyphs += pageglyphs;
  290. else scrollglyphs = (numglyphs - pageglyphs - 1) & ~((1<<wins[0].zoom) - 1);
  291. wins[0].field = 16;
  292. break;
  293. case K_HOME: scrollglyphs = 0; wins[0].field = 16; break;
  294. case K_END: scrollglyphs = (numglyphs - pageglyphs - 1) & ~((1<<wins[0].zoom) - 1); wins[0].field = 16; break;
  295. case K_DEL: case K_BACKSPC: if(selend != -1) { wins[0].field = 14; ctrl_glyphs_onenter(); wins[0].field = -1; } break;
  296. default:
  297. if(event.h & (3 << 1)) {
  298. switch(event.x) {
  299. case 'a': case 'A': selstart = 0; selend = numglyphs - 1; break;
  300. case 'x': case 'X': wins[0].field = 11; ctrl_glyphs_onenter(); break;
  301. case 'c': case 'C': wins[0].field = 12; ctrl_glyphs_onenter(); break;
  302. case 'v': case 'V': wins[0].field = 13; ctrl_glyphs_onenter(); break;
  303. }
  304. wins[0].field = 16;
  305. } else
  306. if(event.x >= ' ') {
  307. strcpy(gsearch, (char*)&event.x);
  308. wins[0].field = 15;
  309. input_refresh = 1;
  310. input_maxlen = 0;
  311. input_str = NULL;
  312. }
  313. break;
  314. }
  315. ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h);
  316. }
  317. /**
  318. * On button press handler
  319. */
  320. void ctrl_glyphs_onbtnpress()
  321. {
  322. ui_win_t *win = &wins[0];
  323. int i, j;
  324. char *s;
  325. selfield = -1;
  326. if(event.w != 1) glast = -1;
  327. if(event.y > 29 && event.y < 50) {
  328. if(event.x >= 8 && event.x < 28) selfield = 0; else
  329. if(((event.w >> 3) & 3) && event.x >= 32 && event.x < 83) {
  330. if(event.w & (1 << 3)) rastsize++;
  331. if(event.w & (1 << 4)) rastsize--;
  332. } else
  333. if(event.x >= 72 && event.x < 83) selfield = event.y < 41 ? 1 : 2; else
  334. if(event.x >= 83 && event.x < 103) selfield = 3; else
  335. if(event.x >= 117 && event.x < 138) selfield = 4; else
  336. if(event.x >= 139 && event.x < 159) selfield = 5; else
  337. if(event.x >= 172 && event.x < 192) selfield = 6; else
  338. if(event.x >= 194 && event.x < 214) selfield = 7; else
  339. if(event.x >= 216 && event.x < 236) selfield = 8; else
  340. if(event.x >= 250 && event.x < 270) selfield = 9; else
  341. if(event.x >= win->w - 132 && event.x < win->w - 8) wins[0].field = 15;
  342. } else
  343. if(event.y >= 52 && event.y < win->h - 26) {
  344. i = gsize * (1<<wins[0].zoom); i = (wins[0].w - i - 12) / 2 + 2 + (1<<wins[0].zoom) * gsize;
  345. if(event.x >= i) {
  346. i = 52 + (wins[0].h - 99) * scrollglyphs / numglyphs; j = 20 + (wins[0].h - 99) * pageglyphs / numglyphs;
  347. if(event.y >= i && event.y < i + j) { selfield = 15; scrolly = event.y - i; }
  348. } else {
  349. wins[0].field = 16;
  350. if(event.w & (1 << 3)) {
  351. if(scrollglyphs > 0) scrollglyphs -= (1<<wins[0].zoom);
  352. } else
  353. if(event.w & (1 << 4)) {
  354. if(scrollglyphs + pageglyphs + (1<<wins[0].zoom) < numglyphs) scrollglyphs += (1<<wins[0].zoom);
  355. } else
  356. if(event.w & 1) {
  357. selfield = 10;
  358. selstart = ((event.y - 52) / gsize) * (1<<wins[0].zoom) + (event.x - ((wins[0].w - 12 - gsize * (1<<wins[0].zoom))/2 + 1))
  359. / gsize + scrollglyphs;
  360. if(selstart < 0 || selstart >= numglyphs) selstart = -1;
  361. selend = glast = -1;
  362. } else
  363. if(event.w & 4) {
  364. if(selend != -1) { wins[0].field = 12; ctrl_glyphs_onenter(); }
  365. selstart = ((event.y - 52) / gsize) * (1<<wins[0].zoom) + (event.x - ((wins[0].w - 12 - gsize * (1<<wins[0].zoom))/2 + 1))
  366. / gsize + scrollglyphs;
  367. if(selstart < 0 || selstart >= numglyphs) selstart = -1;
  368. selend = glast = -1;
  369. wins[0].field = 13; ctrl_glyphs_onenter();
  370. selstart = -1;
  371. }
  372. }
  373. if((event.h & 2) && selfield == 10 && selstart > -1 && selend == -1) {
  374. /* ctrl + click: copy UTF-8 representation to clipboard */
  375. s = utf8(gres[selstart]);
  376. if(s && *s) ui_copy(s);
  377. }
  378. }
  379. }
  380. /**
  381. * On click (button release) handler
  382. */
  383. void ctrl_glyphs_onclick()
  384. {
  385. if(event.y > 29 && event.y < 50) {
  386. if(event.x >= 8 && event.x < 28 && !selfield) { wins[0].field = 7; ctrl_glyphs_onenter(); } else
  387. if(event.x >= 72 && event.x < 83) {
  388. if(selfield == 1 && event.y < 41) rastsize++;
  389. if(selfield == 2 && event.y >= 41) rastsize--;
  390. } else
  391. if(event.x >= 83 && event.x < 103 && selfield == 3) { wins[0].field = 8; ctrl_glyphs_onenter(); }
  392. if(event.x >= 117 && event.x < 138 && selfield == 4) { wins[0].field = 9; ctrl_glyphs_onenter(); wins[0].field = -1; }
  393. if(event.x >= 139 && event.x < 159 && selfield == 5) { wins[0].field = 10; ctrl_glyphs_onenter(); wins[0].field = -1; }
  394. if(event.x >= 172 && event.x < 192 && selfield == 6) { wins[0].field = 11; ctrl_glyphs_onenter(); wins[0].field = -1; }
  395. if(event.x >= 194 && event.x < 214 && selfield == 7) { wins[0].field = 12; ctrl_glyphs_onenter(); wins[0].field = -1; }
  396. if(event.x >= 216 && event.x < 236 && selfield == 8) { wins[0].field = 13; ctrl_glyphs_onenter(); wins[0].field = -1; }
  397. if(event.x >= 250 && event.x < 270 && selfield == 9) { wins[0].field = 14; ctrl_glyphs_onenter(); wins[0].field = -1; }
  398. } else
  399. if(!(event.h & 2) && event.y >= 52 && event.y < wins[0].h - 26 && selfield == 10 && selstart > -1 && selend == -1) {
  400. ui_openwin(gres[selstart]);
  401. }
  402. selfield = -1;
  403. }
  404. /**
  405. * On mouse move handler
  406. */
  407. void ctrl_glyphs_onmove()
  408. {
  409. int i;
  410. if(event.y > 29 && event.y < 49) {
  411. if(event.x >= 8 && event.x < 28) status = lang[GLYPHS_VECTORIZE]; else
  412. if(event.x >= 32 && event.x < 103) status = lang[GLYPHS_RASTERIZE]; else
  413. if(event.x >= 117 && event.x < 138) status = lang[GLYPHS_ZOOMOUT]; else
  414. if(event.x >= 139 && event.x < 159) status = lang[GLYPHS_ZOOMIN]; else
  415. if(event.x >= 172 && event.x < 192) status = lang[GLYPHS_CUT]; else
  416. if(event.x >= 194 && event.x < 214) status = lang[GLYPHS_COPY]; else
  417. if(event.x >= 216 && event.x < 236) status = lang[GLYPHS_PASTE]; else
  418. if(event.x >= 250 && event.x < 270) status = lang[GLYPHS_DELETE];
  419. glast = -1;
  420. } else
  421. if(event.y >= 52 && event.y < wins[0].h - 26) {
  422. i = gsize * (1<<wins[0].zoom); i = (wins[0].w - i - 12) / 2 + 2 + (1<<wins[0].zoom) * gsize;
  423. if(selfield == 15) {
  424. i = scrollglyphs;
  425. scrollglyphs = (event.y - scrolly - 52) * numglyphs / (wins[0].h - 99);
  426. if(scrollglyphs > numglyphs - pageglyphs) scrollglyphs = numglyphs - pageglyphs;
  427. if(scrollglyphs < 0) scrollglyphs = 0;
  428. if(i != scrollglyphs) {
  429. ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h);
  430. }
  431. } else if (event.x < i) {
  432. i = ((event.y - 52) / gsize) * (1<<wins[0].zoom) + (event.x - ((wins[0].w - 12 - gsize * (1<<wins[0].zoom))/2 + 1))
  433. / gsize + scrollglyphs;
  434. if(i >= 0 && i < numglyphs) {
  435. status = gstat;
  436. if(gres[i] != glast) {
  437. if(selfield == 10 && selstart != -1) {
  438. selend = i;
  439. ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h - 18);
  440. sprintf(gstat, "%s U+%06x .. U+%06X", lang[GLYPHS_SELECT], gres[selstart], gres[selend]);
  441. } else {
  442. ui_chrinfo(gres[i]);
  443. }
  444. glast = gres[i];
  445. }
  446. }
  447. }
  448. } else
  449. glast = -1;
  450. }