m_ranges.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*
  2. * sfnedit/m_ranges.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 UNICODE ranges tool
  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. int showallrange = 0, numranges = 0, scrollranges = 0, pageranges = 0, selranges = 0, clkranges = -1, rres[UNICODE_NUMBLOCKS];
  36. char rsearch[32] = { 0 }, rstat[64];
  37. extern int scrollglyphs, selstart, selend, greset;
  38. /**
  39. * UNICODE ranges window
  40. */
  41. void view_ranges()
  42. {
  43. ui_win_t *win = &wins[0];
  44. char tmp[32];
  45. int i, j, k, l, m;
  46. l = strlen(rsearch); numranges = 0;
  47. if(input_refresh) { scrollranges = selranges = 0; }
  48. input_refresh = 0;
  49. for(i = 0; i < UNICODE_NUMBLOCKS; i++) {
  50. ublocks[i].cnt = 0;
  51. if(l) {
  52. k = strlen(ublocks[i].name);
  53. if(k < l) continue;
  54. k -= l;
  55. for(j = 0; j <= k && ui_casecmp(ublocks[i].name + j, rsearch, l); j++);
  56. if(j > k) continue;
  57. }
  58. for(j = ublocks[i].start; j <= ublocks[i].end; j++)
  59. if(ctx.glyphs[j].numlayer) ublocks[i].cnt++;
  60. if(!showallrange && !ublocks[i].cnt) continue;
  61. rres[numranges++] = i;
  62. }
  63. ssfn_dst.w = win->w - 8; if(ssfn_dst.w < 1) ssfn_dst.w = 1;
  64. ssfn_dst.h = win->h;
  65. ui_bool(win, 8, 29, lang[RANGES_SHOWALL], showallrange, wins[0].field == 7);
  66. ui_icon(win, win->w - 134 - 16, 30, ICON_SEARCH, 0);
  67. ui_input(win, win->w - 132, 29, 120, rsearch, wins[0].field == 8, 31, 0);
  68. ui_rect(win, 7, 51, win->w - 14, win->h - 26 - 51, theme[THEME_DARKER], theme[THEME_LIGHT]);
  69. ssfn_dst.w = win->w - 9; if(ssfn_dst.w < 1) ssfn_dst.w = 1;
  70. ui_box(win, 8, 52, 172, 20, theme[THEME_LIGHT], theme[THEME_BG], theme[THEME_DARKER]);
  71. ssfn_dst.fg = theme[THEME_LIGHTER];
  72. ui_text(win, 16, 53, lang[RANGES_COVERAGE]);
  73. ssfn_dst.fg = theme[THEME_DARKER];
  74. ui_text(win, 15, 52, lang[RANGES_COVERAGE]);
  75. ui_box(win, 180, 52, win->w - 189, 20, theme[THEME_LIGHT], theme[THEME_BG], theme[THEME_DARKER]);
  76. ssfn_dst.fg = theme[THEME_LIGHTER];
  77. ui_text(win, 188, 53, lang[RANGES_NAME]);
  78. ssfn_dst.fg = theme[THEME_DARKER];
  79. ui_text(win, 187, 52, lang[RANGES_NAME]);
  80. ssfn_dst.fg = theme[THEME_FG];
  81. ssfn_dst.bg = 0;
  82. ssfn_dst.y = 72;
  83. pageranges = (win->h - 26 - 72) / 16; if(pageranges < 1) pageranges = 1;
  84. if(selranges + 1 > scrollranges + pageranges - 1) scrollranges = selranges - pageranges + 1;
  85. if(selranges >= 0 && selranges < scrollranges) scrollranges = selranges;
  86. ssfn_dst.h = win->h - 26;
  87. for(i = scrollranges; i < numranges && ssfn_dst.y < ssfn_dst.h; i++) {
  88. j = rres[i];
  89. if(i == selranges && win->field == 9)
  90. ui_box(win, 9, ssfn_dst.y, win->w - 30, 16, theme[THEME_SELBG], theme[THEME_SELBG], theme[THEME_SELBG]);
  91. m = ublocks[j].cnt * 1000 / (ublocks[j].end - ublocks[j].start + 1 - ublocks[j].undef);
  92. sprintf(tmp, "%3d.%02d%%", m / 10, m % 10); m /= 10; if(m > 100) m = 100;
  93. ssfn_dst.fg = theme[i == selranges && win->field == 8 ? THEME_SELFG : THEME_FG];
  94. ui_text(win, 11, ssfn_dst.y, tmp);
  95. ui_box(win, 78, ssfn_dst.y + 3, m, 11, theme[THEME_FG], ssfn_dst.fg, theme[THEME_FG]);
  96. ui_box(win, 78 + m, ssfn_dst.y + 3, 100 - m, 11, theme[THEME_DARKER], theme[THEME_DARKER], theme[THEME_DARKER]);
  97. ui_text(win, 185, ssfn_dst.y, ublocks[j].name);
  98. ssfn_dst.y += 16;
  99. }
  100. ui_hscrbar(win, win->w - 20, 72, 12, win->h - 99, scrollranges, pageranges, numranges, selfield == 16);
  101. ssfn_dst.fg = theme[THEME_FG];
  102. ssfn_dst.w = win->w;
  103. ssfn_dst.h = win->h;
  104. }
  105. /**
  106. * On enter handler
  107. */
  108. void ctrl_ranges_onenter()
  109. {
  110. if(wins[0].field == 7) { showallrange ^= 1; input_refresh = 1; } else
  111. if(wins[0].field == 9 && selranges >= 0 && selranges < numranges) {
  112. wins[0].tool = MAIN_TOOL_GLYPHS;
  113. wins[0].field = selfield = -1;
  114. greset = 1;
  115. selstart = ublocks[rres[selranges]].start;
  116. selend = ublocks[rres[selranges]].end;
  117. scrollglyphs = selstart & ~((1<<wins[0].zoom) - 1);
  118. }
  119. ui_resizewin(&wins[0], wins[0].w, wins[0].h);
  120. ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h);
  121. }
  122. /**
  123. * On key handler
  124. */
  125. void ctrl_ranges_onkey()
  126. {
  127. if(wins[0].field == 9) {
  128. switch(event.x) {
  129. case K_UP: if(selranges > 0) { selranges--; } break;
  130. case K_DOWN: if(selranges + 1 < numranges) { selranges++; } break;
  131. case K_PGUP:
  132. selranges -= pageranges - 1;
  133. if(selranges < 0) selranges = 0;
  134. break;
  135. case K_PGDN:
  136. selranges += pageranges - 1;
  137. if(selranges >= numranges) selranges = numranges - 1;
  138. break;
  139. case K_HOME: selranges = 0; break;
  140. case K_END: selranges = numranges - 1; break;
  141. }
  142. } else if(event.x == K_DOWN) {
  143. wins[0].field = 9;
  144. selranges = 0;
  145. }
  146. if(event.x >= ' ') {
  147. strcpy(rsearch, (char*)&event.x);
  148. wins[0].field = 8;
  149. input_refresh = 1;
  150. input_maxlen = 0;
  151. input_str = NULL;
  152. }
  153. ui_resizewin(&wins[0], wins[0].w, wins[0].h);
  154. ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h);
  155. }
  156. /**
  157. * On button press handler
  158. */
  159. void ctrl_ranges_onbtnpress()
  160. {
  161. ui_win_t *win = &wins[0];
  162. int i, j;
  163. if(event.y > 29 && event.y < 48) {
  164. if(event.x >= 8 && event.x < win->w - 154) { showallrange ^= 1; input_refresh = 1; } else
  165. if(event.x >= win->w - 132 && event.x < win->w - 8) wins[0].field = 8;
  166. } else
  167. if(event.y > 73 && event.y < win->h - 26) {
  168. wins[0].field = 9;
  169. if(event.x >= wins[0].w - 20 && numranges) {
  170. i = 72 + (wins[0].h - 117) * scrollranges / numranges; j = 20 + (wins[0].h - 117) * pageranges / numranges;
  171. if(event.y >= i && event.y < i + j) { selfield = 16; scrolly = event.y - i; }
  172. } else {
  173. if(event.w & 1) {
  174. selranges = (event.y - 73) / 16 + scrollranges;
  175. if(selranges >= numranges) selranges = numranges - 1;
  176. if(selranges != clkranges) clkranges = selranges;
  177. else ctrl_ranges_onenter();
  178. } else
  179. if(event.w & (1 << 3)) {
  180. if(scrollranges > 0) scrollranges--;
  181. if(selranges > scrollranges + pageranges - 1) selranges = scrollranges + pageranges - 1;
  182. } else
  183. if(event.w & (1 << 4)) {
  184. if(scrollranges + pageranges < numranges) scrollranges++;
  185. if(selranges < scrollranges) selranges = scrollranges;
  186. }
  187. }
  188. } else wins[0].field = -1;
  189. ui_resizewin(&wins[0], wins[0].w, wins[0].h);
  190. ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h);
  191. }
  192. /**
  193. * On mouse move handler
  194. */
  195. void ctrl_ranges_onmove()
  196. {
  197. int i;
  198. if(event.y > 73 && event.y < wins[0].h - 26) {
  199. if(selfield == 16) {
  200. i = scrollranges;
  201. scrollranges = (event.y - scrolly - 73) * numranges / (wins[0].h - 117);
  202. if(scrollranges > numranges - pageranges) scrollranges = numranges - pageranges;
  203. if(scrollranges < 0) scrollranges = 0;
  204. if(selranges < scrollranges) selranges = scrollranges;
  205. if(selranges > scrollranges + pageranges - 1) selranges = scrollranges + pageranges - 1;
  206. if(i != scrollranges) {
  207. ui_resizewin(&wins[0], wins[0].w, wins[0].h);
  208. ui_refreshwin(0, 0, 0, wins[0].w, wins[0].h);
  209. }
  210. } else {
  211. i = (event.y - 73) / 16 + scrollranges;
  212. if(i >= numranges) i = numranges - 1;
  213. sprintf(rstat, "U+%06X .. U+%06X", ublocks[rres[i]].start, ublocks[rres[i]].end);
  214. status = rstat;
  215. }
  216. }
  217. }