window.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. //========================================================================
  2. // Window properties test
  3. // Copyright (c) Camilla Löwy <[email protected]>
  4. //
  5. // This software is provided 'as-is', without any express or implied
  6. // warranty. In no event will the authors be held liable for any damages
  7. // arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,
  10. // including commercial applications, and to alter it and redistribute it
  11. // freely, subject to the following restrictions:
  12. //
  13. // 1. The origin of this software must not be misrepresented; you must not
  14. // claim that you wrote the original software. If you use this software
  15. // in a product, an acknowledgment in the product documentation would
  16. // be appreciated but is not required.
  17. //
  18. // 2. Altered source versions must be plainly marked as such, and must not
  19. // be misrepresented as being the original software.
  20. //
  21. // 3. This notice may not be removed or altered from any source
  22. // distribution.
  23. //
  24. //========================================================================
  25. #define GLAD_GL_IMPLEMENTATION
  26. #include <glad/gl.h>
  27. #define GLFW_INCLUDE_NONE
  28. #include <GLFW/glfw3.h>
  29. #include <stdarg.h>
  30. #define NK_IMPLEMENTATION
  31. #define NK_INCLUDE_FIXED_TYPES
  32. #define NK_INCLUDE_FONT_BAKING
  33. #define NK_INCLUDE_DEFAULT_FONT
  34. #define NK_INCLUDE_DEFAULT_ALLOCATOR
  35. #define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
  36. #define NK_INCLUDE_STANDARD_VARARGS
  37. #define NK_BUTTON_TRIGGER_ON_RELEASE
  38. #include <nuklear.h>
  39. #define NK_GLFW_GL2_IMPLEMENTATION
  40. #include <nuklear_glfw_gl2.h>
  41. #include <stdbool.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <limits.h>
  45. int main(int argc, char** argv)
  46. {
  47. int windowed_x, windowed_y, windowed_width, windowed_height;
  48. int last_xpos = INT_MIN, last_ypos = INT_MIN;
  49. int last_width = INT_MIN, last_height = INT_MIN;
  50. int limit_aspect_ratio = false, aspect_numer = 1, aspect_denom = 1;
  51. int limit_min_size = false, min_width = 400, min_height = 400;
  52. int limit_max_size = false, max_width = 400, max_height = 400;
  53. char width_buffer[10] = "", height_buffer[10] = "";
  54. char xpos_buffer[10] = "", ypos_buffer[10] = "";
  55. char numer_buffer[10] = "", denom_buffer[10] = "";
  56. char min_width_buffer[10] = "", min_height_buffer[10] = "";
  57. char max_width_buffer[10] = "", max_height_buffer[10] = "";
  58. int may_close = true;
  59. if (!glfwInit())
  60. exit(EXIT_FAILURE);
  61. glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
  62. glfwWindowHint(GLFW_WIN32_KEYBOARD_MENU, GLFW_TRUE);
  63. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
  64. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
  65. GLFWwindow* window = glfwCreateWindow(600, 600, "Window Features", NULL, NULL);
  66. if (!window)
  67. {
  68. glfwTerminate();
  69. exit(EXIT_FAILURE);
  70. }
  71. glfwMakeContextCurrent(window);
  72. gladLoadGL(glfwGetProcAddress);
  73. glfwSwapInterval(0);
  74. bool position_supported = true;
  75. glfwGetError(NULL);
  76. glfwGetWindowPos(window, &last_xpos, &last_ypos);
  77. sprintf(xpos_buffer, "%i", last_xpos);
  78. sprintf(ypos_buffer, "%i", last_ypos);
  79. if (glfwGetError(NULL) == GLFW_FEATURE_UNAVAILABLE)
  80. position_supported = false;
  81. glfwGetWindowSize(window, &last_width, &last_height);
  82. sprintf(width_buffer, "%i", last_width);
  83. sprintf(height_buffer, "%i", last_height);
  84. sprintf(numer_buffer, "%i", aspect_numer);
  85. sprintf(denom_buffer, "%i", aspect_denom);
  86. sprintf(min_width_buffer, "%i", min_width);
  87. sprintf(min_height_buffer, "%i", min_height);
  88. sprintf(max_width_buffer, "%i", max_width);
  89. sprintf(max_height_buffer, "%i", max_height);
  90. struct nk_context* nk = nk_glfw3_init(window, NK_GLFW3_INSTALL_CALLBACKS);
  91. struct nk_font_atlas* atlas;
  92. nk_glfw3_font_stash_begin(&atlas);
  93. nk_glfw3_font_stash_end();
  94. while (!(may_close && glfwWindowShouldClose(window)))
  95. {
  96. int width, height;
  97. glfwGetWindowSize(window, &width, &height);
  98. struct nk_rect area = nk_rect(0.f, 0.f, (float) width, (float) height);
  99. nk_window_set_bounds(nk, "main", area);
  100. nk_glfw3_new_frame();
  101. if (nk_begin(nk, "main", area, 0))
  102. {
  103. nk_layout_row_dynamic(nk, 30, 4);
  104. if (nk_button_label(nk, "Toggle Fullscreen"))
  105. {
  106. if (glfwGetWindowMonitor(window))
  107. {
  108. glfwSetWindowMonitor(window, NULL,
  109. windowed_x, windowed_y,
  110. windowed_width, windowed_height, 0);
  111. }
  112. else
  113. {
  114. GLFWmonitor* monitor = glfwGetPrimaryMonitor();
  115. const GLFWvidmode* mode = glfwGetVideoMode(monitor);
  116. glfwGetWindowPos(window, &windowed_x, &windowed_y);
  117. glfwGetWindowSize(window, &windowed_width, &windowed_height);
  118. glfwSetWindowMonitor(window, monitor,
  119. 0, 0, mode->width, mode->height,
  120. mode->refreshRate);
  121. }
  122. }
  123. if (nk_button_label(nk, "Maximize"))
  124. glfwMaximizeWindow(window);
  125. if (nk_button_label(nk, "Iconify"))
  126. glfwIconifyWindow(window);
  127. if (nk_button_label(nk, "Restore"))
  128. glfwRestoreWindow(window);
  129. nk_layout_row_dynamic(nk, 30, 1);
  130. if (glfwGetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH))
  131. {
  132. nk_label(nk, "Press H to disable mouse passthrough", NK_TEXT_CENTERED);
  133. if (glfwGetKey(window, GLFW_KEY_H))
  134. glfwSetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH, false);
  135. }
  136. nk_label(nk, "Press Enter in a text field to set value", NK_TEXT_CENTERED);
  137. nk_flags events;
  138. const nk_flags flags = NK_EDIT_FIELD |
  139. NK_EDIT_SIG_ENTER |
  140. NK_EDIT_GOTO_END_ON_ACTIVATE;
  141. if (position_supported)
  142. {
  143. int xpos, ypos;
  144. glfwGetWindowPos(window, &xpos, &ypos);
  145. nk_layout_row_dynamic(nk, 30, 3);
  146. nk_label(nk, "Position", NK_TEXT_LEFT);
  147. events = nk_edit_string_zero_terminated(nk, flags, xpos_buffer,
  148. sizeof(xpos_buffer),
  149. nk_filter_decimal);
  150. if (events & NK_EDIT_COMMITED)
  151. {
  152. xpos = atoi(xpos_buffer);
  153. glfwSetWindowPos(window, xpos, ypos);
  154. }
  155. else if (xpos != last_xpos || (events & NK_EDIT_DEACTIVATED))
  156. sprintf(xpos_buffer, "%i", xpos);
  157. events = nk_edit_string_zero_terminated(nk, flags, ypos_buffer,
  158. sizeof(ypos_buffer),
  159. nk_filter_decimal);
  160. if (events & NK_EDIT_COMMITED)
  161. {
  162. ypos = atoi(ypos_buffer);
  163. glfwSetWindowPos(window, xpos, ypos);
  164. }
  165. else if (ypos != last_ypos || (events & NK_EDIT_DEACTIVATED))
  166. sprintf(ypos_buffer, "%i", ypos);
  167. last_xpos = xpos;
  168. last_ypos = ypos;
  169. }
  170. else
  171. nk_label(nk, "Position not supported", NK_TEXT_LEFT);
  172. nk_layout_row_dynamic(nk, 30, 3);
  173. nk_label(nk, "Size", NK_TEXT_LEFT);
  174. events = nk_edit_string_zero_terminated(nk, flags, width_buffer,
  175. sizeof(width_buffer),
  176. nk_filter_decimal);
  177. if (events & NK_EDIT_COMMITED)
  178. {
  179. width = atoi(width_buffer);
  180. glfwSetWindowSize(window, width, height);
  181. }
  182. else if (width != last_width || (events & NK_EDIT_DEACTIVATED))
  183. sprintf(width_buffer, "%i", width);
  184. events = nk_edit_string_zero_terminated(nk, flags, height_buffer,
  185. sizeof(height_buffer),
  186. nk_filter_decimal);
  187. if (events & NK_EDIT_COMMITED)
  188. {
  189. height = atoi(height_buffer);
  190. glfwSetWindowSize(window, width, height);
  191. }
  192. else if (height != last_height || (events & NK_EDIT_DEACTIVATED))
  193. sprintf(height_buffer, "%i", height);
  194. last_width = width;
  195. last_height = height;
  196. bool update_ratio_limit = false;
  197. if (nk_checkbox_label(nk, "Aspect Ratio", &limit_aspect_ratio))
  198. update_ratio_limit = true;
  199. events = nk_edit_string_zero_terminated(nk, flags, numer_buffer,
  200. sizeof(numer_buffer),
  201. nk_filter_decimal);
  202. if (events & NK_EDIT_COMMITED)
  203. {
  204. aspect_numer = abs(atoi(numer_buffer));
  205. update_ratio_limit = true;
  206. }
  207. else if (events & NK_EDIT_DEACTIVATED)
  208. sprintf(numer_buffer, "%i", aspect_numer);
  209. events = nk_edit_string_zero_terminated(nk, flags, denom_buffer,
  210. sizeof(denom_buffer),
  211. nk_filter_decimal);
  212. if (events & NK_EDIT_COMMITED)
  213. {
  214. aspect_denom = abs(atoi(denom_buffer));
  215. update_ratio_limit = true;
  216. }
  217. else if (events & NK_EDIT_DEACTIVATED)
  218. sprintf(denom_buffer, "%i", aspect_denom);
  219. if (update_ratio_limit)
  220. {
  221. if (limit_aspect_ratio)
  222. glfwSetWindowAspectRatio(window, aspect_numer, aspect_denom);
  223. else
  224. glfwSetWindowAspectRatio(window, GLFW_DONT_CARE, GLFW_DONT_CARE);
  225. }
  226. bool update_size_limit = false;
  227. if (nk_checkbox_label(nk, "Minimum Size", &limit_min_size))
  228. update_size_limit = true;
  229. events = nk_edit_string_zero_terminated(nk, flags, min_width_buffer,
  230. sizeof(min_width_buffer),
  231. nk_filter_decimal);
  232. if (events & NK_EDIT_COMMITED)
  233. {
  234. min_width = abs(atoi(min_width_buffer));
  235. update_size_limit = true;
  236. }
  237. else if (events & NK_EDIT_DEACTIVATED)
  238. sprintf(min_width_buffer, "%i", min_width);
  239. events = nk_edit_string_zero_terminated(nk, flags, min_height_buffer,
  240. sizeof(min_height_buffer),
  241. nk_filter_decimal);
  242. if (events & NK_EDIT_COMMITED)
  243. {
  244. min_height = abs(atoi(min_height_buffer));
  245. update_size_limit = true;
  246. }
  247. else if (events & NK_EDIT_DEACTIVATED)
  248. sprintf(min_height_buffer, "%i", min_height);
  249. if (nk_checkbox_label(nk, "Maximum Size", &limit_max_size))
  250. update_size_limit = true;
  251. events = nk_edit_string_zero_terminated(nk, flags, max_width_buffer,
  252. sizeof(max_width_buffer),
  253. nk_filter_decimal);
  254. if (events & NK_EDIT_COMMITED)
  255. {
  256. max_width = abs(atoi(max_width_buffer));
  257. update_size_limit = true;
  258. }
  259. else if (events & NK_EDIT_DEACTIVATED)
  260. sprintf(max_width_buffer, "%i", max_width);
  261. events = nk_edit_string_zero_terminated(nk, flags, max_height_buffer,
  262. sizeof(max_height_buffer),
  263. nk_filter_decimal);
  264. if (events & NK_EDIT_COMMITED)
  265. {
  266. max_height = abs(atoi(max_height_buffer));
  267. update_size_limit = true;
  268. }
  269. else if (events & NK_EDIT_DEACTIVATED)
  270. sprintf(max_height_buffer, "%i", max_height);
  271. if (update_size_limit)
  272. {
  273. glfwSetWindowSizeLimits(window,
  274. limit_min_size ? min_width : GLFW_DONT_CARE,
  275. limit_min_size ? min_height : GLFW_DONT_CARE,
  276. limit_max_size ? max_width : GLFW_DONT_CARE,
  277. limit_max_size ? max_height : GLFW_DONT_CARE);
  278. }
  279. int fb_width, fb_height;
  280. glfwGetFramebufferSize(window, &fb_width, &fb_height);
  281. nk_label(nk, "Framebuffer Size", NK_TEXT_LEFT);
  282. nk_labelf(nk, NK_TEXT_LEFT, "%i", fb_width);
  283. nk_labelf(nk, NK_TEXT_LEFT, "%i", fb_height);
  284. float xscale, yscale;
  285. glfwGetWindowContentScale(window, &xscale, &yscale);
  286. nk_label(nk, "Content Scale", NK_TEXT_LEFT);
  287. nk_labelf(nk, NK_TEXT_LEFT, "%f", xscale);
  288. nk_labelf(nk, NK_TEXT_LEFT, "%f", yscale);
  289. nk_layout_row_begin(nk, NK_DYNAMIC, 30, 5);
  290. int frame_left, frame_top, frame_right, frame_bottom;
  291. glfwGetWindowFrameSize(window, &frame_left, &frame_top, &frame_right, &frame_bottom);
  292. nk_layout_row_push(nk, 1.f / 3.f);
  293. nk_label(nk, "Frame Size:", NK_TEXT_LEFT);
  294. nk_layout_row_push(nk, 1.f / 6.f);
  295. nk_labelf(nk, NK_TEXT_LEFT, "%i", frame_left);
  296. nk_layout_row_push(nk, 1.f / 6.f);
  297. nk_labelf(nk, NK_TEXT_LEFT, "%i", frame_top);
  298. nk_layout_row_push(nk, 1.f / 6.f);
  299. nk_labelf(nk, NK_TEXT_LEFT, "%i", frame_right);
  300. nk_layout_row_push(nk, 1.f / 6.f);
  301. nk_labelf(nk, NK_TEXT_LEFT, "%i", frame_bottom);
  302. nk_layout_row_end(nk);
  303. nk_layout_row_begin(nk, NK_DYNAMIC, 30, 2);
  304. float opacity = glfwGetWindowOpacity(window);
  305. nk_layout_row_push(nk, 1.f / 3.f);
  306. nk_labelf(nk, NK_TEXT_LEFT, "Opacity: %0.3f", opacity);
  307. nk_layout_row_push(nk, 2.f / 3.f);
  308. if (nk_slider_float(nk, 0.f, &opacity, 1.f, 0.001f))
  309. glfwSetWindowOpacity(window, opacity);
  310. nk_layout_row_end(nk);
  311. nk_layout_row_begin(nk, NK_DYNAMIC, 30, 2);
  312. int should_close = glfwWindowShouldClose(window);
  313. nk_layout_row_push(nk, 1.f / 3.f);
  314. if (nk_checkbox_label(nk, "Should Close", &should_close))
  315. glfwSetWindowShouldClose(window, should_close);
  316. nk_layout_row_push(nk, 2.f / 3.f);
  317. nk_checkbox_label(nk, "May Close", &may_close);
  318. nk_layout_row_end(nk);
  319. nk_layout_row_dynamic(nk, 30, 1);
  320. nk_label(nk, "Attributes", NK_TEXT_CENTERED);
  321. nk_layout_row_dynamic(nk, 30, width > 200 ? width / 200 : 1);
  322. int decorated = glfwGetWindowAttrib(window, GLFW_DECORATED);
  323. if (nk_checkbox_label(nk, "Decorated", &decorated))
  324. glfwSetWindowAttrib(window, GLFW_DECORATED, decorated);
  325. int resizable = glfwGetWindowAttrib(window, GLFW_RESIZABLE);
  326. if (nk_checkbox_label(nk, "Resizable", &resizable))
  327. glfwSetWindowAttrib(window, GLFW_RESIZABLE, resizable);
  328. int floating = glfwGetWindowAttrib(window, GLFW_FLOATING);
  329. if (nk_checkbox_label(nk, "Floating", &floating))
  330. glfwSetWindowAttrib(window, GLFW_FLOATING, floating);
  331. int passthrough = glfwGetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH);
  332. if (nk_checkbox_label(nk, "Mouse Passthrough", &passthrough))
  333. glfwSetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH, passthrough);
  334. int auto_iconify = glfwGetWindowAttrib(window, GLFW_AUTO_ICONIFY);
  335. if (nk_checkbox_label(nk, "Auto Iconify", &auto_iconify))
  336. glfwSetWindowAttrib(window, GLFW_AUTO_ICONIFY, auto_iconify);
  337. nk_value_bool(nk, "Focused", glfwGetWindowAttrib(window, GLFW_FOCUSED));
  338. nk_value_bool(nk, "Hovered", glfwGetWindowAttrib(window, GLFW_HOVERED));
  339. nk_value_bool(nk, "Visible", glfwGetWindowAttrib(window, GLFW_VISIBLE));
  340. nk_value_bool(nk, "Iconified", glfwGetWindowAttrib(window, GLFW_ICONIFIED));
  341. nk_value_bool(nk, "Maximized", glfwGetWindowAttrib(window, GLFW_MAXIMIZED));
  342. }
  343. nk_end(nk);
  344. glClear(GL_COLOR_BUFFER_BIT);
  345. nk_glfw3_render(NK_ANTI_ALIASING_ON);
  346. glfwSwapBuffers(window);
  347. glfwWaitEvents();
  348. }
  349. nk_glfw3_shutdown();
  350. glfwTerminate();
  351. exit(EXIT_SUCCESS);
  352. }