nuklear_allegro5.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. /*
  2. * Nuklear - 1.32.0 - public domain
  3. * no warrenty implied; use at your own risk.
  4. * authored from 2015-2016 by Micha Mettke
  5. */
  6. /*
  7. * ==============================================================
  8. *
  9. * API
  10. *
  11. * ===============================================================
  12. */
  13. #ifndef NK_ALLEGRO5_H_
  14. #define NK_ALLEGRO5_H_
  15. #include <string.h>
  16. #include <allegro5/allegro.h>
  17. #include <allegro5/allegro_image.h>
  18. #include <allegro5/allegro_primitives.h>
  19. #include <allegro5/allegro_font.h>
  20. #include <allegro5/allegro_ttf.h>
  21. typedef struct NkAllegro5Font NkAllegro5Font;
  22. NK_API struct nk_context* nk_allegro5_init(NkAllegro5Font *font, ALLEGRO_DISPLAY *dsp,
  23. unsigned int width, unsigned int height);
  24. NK_API int nk_allegro5_handle_event(ALLEGRO_EVENT *ev);
  25. NK_API void nk_allegro5_shutdown(void);
  26. NK_API void nk_allegro5_render(void);
  27. NK_API struct nk_image* nk_allegro5_create_image(const char* file_name);
  28. NK_API void nk_allegro5_del_image(struct nk_image* image);
  29. /* Fonts. We wrap normal allegro fonts in some nuklear book keeping */
  30. NK_API NkAllegro5Font* nk_allegro5_font_create_from_file(const char *file_name, int font_size, int flags);
  31. NK_API void nk_allegro5_font_del(NkAllegro5Font *font);
  32. /* NOTE : just use NkAllegro5Font instead of nk_user_font,
  33. since the former just extends the latter*/
  34. NK_API void nk_allegro5_font_set_font(NkAllegro5Font *font);
  35. #endif
  36. /*
  37. * ==============================================================
  38. *
  39. * IMPLEMENTATION
  40. *
  41. * ===============================================================
  42. */
  43. #ifdef NK_ALLEGRO5_IMPLEMENTATION
  44. #ifndef NK_ALLEGRO5_TEXT_MAX
  45. #define NK_ALLEGRO5_TEXT_MAX 256
  46. #endif
  47. struct NkAllegro5Font {
  48. struct nk_user_font nk;
  49. ALLEGRO_FONT *font;
  50. };
  51. static struct nk_allegro5 {
  52. ALLEGRO_DISPLAY *dsp;
  53. unsigned int width;
  54. unsigned int height;
  55. int is_touch_down;
  56. int touch_down_id;
  57. struct nk_context ctx;
  58. struct nk_buffer cmds;
  59. } allegro5;
  60. NK_API struct nk_image* nk_allegro5_create_image(const char* file_name)
  61. {
  62. ALLEGRO_BITMAP *bitmap;
  63. struct nk_image *image;
  64. if (!al_init_image_addon()) {
  65. fprintf(stdout, "Unable to initialize required allegro5 image addon\n");
  66. exit(1);
  67. }
  68. bitmap = al_load_bitmap(file_name);
  69. if (bitmap == NULL) {
  70. fprintf(stdout, "Unable to load image file: %s\n", file_name);
  71. return NULL;
  72. }
  73. image = (struct nk_image*)calloc(1, sizeof(struct nk_image));
  74. image->handle.ptr = bitmap;
  75. image->w = al_get_bitmap_width(bitmap);
  76. image->h = al_get_bitmap_height(bitmap);
  77. return image;
  78. }
  79. NK_API void nk_allegro5_del_image(struct nk_image* image)
  80. {
  81. if(!image) return;
  82. al_destroy_bitmap(image->handle.ptr);
  83. free(image);
  84. }
  85. static float
  86. nk_allegro5_font_get_text_width(nk_handle handle, float height, const char *text, int len)
  87. {
  88. float width;
  89. char *strcpy;
  90. NkAllegro5Font *font = (NkAllegro5Font*)handle.ptr;
  91. NK_UNUSED(height);
  92. if (!font || !text) {
  93. return 0;
  94. }
  95. /* We must copy into a new buffer with exact length null-terminated
  96. as nuklear uses variable size buffers and al_get_text_width doesn't
  97. accept a length, it infers length from null-termination
  98. (which is unsafe API design by allegro devs!) */
  99. strcpy = malloc(len + 1);
  100. strncpy(strcpy, text, len);
  101. strcpy[len] = '\0';
  102. width = al_get_text_width(font->font, strcpy);
  103. free(strcpy);
  104. return width;
  105. }
  106. /* Flags are identical to al_load_font() flags argument */
  107. NK_API NkAllegro5Font*
  108. nk_allegro5_font_create_from_file(const char *file_name, int font_size, int flags)
  109. {
  110. NkAllegro5Font *font;
  111. if (!al_init_image_addon()) {
  112. fprintf(stdout, "Unable to initialize required allegro5 image addon\n");
  113. exit(1);
  114. }
  115. if (!al_init_font_addon()) {
  116. fprintf(stdout, "Unable to initialize required allegro5 font addon\n");
  117. exit(1);
  118. }
  119. if (!al_init_ttf_addon()) {
  120. fprintf(stdout, "Unable to initialize required allegro5 TTF font addon\n");
  121. exit(1);
  122. }
  123. font = (NkAllegro5Font*)calloc(1, sizeof(NkAllegro5Font));
  124. font->font = al_load_font(file_name, font_size, flags);
  125. if (font->font == NULL) {
  126. fprintf(stdout, "Unable to load font file: %s\n", file_name);
  127. return NULL;
  128. }
  129. font->nk.userdata = nk_handle_ptr(font);
  130. font->nk.height = (float)al_get_font_line_height(font->font);
  131. font->nk.width = nk_allegro5_font_get_text_width;
  132. return font;
  133. }
  134. NK_API void
  135. nk_allegro5_font_set_font(NkAllegro5Font *allegro5font)
  136. {
  137. struct nk_user_font *font = &allegro5font->nk;
  138. nk_style_set_font(&allegro5.ctx, font);
  139. }
  140. NK_API void
  141. nk_allegro5_font_del(NkAllegro5Font *font)
  142. {
  143. if(!font) return;
  144. al_destroy_font(font->font);
  145. free(font);
  146. }
  147. static ALLEGRO_COLOR
  148. nk_color_to_allegro_color(struct nk_color color)
  149. {
  150. return al_map_rgba((unsigned char)color.r, (unsigned char)color.g,
  151. (unsigned char)color.b, (unsigned char)color.a);
  152. }
  153. NK_API void
  154. nk_allegro5_render()
  155. {
  156. const struct nk_command *cmd;
  157. al_set_target_backbuffer(allegro5.dsp);
  158. nk_foreach(cmd, &allegro5.ctx)
  159. {
  160. ALLEGRO_COLOR color;
  161. switch (cmd->type) {
  162. case NK_COMMAND_NOP: break;
  163. case NK_COMMAND_SCISSOR: {
  164. const struct nk_command_scissor *s =(const struct nk_command_scissor*)cmd;
  165. al_set_clipping_rectangle((int)s->x, (int)s->y, (int)s->w, (int)s->h);
  166. } break;
  167. case NK_COMMAND_LINE: {
  168. const struct nk_command_line *l = (const struct nk_command_line *)cmd;
  169. color = nk_color_to_allegro_color(l->color);
  170. al_draw_line((float)l->begin.x, (float)l->begin.y, (float)l->end.x,
  171. (float)l->end.y, color, (float)l->line_thickness);
  172. } break;
  173. case NK_COMMAND_RECT: {
  174. const struct nk_command_rect *r = (const struct nk_command_rect *)cmd;
  175. color = nk_color_to_allegro_color(r->color);
  176. al_draw_rounded_rectangle((float)r->x, (float)r->y, (float)(r->x + r->w),
  177. (float)(r->y + r->h), (float)r->rounding, (float)r->rounding, color,
  178. (float)r->line_thickness);
  179. } break;
  180. case NK_COMMAND_RECT_FILLED: {
  181. const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd;
  182. color = nk_color_to_allegro_color(r->color);
  183. al_draw_filled_rounded_rectangle((float)r->x, (float)r->y,
  184. (float)(r->x + r->w), (float)(r->y + r->h), (float)r->rounding,
  185. (float)r->rounding, color);
  186. } break;
  187. case NK_COMMAND_CIRCLE: {
  188. float xr, yr;
  189. const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
  190. color = nk_color_to_allegro_color(c->color);
  191. xr = (float)c->w/2;
  192. yr = (float)c->h/2;
  193. al_draw_ellipse(((float)(c->x)) + xr, ((float)c->y) + yr,
  194. xr, yr, color, (float)c->line_thickness);
  195. } break;
  196. case NK_COMMAND_CIRCLE_FILLED: {
  197. float xr, yr;
  198. const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
  199. color = nk_color_to_allegro_color(c->color);
  200. xr = (float)c->w/2;
  201. yr = (float)c->h/2;
  202. al_draw_filled_ellipse(((float)(c->x)) + xr, ((float)c->y) + yr,
  203. xr, yr, color);
  204. } break;
  205. case NK_COMMAND_TRIANGLE: {
  206. const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd;
  207. color = nk_color_to_allegro_color(t->color);
  208. al_draw_triangle((float)t->a.x, (float)t->a.y, (float)t->b.x, (float)t->b.y,
  209. (float)t->c.x, (float)t->c.y, color, (float)t->line_thickness);
  210. } break;
  211. case NK_COMMAND_TRIANGLE_FILLED: {
  212. const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd;
  213. color = nk_color_to_allegro_color(t->color);
  214. al_draw_filled_triangle((float)t->a.x, (float)t->a.y, (float)t->b.x,
  215. (float)t->b.y, (float)t->c.x, (float)t->c.y, color);
  216. } break;
  217. case NK_COMMAND_POLYGON: {
  218. int i;
  219. float *vertices;
  220. const struct nk_command_polygon *p = (const struct nk_command_polygon*)cmd;
  221. vertices = calloc(p->point_count * 2, sizeof(float));
  222. color = nk_color_to_allegro_color(p->color);
  223. for (i = 0; i < p->point_count; i++) {
  224. vertices[i*2] = p->points[i].x;
  225. vertices[(i*2) + 1] = p->points[i].y;
  226. }
  227. al_draw_polyline((const float*)&vertices, (2 * sizeof(float)),
  228. (int)p->point_count, ALLEGRO_LINE_JOIN_ROUND, ALLEGRO_LINE_CAP_CLOSED,
  229. color, (float)p->line_thickness, 0.0);
  230. free(vertices);
  231. } break;
  232. case NK_COMMAND_POLYGON_FILLED: {
  233. int i;
  234. float *vertices;
  235. const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd;
  236. vertices = calloc(p->point_count * 2, sizeof(float));
  237. color = nk_color_to_allegro_color(p->color);
  238. for (i = 0; i < p->point_count; i++) {
  239. vertices[i*2] = p->points[i].x;
  240. vertices[(i*2) + 1] = p->points[i].y;
  241. }
  242. al_draw_filled_polygon((const float*)&vertices, (int)p->point_count, color);
  243. free(vertices);
  244. } break;
  245. case NK_COMMAND_POLYLINE: {
  246. int i;
  247. float *vertices;
  248. const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
  249. vertices = calloc(p->point_count * 2, sizeof(float));
  250. color = nk_color_to_allegro_color(p->color);
  251. for (i = 0; i < p->point_count; i++) {
  252. vertices[i*2] = p->points[i].x;
  253. vertices[(i*2) + 1] = p->points[i].y;
  254. }
  255. al_draw_polyline((const float*)&vertices, (2 * sizeof(float)),
  256. (int)p->point_count, ALLEGRO_LINE_JOIN_ROUND, ALLEGRO_LINE_CAP_ROUND,
  257. color, (float)p->line_thickness, 0.0);
  258. free(vertices);
  259. } break;
  260. case NK_COMMAND_TEXT: {
  261. NkAllegro5Font *font;
  262. const struct nk_command_text *t = (const struct nk_command_text*)cmd;
  263. color = nk_color_to_allegro_color(t->foreground);
  264. font = (NkAllegro5Font*)t->font->userdata.ptr;
  265. al_draw_text(font->font,
  266. color, (float)t->x, (float)t->y, 0,
  267. (const char*)t->string);
  268. } break;
  269. case NK_COMMAND_CURVE: {
  270. float points[8];
  271. const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
  272. color = nk_color_to_allegro_color(q->color);
  273. points[0] = (float)q->begin.x;
  274. points[1] = (float)q->begin.y;
  275. points[2] = (float)q->ctrl[0].x;
  276. points[3] = (float)q->ctrl[0].y;
  277. points[4] = (float)q->ctrl[1].x;
  278. points[5] = (float)q->ctrl[1].y;
  279. points[6] = (float)q->end.x;
  280. points[7] = (float)q->end.y;
  281. al_draw_spline(points, color, (float)q->line_thickness);
  282. } break;
  283. case NK_COMMAND_ARC: {
  284. const struct nk_command_arc *a = (const struct nk_command_arc *)cmd;
  285. color = nk_color_to_allegro_color(a->color);
  286. al_draw_arc((float)a->cx, (float)a->cy, (float)a->r, a->a[0],
  287. a->a[1], color, (float)a->line_thickness);
  288. } break;
  289. case NK_COMMAND_IMAGE: {
  290. const struct nk_command_image *i = (const struct nk_command_image *)cmd;
  291. al_draw_bitmap_region(i->img.handle.ptr, 0, 0, i->w, i->h, i->x, i->y, 0);
  292. } break;
  293. case NK_COMMAND_RECT_MULTI_COLOR:
  294. case NK_COMMAND_ARC_FILLED:
  295. default: break;
  296. }
  297. }
  298. nk_clear(&allegro5.ctx);
  299. }
  300. NK_API int
  301. nk_allegro5_handle_event(ALLEGRO_EVENT *ev)
  302. {
  303. struct nk_context *ctx = &allegro5.ctx;
  304. switch (ev->type) {
  305. case ALLEGRO_EVENT_DISPLAY_RESIZE: {
  306. allegro5.width = (unsigned int)ev->display.width;
  307. allegro5.height = (unsigned int)ev->display.height;
  308. al_acknowledge_resize(ev->display.source);
  309. return 1;
  310. } break;
  311. case ALLEGRO_EVENT_MOUSE_AXES: {
  312. nk_input_motion(ctx, ev->mouse.x, ev->mouse.y);
  313. if (ev->mouse.dz != 0) {
  314. nk_input_scroll(ctx, nk_vec2(0,(float)ev->mouse.dz / al_get_mouse_wheel_precision()));
  315. }
  316. return 1;
  317. } break;
  318. case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
  319. case ALLEGRO_EVENT_MOUSE_BUTTON_UP: {
  320. int button = NK_BUTTON_LEFT;
  321. if (ev->mouse.button == 2) {
  322. button = NK_BUTTON_RIGHT;
  323. }
  324. else if (ev->mouse.button == 3) {
  325. button = NK_BUTTON_MIDDLE;
  326. }
  327. nk_input_button(ctx, button, ev->mouse.x, ev->mouse.y, ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN);
  328. return 1;
  329. } break;
  330. /* This essentially converts touch events to mouse events */
  331. case ALLEGRO_EVENT_TOUCH_BEGIN:
  332. case ALLEGRO_EVENT_TOUCH_END: {
  333. /* We only acknowledge one touch at a time. Otherwise, each touch
  334. would be manipulating multiple nuklear elements, as if there
  335. were multiple mouse cursors */
  336. if (allegro5.is_touch_down && allegro5.touch_down_id != ev->touch.id) {
  337. return 0;
  338. }
  339. if (ev->type == ALLEGRO_EVENT_TOUCH_BEGIN) {
  340. allegro5.is_touch_down = 1;
  341. allegro5.touch_down_id = ev->touch.id;
  342. /* FIXME: This is a hack to properly simulate
  343. touches as a mouse with nuklear. If you instantly jump
  344. from one place to another without an nk_input_end(), it
  345. confuses the nuklear state. nuklear expects smooth mouse
  346. movements, which is unlike a touch screen */
  347. nk_input_motion(ctx, (int)ev->touch.x, (int)ev->touch.y);
  348. nk_input_end(ctx);
  349. nk_input_begin(ctx);
  350. }
  351. else {
  352. allegro5.is_touch_down = 0;
  353. allegro5.touch_down_id = -1;
  354. }
  355. nk_input_button(ctx, NK_BUTTON_LEFT, (int)ev->touch.x, (int)ev->touch.y, ev->type == ALLEGRO_EVENT_TOUCH_BEGIN);
  356. return 1;
  357. } break;
  358. case ALLEGRO_EVENT_TOUCH_MOVE: {
  359. /* Only acknowledge movements of a single touch, we are
  360. simulating a mouse cursor */
  361. if (!allegro5.is_touch_down || allegro5.touch_down_id != ev->touch.id) {
  362. return 0;
  363. }
  364. nk_input_motion(ctx, (int)ev->touch.x, (int)ev->touch.y);
  365. return 1;
  366. } break;
  367. case ALLEGRO_EVENT_KEY_DOWN:
  368. case ALLEGRO_EVENT_KEY_UP: {
  369. int kc = ev->keyboard.keycode;
  370. int down = ev->type == ALLEGRO_EVENT_KEY_DOWN;
  371. if (kc == ALLEGRO_KEY_LSHIFT || kc == ALLEGRO_KEY_RSHIFT) nk_input_key(ctx, NK_KEY_SHIFT, down);
  372. else if (kc == ALLEGRO_KEY_DELETE) nk_input_key(ctx, NK_KEY_DEL, down);
  373. else if (kc == ALLEGRO_KEY_ENTER) nk_input_key(ctx, NK_KEY_ENTER, down);
  374. else if (kc == ALLEGRO_KEY_TAB) nk_input_key(ctx, NK_KEY_TAB, down);
  375. else if (kc == ALLEGRO_KEY_LEFT) nk_input_key(ctx, NK_KEY_LEFT, down);
  376. else if (kc == ALLEGRO_KEY_RIGHT) nk_input_key(ctx, NK_KEY_RIGHT, down);
  377. else if (kc == ALLEGRO_KEY_UP) nk_input_key(ctx, NK_KEY_UP, down);
  378. else if (kc == ALLEGRO_KEY_DOWN) nk_input_key(ctx, NK_KEY_DOWN, down);
  379. else if (kc == ALLEGRO_KEY_BACKSPACE) nk_input_key(ctx, NK_KEY_BACKSPACE, down);
  380. else if (kc == ALLEGRO_KEY_ESCAPE) nk_input_key(ctx, NK_KEY_TEXT_RESET_MODE, down);
  381. else if (kc == ALLEGRO_KEY_PGUP) nk_input_key(ctx, NK_KEY_SCROLL_UP, down);
  382. else if (kc == ALLEGRO_KEY_PGDN) nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down);
  383. else if (kc == ALLEGRO_KEY_HOME) {
  384. nk_input_key(ctx, NK_KEY_TEXT_START, down);
  385. nk_input_key(ctx, NK_KEY_SCROLL_START, down);
  386. } else if (kc == ALLEGRO_KEY_END) {
  387. nk_input_key(ctx, NK_KEY_TEXT_END, down);
  388. nk_input_key(ctx, NK_KEY_SCROLL_END, down);
  389. }
  390. return 1;
  391. } break;
  392. case ALLEGRO_EVENT_KEY_CHAR: {
  393. int kc = ev->keyboard.keycode;
  394. int control_mask = (ev->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL) ||
  395. (ev->keyboard.modifiers & ALLEGRO_KEYMOD_COMMAND);
  396. if (kc == ALLEGRO_KEY_C && control_mask) {
  397. nk_input_key(ctx, NK_KEY_COPY, 1);
  398. } else if (kc == ALLEGRO_KEY_V && control_mask) {
  399. nk_input_key(ctx, NK_KEY_PASTE, 1);
  400. } else if (kc == ALLEGRO_KEY_X && control_mask) {
  401. nk_input_key(ctx, NK_KEY_CUT, 1);
  402. } else if (kc == ALLEGRO_KEY_Z && control_mask) {
  403. nk_input_key(ctx, NK_KEY_TEXT_UNDO, 1);
  404. } else if (kc == ALLEGRO_KEY_R && control_mask) {
  405. nk_input_key(ctx, NK_KEY_TEXT_REDO, 1);
  406. } else if (kc == ALLEGRO_KEY_A && control_mask) {
  407. nk_input_key(ctx, NK_KEY_TEXT_SELECT_ALL, 1);
  408. } else {
  409. if (kc != ALLEGRO_KEY_BACKSPACE &&
  410. kc != ALLEGRO_KEY_LEFT &&
  411. kc != ALLEGRO_KEY_RIGHT &&
  412. kc != ALLEGRO_KEY_UP &&
  413. kc != ALLEGRO_KEY_DOWN &&
  414. kc != ALLEGRO_KEY_HOME &&
  415. kc != ALLEGRO_KEY_DELETE &&
  416. kc != ALLEGRO_KEY_ENTER &&
  417. kc != ALLEGRO_KEY_END &&
  418. kc != ALLEGRO_KEY_ESCAPE &&
  419. kc != ALLEGRO_KEY_PGDN &&
  420. kc != ALLEGRO_KEY_PGUP) {
  421. nk_input_unicode(ctx, ev->keyboard.unichar);
  422. }
  423. }
  424. return 1;
  425. } break;
  426. default: return 0; break;
  427. }
  428. }
  429. NK_INTERN void
  430. nk_allegro5_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
  431. {
  432. char *text = al_get_clipboard_text(allegro5.dsp);
  433. if (text) nk_textedit_paste(edit, text, nk_strlen(text));
  434. (void)usr;
  435. al_free(text);
  436. }
  437. NK_INTERN void
  438. nk_allegro5_clipboard_copy(nk_handle usr, const char *text, int len)
  439. {
  440. char *str = 0;
  441. (void)usr;
  442. if (!len) return;
  443. str = (char*)malloc((size_t)len+1);
  444. if (!str) return;
  445. memcpy(str, text, (size_t)len);
  446. str[len] = '\0';
  447. al_set_clipboard_text(allegro5.dsp, str);
  448. free(str);
  449. }
  450. NK_API struct nk_context*
  451. nk_allegro5_init(NkAllegro5Font *allegro5font, ALLEGRO_DISPLAY *dsp,
  452. unsigned int width, unsigned int height)
  453. {
  454. struct nk_user_font *font;
  455. if (!al_init_primitives_addon()) {
  456. fprintf(stdout, "Unable to initialize required allegro5 primitives addon\n");
  457. exit(1);
  458. }
  459. font = &allegro5font->nk;
  460. allegro5.dsp = dsp;
  461. allegro5.width = width;
  462. allegro5.height = height;
  463. allegro5.is_touch_down = 0;
  464. allegro5.touch_down_id = -1;
  465. nk_init_default(&allegro5.ctx, font);
  466. allegro5.ctx.clip.copy = nk_allegro5_clipboard_copy;
  467. allegro5.ctx.clip.paste = nk_allegro5_clipboard_paste;
  468. allegro5.ctx.clip.userdata = nk_handle_ptr(0);
  469. return &allegro5.ctx;
  470. }
  471. NK_API
  472. void nk_allegro5_shutdown(void)
  473. {
  474. nk_free(&allegro5.ctx);
  475. memset(&allegro5, 0, sizeof(allegro5));
  476. }
  477. #endif /* NK_ALLEGRO5_IMPLEMENTATION */