code_editor.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. /*******************************************************************************
  2. * Emu51
  3. * code_editor.cpp:
  4. * Created by mlt on 22/03/23.
  5. ******************************************************************************/
  6. #include <stdio.h>
  7. #include <emu51.h>
  8. #include <code_editor.h>
  9. #include <gui.h>
  10. void code_editor::load_source(char *filename)
  11. {
  12. FILE *strin;
  13. int c, i, tp, j = 0;
  14. strin = NULL;
  15. strin = fopen(filename, "rb");
  16. lines = 0;
  17. if ( strin == NULL )
  18. {
  19. ShowMessage("Can't open the file", screen, 200, 200, 200, 60, "Message!");
  20. }
  21. else
  22. {
  23. //for (c=0;c<65535;c++)
  24. //{
  25. // if (text_edit[c]!=NULL) delete[] text_edit[c];
  26. // else break;
  27. //}
  28. while ( !feof(strin))
  29. {
  30. alloc_new_line();
  31. for ( i = 0 ; ( i < 256 ) && !feof(strin) ; i++ )
  32. {
  33. c = fgetc(strin);
  34. if ( c == 9 ) //TAB
  35. {
  36. tp = i / tab_size;
  37. tp++;
  38. tp *= 8;
  39. for ( i ; i <= tp ; i++ )
  40. {
  41. text_edit[j][i] = 32;
  42. }
  43. i--;
  44. }
  45. else
  46. {
  47. if (( c == 10 ) || ( c == 13 ))
  48. {
  49. if ( c == 13 )
  50. {
  51. fgetc(strin);
  52. }
  53. for ( i ; i < 256 ; i++ )
  54. {
  55. text_edit[j][i] = 10;
  56. }
  57. }
  58. else
  59. {
  60. text_edit[j][i] = c == -1 ? 10 : c;
  61. }
  62. }
  63. }
  64. j++;
  65. }
  66. lines = j;
  67. fclose(strin);
  68. }
  69. cp = 0;
  70. cl = 0;
  71. scp = 0;
  72. scl = 0;
  73. disp();
  74. }
  75. void code_editor::disp(void)
  76. {
  77. int i, j, cnti, cntj = 0;
  78. for ( j = cl - scl ; j < cl - scl + _h + 1 && cntj < lines ; j++ )
  79. {
  80. cnti = 0;
  81. bool endf = false;
  82. for ( i = cp - scp ; i < cp - scp + _w && !endf ; i++ )
  83. {
  84. if ( text_edit[j][i] == 10 || text_edit[j][i] == 0 || text_edit[j][i] == 13 )
  85. {
  86. endf = true;
  87. }
  88. else
  89. {
  90. textprintf(surface, mainf, left + cnti * 8, top + cntj * 10, makecol(255, 255, 255), "%c",
  91. text_edit[j][i]);
  92. cnti++;
  93. }
  94. }
  95. for ( i ; i < cp - scp + _w + 1 ; i++ )
  96. {
  97. textprintf(surface, mainf, left + cnti * 8, top + cntj * 10, makecol(255, 255, 255), " ");
  98. cnti++;
  99. }
  100. cntj++;
  101. }
  102. if ( cntj < _h )
  103. {
  104. rectfill(surface, left, top + cntj * 10, surface->w - left, surface->h - left, 0);
  105. }
  106. }
  107. void code_editor::process(void)
  108. {
  109. BITMAP *cache;
  110. int c, i;
  111. bool exit_ed = false;
  112. char *filen;
  113. filen = new char[256];
  114. cache = create_bitmap(SCREEN_W, SCREEN_H);
  115. blit(screen, cache, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
  116. clear(surface);
  117. hline(surface, 2, surface->h - 2, surface->w - 2, makecol(255, 255, 255));
  118. vline(surface, 2, 2, surface->h - 2, makecol(255, 255, 255));
  119. vline(surface, surface->w - 2, 2, surface->h - 2, makecol(255, 255, 255));
  120. for ( c = 2 ; c <= 2 + 10 ; c += 2 )
  121. {
  122. hline(surface, 2, c, surface->w - 2, makecol(255, 255, 255));
  123. }
  124. textprintf_centre(surface, mainf, surface->w / 2, 4, makecol(255, 255, 255), " Source editor ");
  125. lines = 0;
  126. alloc_new_line();
  127. uint16_t key_p;
  128. uint16_t key_ch;
  129. while ( !exit_ed )
  130. {
  131. key_p = readkey();
  132. key_ch = key_p & 0xff;
  133. key_p = key_p >> 8;
  134. switch ( key_p )
  135. {
  136. case KEY_BACKSPACE:
  137. if ( cp > 0 )
  138. {
  139. clear_cr();
  140. if ( scp > 0 )
  141. {
  142. scp--;
  143. }
  144. cp--;
  145. backspace();
  146. }
  147. else
  148. {
  149. if ( cl > 0 )
  150. {
  151. clear_cr();
  152. for ( c = 0 ; ( c < 256 ) && ( text_edit[cl - 1][c] != 10 ) ; c++ )
  153. {
  154. }
  155. cp = c;
  156. scp = cp;
  157. if ( scp >= _w )
  158. {
  159. scp = _w - 1;
  160. }
  161. for ( c ; c < 256 ; c++ )
  162. {
  163. text_edit[cl - 1][c] = text_edit[cl][c - cp];
  164. if ( text_edit[cl][c - cp] == 10 )
  165. {
  166. break;
  167. }
  168. }
  169. delete[]text_edit[cl];
  170. for ( i = cl ; i < lines ; i++ )
  171. {
  172. text_edit[i] = text_edit[i + 1];
  173. }
  174. lines--;
  175. text_edit[lines] = NULL;
  176. cl--;
  177. if ( scl > 0 )
  178. {
  179. scl--;
  180. }
  181. }
  182. }
  183. break;
  184. case KEY_DEL:
  185. backspace();
  186. break;
  187. case KEY_ENTER:
  188. if ( cl < 65536 )
  189. {
  190. clear_cr();
  191. cl++;
  192. if ( scl < _h )
  193. {
  194. scl++;
  195. }
  196. if ( !insert_new_line(cl))
  197. {
  198. ShowMessage("Out of memory", surface, 200, 100, 200, 60, "Error!");
  199. }
  200. else
  201. {
  202. for ( c = cp ; c < 256 ; c++ )
  203. {
  204. text_edit[cl][c - cp] = text_edit[cl - 1][c];
  205. text_edit[cl - 1][c] = 10;
  206. }
  207. cp = 0;
  208. scp = 0;
  209. }
  210. }
  211. else
  212. {
  213. ShowMessage("Source can't has more then 65536 lines of code!!!", surface, 200, 100, 200, 60, "Error!");
  214. }
  215. break;
  216. case KEY_END:
  217. clear_cr();
  218. for ( cp = 0 ; cp < 256 && text_edit[cl][cp] != 10 ; cp++ )
  219. {
  220. }
  221. scp = cp;
  222. if ( scp >= _w )
  223. {
  224. scp = _w - 1;
  225. }
  226. break;
  227. case KEY_HOME:
  228. clear_cr();
  229. cp = 0;
  230. scp = 0;
  231. break;
  232. case KEY_LEFT:
  233. if ( cp > 0 )
  234. {
  235. clear_cr();
  236. cp--;
  237. if ( scp > 0 )
  238. {
  239. scp--;
  240. }
  241. }
  242. else
  243. {
  244. if ( cl > 0 )
  245. {
  246. clear_cr();
  247. for ( c = 0 ; ( c < 256 ) && ( text_edit[cl - 1][c] != 10 ) ; c++ )
  248. {
  249. }
  250. cp = c;
  251. scp = cp;
  252. if ( scp >= _w )
  253. {
  254. scp = _w - 1;
  255. }
  256. cl--;
  257. if ( scl > 0 )
  258. {
  259. scl--;
  260. }
  261. }
  262. }
  263. break;
  264. case KEY_RIGHT:
  265. if ( cp < 256 && text_edit[cl][cp] != 10 )
  266. {
  267. clear_cr();
  268. cp++;
  269. if ( scp < _w )
  270. {
  271. scp++;
  272. }
  273. }
  274. else
  275. {
  276. if ( cl + 1 < lines )
  277. {
  278. clear_cr();
  279. cp = 0;
  280. scp = cp;
  281. if ( scp >= _w )
  282. {
  283. scp = _w - 1;
  284. }
  285. cl++;
  286. if ( scl < _h )
  287. {
  288. scl++;
  289. }
  290. }
  291. }
  292. break;
  293. case KEY_UP:
  294. if ( cl > 0 )
  295. {
  296. clear_cr();
  297. cl--;
  298. if ( scl > 0 )
  299. {
  300. scl--;
  301. }
  302. for ( c = 0 ; c < 256 && text_edit[cl][c] != 10 ; c++ )
  303. {
  304. }
  305. if ( c - 1 < cp )
  306. {
  307. cp = c;
  308. scp = cp;
  309. if ( scp >= _w )
  310. {
  311. scp = _w - 1;
  312. }
  313. }
  314. }
  315. break;
  316. case KEY_DOWN:
  317. if ( cl < 65536 && cl < ( lines - 1 ))
  318. {
  319. clear_cr();
  320. cl++;
  321. if ( scl < _h )
  322. {
  323. scl++;
  324. }
  325. for ( c = 0 ; c < 256 && text_edit[cl][c] != 10 ; c++ )
  326. {
  327. }
  328. if ( c - 1 < cp )
  329. {
  330. cp = c;
  331. scp = cp;
  332. if ( scp >= _w )
  333. {
  334. scp = _w - 1;
  335. }
  336. }
  337. }
  338. break;
  339. case KEY_ESC:
  340. if ( QuestionBox("Are you sure want to EXIT?", screen, 200, 200, 400, 60, "Confirm!", makecol(255, 0, 0)))
  341. {
  342. exit_ed = true;
  343. for ( c = 0 ; c < lines ; c++ )
  344. {
  345. if ( text_edit[c] != NULL )
  346. {
  347. delete[] text_edit[c];
  348. }
  349. }
  350. lines = 0;
  351. }
  352. else
  353. {
  354. rest(500);
  355. clear_keybuf();
  356. }
  357. break;
  358. case KEY_F3:
  359. GetText(filen, screen, 100, 200, 600, 60, 256, " Enter source code file name ");
  360. for ( c = 254 ; filen[c] == ' ' || filen[c] == '\r' ; c-- )
  361. {
  362. filen[c] = 0;
  363. }
  364. load_source(filen);
  365. break;
  366. default:
  367. if ( key_ch != 0 && cp < 256 )
  368. {
  369. insert_char(cl, key_ch);
  370. clear_cr();
  371. cp++;
  372. if ( scp < _w )
  373. {
  374. scp++;
  375. }
  376. key_ch = 0;
  377. }
  378. break;
  379. }
  380. if ( !exit_ed )
  381. {
  382. disp();
  383. draw_cr();
  384. }
  385. textprintf(surface, mainf, 1, 1, makecol(255, 255, 255), " p%d l%d sp%d sl%d c%d ln%d", cp, cl, scp, scl,
  386. text_edit[cl][cp], lines);
  387. blit(surface, screen, 0, 0, 0, 0, surface->w, surface->h);
  388. }
  389. blit(cache, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
  390. destroy_bitmap(cache);
  391. delete[] filen;
  392. return;
  393. }
  394. void code_editor::insert_char(int ln, char ch)
  395. {
  396. int i;
  397. for ( i = 256 ; i > cp ; i-- )
  398. {
  399. text_edit[cl][i] = text_edit[cl][i - 1];
  400. }
  401. text_edit[cl][cp] = ch;
  402. }
  403. void code_editor::backspace(void)
  404. {
  405. int i;
  406. for ( i = cp ; i < 256 ; i++ )
  407. {
  408. text_edit[cl][i] = text_edit[cl][i + 1];
  409. }
  410. }
  411. void code_editor::draw_cr(void)
  412. {
  413. hline(surface, left + 8 * scp, top + 10 * scl + 9, left + 8 * scp + 8, makecol(255, 255, 255));
  414. }
  415. void code_editor::clear_cr(void)
  416. {
  417. hline(surface, left + 8 * scp, top + 10 * scl + 9, left + 8 * scp + 8, 0);
  418. }
  419. code_editor::code_editor(void)
  420. {
  421. int i;
  422. for ( i = 0 ; i < 65536 ; i++ )
  423. {
  424. text_edit[i] = NULL;
  425. }
  426. lines = 0;
  427. top = 24;
  428. left = 11;
  429. cl = 0;
  430. cp = 0;
  431. scl = 0;
  432. scp = 0;
  433. surface = create_bitmap(SCREEN_W, SCREEN_H - 100);
  434. _w = ( surface->w - left * 2 ) / 8 - 1;
  435. _h = ( surface->h - top - left ) / 10 - 1;
  436. tab_size = 8;
  437. }
  438. code_editor::~code_editor(void)
  439. {
  440. }
  441. bool code_editor::alloc_new_line(void)
  442. {
  443. int i;
  444. if ( lines < 65536 )
  445. {
  446. text_edit[lines] = new char[256];
  447. for ( i = 0 ; i < 256 ; i++ )
  448. {
  449. text_edit[lines][i] = 10;
  450. }
  451. lines++;
  452. return text_edit[lines] == NULL ? false : true;
  453. }
  454. return false;
  455. }
  456. bool code_editor::insert_new_line(int ln)
  457. {
  458. int i;
  459. if ( lines < 65536 )
  460. {
  461. for ( i = lines ; i > ln ; i-- )
  462. {
  463. text_edit[i] = text_edit[i - 1];
  464. }
  465. text_edit[ln] = NULL;
  466. text_edit[ln] = new char[256];
  467. for ( i = 0 ; i < 256 ; i++ )
  468. {
  469. text_edit[ln][i] = 10;
  470. }
  471. lines++;
  472. if ( text_edit[ln] == NULL )
  473. {
  474. for ( i = ln ; i < lines ; i++ )
  475. {
  476. text_edit[i] = text_edit[i + 1];
  477. }
  478. lines--;
  479. return false;
  480. }
  481. else
  482. {
  483. return true;
  484. }
  485. }
  486. return false;
  487. }
  488. void code_editor::delete_last(void)
  489. {
  490. lines--;
  491. delete[] text_edit[lines];
  492. text_edit[lines] = NULL;
  493. }
  494. void code_editor::cut_line(int ln)
  495. {
  496. int i;
  497. if ( text_edit[ln] != NULL )
  498. {
  499. for ( i = ln ; i < lines ; i++ )
  500. {
  501. text_edit[i] = text_edit[i + 1];
  502. }
  503. lines--;
  504. }
  505. }