nuklear_glfw3.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  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_GLFW_GL3_H_
  14. #define NK_GLFW_GL3_H_
  15. #include <GLFW/glfw3.h>
  16. enum nk_glfw_init_state {
  17. NK_GLFW3_DEFAULT = 0,
  18. NK_GLFW3_INSTALL_CALLBACKS
  19. };
  20. NK_API struct nk_context* nk_glfw3_init(GLFWwindow* win, enum nk_glfw_init_state);
  21. NK_API void nk_glfw3_shutdown(void);
  22. NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas** atlas);
  23. NK_API void nk_glfw3_font_stash_end(void);
  24. NK_API void nk_glfw3_new_frame(void);
  25. NK_API void nk_glfw3_render(enum nk_anti_aliasing, int max_vertex_buffer, int max_element_buffer);
  26. NK_API void nk_glfw3_device_destroy(void);
  27. NK_API void nk_glfw3_device_create(void);
  28. NK_API void nk_glfw3_char_callback(GLFWwindow* win, unsigned int codepoint);
  29. NK_API void nk_gflw3_scroll_callback(GLFWwindow* win, double xoff, double yoff);
  30. NK_API void nk_glfw3_mouse_button_callback(GLFWwindow* win, int button, int action, int mods);
  31. #endif
  32. /*
  33. * ==============================================================
  34. *
  35. * IMPLEMENTATION
  36. *
  37. * ===============================================================
  38. */
  39. #ifdef NK_GLFW_GL3_IMPLEMENTATION
  40. #ifndef NK_GLFW_TEXT_MAX
  41. #define NK_GLFW_TEXT_MAX 256
  42. #endif
  43. #ifndef NK_GLFW_DOUBLE_CLICK_LO
  44. #define NK_GLFW_DOUBLE_CLICK_LO 0.02
  45. #endif
  46. #ifndef NK_GLFW_DOUBLE_CLICK_HI
  47. #define NK_GLFW_DOUBLE_CLICK_HI 0.2
  48. #endif
  49. struct nk_glfw_device {
  50. struct nk_buffer cmds;
  51. struct nk_draw_null_texture null;
  52. GLuint vbo, vao, ebo;
  53. GLuint prog;
  54. GLuint vert_shdr;
  55. GLuint frag_shdr;
  56. GLint attrib_pos;
  57. GLint attrib_uv;
  58. GLint attrib_col;
  59. GLint uniform_tex;
  60. GLint uniform_proj;
  61. GLuint font_tex;
  62. };
  63. struct nk_glfw_vertex {
  64. float position[2];
  65. float uv[2];
  66. nk_byte col[4];
  67. };
  68. static struct nk_glfw {
  69. GLFWwindow* win;
  70. int width, height;
  71. int display_width, display_height;
  72. struct nk_glfw_device ogl;
  73. struct nk_context ctx;
  74. struct nk_font_atlas atlas;
  75. struct nk_vec2 fb_scale;
  76. unsigned int text[NK_GLFW_TEXT_MAX];
  77. int text_len;
  78. struct nk_vec2 scroll;
  79. double last_button_click;
  80. int is_double_click_down;
  81. struct nk_vec2 double_click_pos;
  82. } glfw;
  83. #ifdef __APPLE__
  84. #define NK_SHADER_VERSION "#version 150\n"
  85. #else
  86. #define NK_SHADER_VERSION "#version 300 es\n"
  87. #endif
  88. NK_API void
  89. nk_glfw3_device_create(void)
  90. {
  91. GLint status;
  92. static const GLchar* vertex_shader =
  93. NK_SHADER_VERSION
  94. "uniform mat4 ProjMtx;\n"
  95. "in vec2 Position;\n"
  96. "in vec2 TexCoord;\n"
  97. "in vec4 Color;\n"
  98. "out vec2 Frag_UV;\n"
  99. "out vec4 Frag_Color;\n"
  100. "void main() {\n"
  101. " Frag_UV = TexCoord;\n"
  102. " Frag_Color = Color;\n"
  103. " gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n"
  104. "}\n";
  105. static const GLchar* fragment_shader =
  106. NK_SHADER_VERSION
  107. "precision mediump float;\n"
  108. "uniform sampler2D Texture;\n"
  109. "in vec2 Frag_UV;\n"
  110. "in vec4 Frag_Color;\n"
  111. "out vec4 Out_Color;\n"
  112. "void main(){\n"
  113. " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
  114. "}\n";
  115. struct nk_glfw_device* dev = &glfw.ogl;
  116. nk_buffer_init_default(&dev->cmds);
  117. dev->prog = glCreateProgram();
  118. dev->vert_shdr = glCreateShader(GL_VERTEX_SHADER);
  119. dev->frag_shdr = glCreateShader(GL_FRAGMENT_SHADER);
  120. glShaderSource(dev->vert_shdr, 1, &vertex_shader, 0);
  121. glShaderSource(dev->frag_shdr, 1, &fragment_shader, 0);
  122. glCompileShader(dev->vert_shdr);
  123. glCompileShader(dev->frag_shdr);
  124. glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status);
  125. assert(status == GL_TRUE);
  126. glGetShaderiv(dev->frag_shdr, GL_COMPILE_STATUS, &status);
  127. assert(status == GL_TRUE);
  128. glAttachShader(dev->prog, dev->vert_shdr);
  129. glAttachShader(dev->prog, dev->frag_shdr);
  130. glLinkProgram(dev->prog);
  131. glGetProgramiv(dev->prog, GL_LINK_STATUS, &status);
  132. assert(status == GL_TRUE);
  133. dev->uniform_tex = glGetUniformLocation(dev->prog, "Texture");
  134. dev->uniform_proj = glGetUniformLocation(dev->prog, "ProjMtx");
  135. dev->attrib_pos = glGetAttribLocation(dev->prog, "Position");
  136. dev->attrib_uv = glGetAttribLocation(dev->prog, "TexCoord");
  137. dev->attrib_col = glGetAttribLocation(dev->prog, "Color");
  138. {
  139. /* buffer setup */
  140. GLsizei vs = sizeof(struct nk_glfw_vertex);
  141. size_t vp = offsetof(struct nk_glfw_vertex, position);
  142. size_t vt = offsetof(struct nk_glfw_vertex, uv);
  143. size_t vc = offsetof(struct nk_glfw_vertex, col);
  144. glGenBuffers(1, &dev->vbo);
  145. glGenBuffers(1, &dev->ebo);
  146. glGenVertexArrays(1, &dev->vao);
  147. glBindVertexArray(dev->vao);
  148. glBindBuffer(GL_ARRAY_BUFFER, dev->vbo);
  149. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo);
  150. glEnableVertexAttribArray((GLuint)dev->attrib_pos);
  151. glEnableVertexAttribArray((GLuint)dev->attrib_uv);
  152. glEnableVertexAttribArray((GLuint)dev->attrib_col);
  153. glVertexAttribPointer((GLuint)dev->attrib_pos, 2, GL_FLOAT, GL_FALSE, vs, (void*)vp);
  154. glVertexAttribPointer((GLuint)dev->attrib_uv, 2, GL_FLOAT, GL_FALSE, vs, (void*)vt);
  155. glVertexAttribPointer((GLuint)dev->attrib_col, 4, GL_UNSIGNED_BYTE, GL_TRUE, vs, (void*)vc);
  156. }
  157. glBindTexture(GL_TEXTURE_2D, 0);
  158. glBindBuffer(GL_ARRAY_BUFFER, 0);
  159. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  160. glBindVertexArray(0);
  161. }
  162. NK_INTERN void
  163. nk_glfw3_device_upload_atlas(const void* image, int width, int height)
  164. {
  165. struct nk_glfw_device* dev = &glfw.ogl;
  166. glGenTextures(1, &dev->font_tex);
  167. glBindTexture(GL_TEXTURE_2D, dev->font_tex);
  168. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  169. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  170. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0,
  171. GL_RGBA, GL_UNSIGNED_BYTE, image);
  172. }
  173. NK_API void
  174. nk_glfw3_device_destroy(void)
  175. {
  176. struct nk_glfw_device* dev = &glfw.ogl;
  177. glDetachShader(dev->prog, dev->vert_shdr);
  178. glDetachShader(dev->prog, dev->frag_shdr);
  179. glDeleteShader(dev->vert_shdr);
  180. glDeleteShader(dev->frag_shdr);
  181. glDeleteProgram(dev->prog);
  182. glDeleteTextures(1, &dev->font_tex);
  183. glDeleteBuffers(1, &dev->vbo);
  184. glDeleteBuffers(1, &dev->ebo);
  185. nk_buffer_free(&dev->cmds);
  186. }
  187. NK_API void
  188. nk_glfw3_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer)
  189. {
  190. struct nk_glfw_device* dev = &glfw.ogl;
  191. struct nk_buffer vbuf, ebuf;
  192. GLfloat ortho[4][4] = {
  193. {2.0f, 0.0f, 0.0f, 0.0f},
  194. {0.0f,-2.0f, 0.0f, 0.0f},
  195. {0.0f, 0.0f,-1.0f, 0.0f},
  196. {-1.0f,1.0f, 0.0f, 1.0f},
  197. };
  198. ortho[0][0] /= (GLfloat)glfw.width;
  199. ortho[1][1] /= (GLfloat)glfw.height;
  200. /* setup global state */
  201. glEnable(GL_BLEND);
  202. glBlendEquation(GL_FUNC_ADD);
  203. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  204. glDisable(GL_CULL_FACE);
  205. glDisable(GL_DEPTH_TEST);
  206. glEnable(GL_SCISSOR_TEST);
  207. glActiveTexture(GL_TEXTURE0);
  208. /* setup program */
  209. glUseProgram(dev->prog);
  210. glUniform1i(dev->uniform_tex, 0);
  211. glUniformMatrix4fv(dev->uniform_proj, 1, GL_FALSE, &ortho[0][0]);
  212. glViewport(0, 0, (GLsizei)glfw.display_width, (GLsizei)glfw.display_height);
  213. {
  214. /* convert from command queue into draw list and draw to screen */
  215. const struct nk_draw_command* cmd;
  216. void* vertices, * elements;
  217. const nk_draw_index* offset = NULL;
  218. /* allocate vertex and element buffer */
  219. glBindVertexArray(dev->vao);
  220. glBindBuffer(GL_ARRAY_BUFFER, dev->vbo);
  221. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo);
  222. glBufferData(GL_ARRAY_BUFFER, max_vertex_buffer, NULL, GL_STREAM_DRAW);
  223. glBufferData(GL_ELEMENT_ARRAY_BUFFER, max_element_buffer, NULL, GL_STREAM_DRAW);
  224. /* load draw vertices & elements directly into vertex + element buffer */
  225. vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
  226. elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
  227. {
  228. /* fill convert configuration */
  229. struct nk_convert_config config;
  230. static const struct nk_draw_vertex_layout_element vertex_layout[] = {
  231. {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, position)},
  232. {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, uv)},
  233. {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_glfw_vertex, col)},
  234. {NK_VERTEX_LAYOUT_END}
  235. };
  236. NK_MEMSET(&config, 0, sizeof(config));
  237. config.vertex_layout = vertex_layout;
  238. config.vertex_size = sizeof(struct nk_glfw_vertex);
  239. config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex);
  240. //config.null = dev->null;
  241. config.circle_segment_count = 22;
  242. config.curve_segment_count = 22;
  243. config.arc_segment_count = 22;
  244. config.global_alpha = 1.0f;
  245. config.shape_AA = AA;
  246. config.line_AA = AA;
  247. /* setup buffers to load vertices and elements */
  248. nk_buffer_init_fixed(&vbuf, vertices, (size_t)max_vertex_buffer);
  249. nk_buffer_init_fixed(&ebuf, elements, (size_t)max_element_buffer);
  250. nk_convert(&glfw.ctx, &dev->cmds, &vbuf, &ebuf, &config);
  251. }
  252. glUnmapBuffer(GL_ARRAY_BUFFER);
  253. glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
  254. /* iterate over and execute each draw command */
  255. nk_draw_foreach(cmd, &glfw.ctx, &dev->cmds)
  256. {
  257. if (!cmd->elem_count) continue;
  258. glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
  259. glScissor(
  260. (GLint)(cmd->clip_rect.x * glfw.fb_scale.x),
  261. (GLint)((glfw.height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * glfw.fb_scale.y),
  262. (GLint)(cmd->clip_rect.w * glfw.fb_scale.x),
  263. (GLint)(cmd->clip_rect.h * glfw.fb_scale.y));
  264. glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
  265. offset += cmd->elem_count;
  266. }
  267. nk_clear(&glfw.ctx);
  268. }
  269. /* default OpenGL state */
  270. glUseProgram(0);
  271. glBindBuffer(GL_ARRAY_BUFFER, 0);
  272. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  273. glBindVertexArray(0);
  274. glDisable(GL_BLEND);
  275. glDisable(GL_SCISSOR_TEST);
  276. }
  277. NK_API void
  278. nk_glfw3_char_callback(GLFWwindow* win, unsigned int codepoint)
  279. {
  280. (void)win;
  281. if (glfw.text_len < NK_GLFW_TEXT_MAX)
  282. glfw.text[glfw.text_len++] = codepoint;
  283. }
  284. NK_API void
  285. nk_gflw3_scroll_callback(GLFWwindow* win, double xoff, double yoff)
  286. {
  287. (void)win; (void)xoff;
  288. glfw.scroll.x += (float)xoff;
  289. glfw.scroll.y += (float)yoff;
  290. }
  291. NK_API void
  292. nk_glfw3_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
  293. {
  294. double x, y;
  295. if (button != GLFW_MOUSE_BUTTON_LEFT) return;
  296. glfwGetCursorPos(window, &x, &y);
  297. if (action == GLFW_PRESS) {
  298. double dt = glfwGetTime() - glfw.last_button_click;
  299. if (dt > NK_GLFW_DOUBLE_CLICK_LO && dt < NK_GLFW_DOUBLE_CLICK_HI) {
  300. glfw.is_double_click_down = nk_true;
  301. glfw.double_click_pos = nk_vec2((float)x, (float)y);
  302. }
  303. glfw.last_button_click = glfwGetTime();
  304. }
  305. else glfw.is_double_click_down = nk_false;
  306. }
  307. NK_INTERN void
  308. nk_glfw3_clipboard_paste(nk_handle usr, struct nk_text_edit* edit)
  309. {
  310. const char* text = glfwGetClipboardString(glfw.win);
  311. if (text) nk_textedit_paste(edit, text, nk_strlen(text));
  312. (void)usr;
  313. }
  314. NK_INTERN void
  315. nk_glfw3_clipboard_copy(nk_handle usr, const char* text, int len)
  316. {
  317. char* str = 0;
  318. (void)usr;
  319. if (!len) return;
  320. str = (char*)malloc((size_t)len + 1);
  321. if (!str) return;
  322. memcpy(str, text, (size_t)len);
  323. str[len] = '\0';
  324. glfwSetClipboardString(glfw.win, str);
  325. free(str);
  326. }
  327. NK_API struct nk_context*
  328. nk_glfw3_init(GLFWwindow* win, enum nk_glfw_init_state init_state)
  329. {
  330. glfw.win = win;
  331. if (init_state == NK_GLFW3_INSTALL_CALLBACKS) {
  332. glfwSetScrollCallback(win, nk_gflw3_scroll_callback);
  333. glfwSetCharCallback(win, nk_glfw3_char_callback);
  334. glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback);
  335. }
  336. nk_init_default(&glfw.ctx, 0);
  337. glfw.ctx.clip.copy = nk_glfw3_clipboard_copy;
  338. glfw.ctx.clip.paste = nk_glfw3_clipboard_paste;
  339. glfw.ctx.clip.userdata = nk_handle_ptr(0);
  340. glfw.last_button_click = 0;
  341. nk_glfw3_device_create();
  342. glfw.is_double_click_down = nk_false;
  343. glfw.double_click_pos = nk_vec2(0, 0);
  344. return &glfw.ctx;
  345. }
  346. NK_API void
  347. nk_glfw3_font_stash_begin(struct nk_font_atlas** atlas)
  348. {
  349. nk_font_atlas_init_default(&glfw.atlas);
  350. nk_font_atlas_begin(&glfw.atlas);
  351. *atlas = &glfw.atlas;
  352. }
  353. NK_API void
  354. nk_glfw3_font_stash_end(void)
  355. {
  356. const void* image; int w, h;
  357. image = nk_font_atlas_bake(&glfw.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
  358. nk_glfw3_device_upload_atlas(image, w, h);
  359. nk_font_atlas_end(&glfw.atlas, nk_handle_id((int)glfw.ogl.font_tex), &glfw.ogl.null);
  360. if (glfw.atlas.default_font)
  361. nk_style_set_font(&glfw.ctx, &glfw.atlas.default_font->handle);
  362. }
  363. NK_API void
  364. nk_glfw3_new_frame(void)
  365. {
  366. int i;
  367. double x, y;
  368. struct nk_context* ctx = &glfw.ctx;
  369. struct GLFWwindow* win = glfw.win;
  370. glfwGetWindowSize(win, &glfw.width, &glfw.height);
  371. glfwGetFramebufferSize(win, &glfw.display_width, &glfw.display_height);
  372. glfw.fb_scale.x = (float)glfw.display_width / (float)glfw.width;
  373. glfw.fb_scale.y = (float)glfw.display_height / (float)glfw.height;
  374. nk_input_begin(ctx);
  375. for (i = 0; i < glfw.text_len; ++i)
  376. nk_input_unicode(ctx, glfw.text[i]);
  377. #ifdef NK_GLFW_GL3_MOUSE_GRABBING
  378. /* optional grabbing behavior */
  379. if (ctx->input.mouse.grab)
  380. glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
  381. else if (ctx->input.mouse.ungrab)
  382. glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
  383. #endif
  384. nk_input_key(ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS);
  385. nk_input_key(ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS);
  386. nk_input_key(ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS);
  387. nk_input_key(ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS);
  388. nk_input_key(ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS);
  389. nk_input_key(ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS);
  390. nk_input_key(ctx, NK_KEY_TEXT_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
  391. nk_input_key(ctx, NK_KEY_TEXT_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
  392. nk_input_key(ctx, NK_KEY_SCROLL_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
  393. nk_input_key(ctx, NK_KEY_SCROLL_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
  394. nk_input_key(ctx, NK_KEY_SCROLL_DOWN, glfwGetKey(win, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS);
  395. nk_input_key(ctx, NK_KEY_SCROLL_UP, glfwGetKey(win, GLFW_KEY_PAGE_UP) == GLFW_PRESS);
  396. nk_input_key(ctx, NK_KEY_SHIFT, glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS ||
  397. glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS);
  398. if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS ||
  399. glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) {
  400. nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS);
  401. nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_V) == GLFW_PRESS);
  402. nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS);
  403. nk_input_key(ctx, NK_KEY_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == GLFW_PRESS);
  404. nk_input_key(ctx, NK_KEY_TEXT_REDO, glfwGetKey(win, GLFW_KEY_R) == GLFW_PRESS);
  405. nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
  406. nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
  407. nk_input_key(ctx, NK_KEY_TEXT_LINE_START, glfwGetKey(win, GLFW_KEY_B) == GLFW_PRESS);
  408. nk_input_key(ctx, NK_KEY_TEXT_LINE_END, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS);
  409. }
  410. else {
  411. nk_input_key(ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
  412. nk_input_key(ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
  413. nk_input_key(ctx, NK_KEY_COPY, 0);
  414. nk_input_key(ctx, NK_KEY_PASTE, 0);
  415. nk_input_key(ctx, NK_KEY_CUT, 0);
  416. nk_input_key(ctx, NK_KEY_SHIFT, 0);
  417. }
  418. glfwGetCursorPos(win, &x, &y);
  419. nk_input_motion(ctx, (int)x, (int)y);
  420. #ifdef NK_GLFW_GL3_MOUSE_GRABBING
  421. if (ctx->input.mouse.grabbed) {
  422. glfwSetCursorPos(glfw.win, ctx->input.mouse.prev.x, ctx->input.mouse.prev.y);
  423. ctx->input.mouse.pos.x = ctx->input.mouse.prev.x;
  424. ctx->input.mouse.pos.y = ctx->input.mouse.prev.y;
  425. }
  426. #endif
  427. nk_input_button(ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS);
  428. nk_input_button(ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS);
  429. nk_input_button(ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS);
  430. nk_input_button(ctx, NK_BUTTON_DOUBLE, (int)glfw.double_click_pos.x, (int)glfw.double_click_pos.y, glfw.is_double_click_down);
  431. nk_input_scroll(ctx, glfw.scroll);
  432. nk_input_end(&glfw.ctx);
  433. glfw.text_len = 0;
  434. glfw.scroll = nk_vec2(0, 0);
  435. }
  436. NK_API
  437. void nk_glfw3_shutdown(void)
  438. {
  439. nk_font_atlas_clear(&glfw.atlas);
  440. nk_free(&glfw.ctx);
  441. nk_glfw3_device_destroy();
  442. memset(&glfw, 0, sizeof(glfw));
  443. }
  444. #endif