JSUIAPI.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
  2. // Please see LICENSE.md in repository root for license information
  3. // https://github.com/AtomicGameEngine/AtomicGameEngine
  4. #include <TurboBadger/tb_window.h>
  5. #include "JSUIAPI.h"
  6. #include "JSVM.h"
  7. #include <Atomic/UI/UI.h>
  8. #include <Atomic/UI/UISelectItem.h>
  9. #include <Atomic/UI/UIMenuWindow.h>
  10. #include <Atomic/UI/UIButton.h>
  11. #include <Atomic/UI/UIWindow.h>
  12. namespace Atomic
  13. {
  14. static int UIButton_Popup(duk_context* ctx)
  15. {
  16. if (!duk_is_object(ctx, 0))
  17. {
  18. duk_push_string(ctx, "UIButton.popup first argument must be an object");
  19. duk_throw(ctx);
  20. }
  21. if (!duk_is_callable(ctx, 1))
  22. {
  23. duk_push_string(ctx, "UIButton.popup second argument must be callable");
  24. duk_throw(ctx);
  25. }
  26. JSVM* vm = JSVM::GetJSVM(ctx);
  27. duk_enum(ctx, 0, DUK_ENUM_OWN_PROPERTIES_ONLY);
  28. UISelectItemSource* source = new UISelectItemSource(vm->GetContext());
  29. while (duk_next(ctx, -1, 0)) {
  30. String key = duk_get_string(ctx, -1);
  31. duk_get_prop(ctx, 0);
  32. if (duk_is_array(ctx, -1))
  33. {
  34. // need to support this, for skin image, etc
  35. assert(0);
  36. }
  37. else if (duk_is_string(ctx, -1))
  38. {
  39. // id
  40. String id = duk_get_string(ctx, -1);
  41. source->AddItem(new UISelectItem(vm->GetContext(), key, id));
  42. }
  43. else
  44. {
  45. duk_push_string(ctx, "UIButton.popup data object key is not an array or string");
  46. duk_throw(ctx);
  47. }
  48. duk_pop(ctx); // pop key value
  49. }
  50. duk_pop(ctx); // pop enum object
  51. duk_push_this(ctx);
  52. duk_dup(ctx, 1);
  53. duk_put_prop_string(ctx, -2, "__popup_menu_callback");
  54. UIButton* button = js_to_class_instance<UIButton>(ctx, -1, 0);
  55. UIMenuWindow* menuWindow = new UIMenuWindow(vm->GetContext(), button, "__popup-menu");
  56. menuWindow->Show(source);
  57. duk_pop(ctx);
  58. return 0;
  59. }
  60. int UIWindow_GetResizeToFitContentRect(duk_context* ctx)
  61. {
  62. duk_push_this(ctx);
  63. UIWindow* window = js_to_class_instance<UIWindow>(ctx, -1, 0);
  64. duk_pop(ctx);
  65. tb::TBWindow* tbwindow = (tb::TBWindow*) window->GetInternalWidget();
  66. tb::TBRect rect = tbwindow->GetResizeToFitContentRect();
  67. duk_push_object(ctx);
  68. duk_push_number(ctx, rect.x);
  69. duk_put_prop_string(ctx, -2, "x");
  70. duk_push_number(ctx, rect.y);
  71. duk_put_prop_string(ctx, -2, "y");
  72. duk_push_number(ctx, rect.w);
  73. duk_put_prop_string(ctx, -2, "width");
  74. duk_push_number(ctx, rect.h);
  75. duk_put_prop_string(ctx, -2, "height");
  76. return 1;
  77. }
  78. int UI_DebugGetUIKeepAliveCount(duk_context* ctx)
  79. {
  80. duk_push_global_stash(ctx);
  81. duk_get_prop_string(ctx, -1, "__jsui_widgetkeepalive");
  82. duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY);
  83. double count = 0;
  84. while (duk_next(ctx, -1 , 0)) {
  85. duk_pop(ctx); /* pop_key */
  86. count++;
  87. }
  88. duk_pop_n(ctx, 3); /* pop enum object, keep alive object, and stash */
  89. duk_push_number(ctx, count);
  90. return 1;
  91. }
  92. int UI_DebugGetWrappedWidgetCount(duk_context* ctx)
  93. {
  94. JSVM* vm = JSVM::GetJSVM(ctx);
  95. UI* ui = vm->GetSubsystem<UI>();
  96. duk_push_number(ctx, (double) ui->DebugGetWrappedWidgetCount());
  97. return 1;
  98. }
  99. int UI_DebugShowSettingsWindow(duk_context* ctx)
  100. {
  101. UIWidget* widget = js_to_class_instance<UIWidget>(ctx, 0, 0);
  102. if (!widget)
  103. return 0;
  104. #ifdef TB_RUNTIME_DEBUG_INFO
  105. if (widget->GetInternalWidget())
  106. tb::ShowDebugInfoSettingsWindow(widget->GetInternalWidget());
  107. #endif
  108. return 0;
  109. }
  110. void jsapi_init_ui(JSVM* vm)
  111. {
  112. duk_context* ctx = vm->GetJSContext();
  113. // UI class object
  114. duk_get_global_string(ctx, "Atomic");
  115. duk_get_prop_string(ctx, -1, "UI");
  116. duk_push_c_function(ctx, UI_DebugGetWrappedWidgetCount, 0);
  117. duk_put_prop_string(ctx, -2, "debugGetWrappedWidgetCount");
  118. duk_push_c_function(ctx, UI_DebugGetUIKeepAliveCount, 0);
  119. duk_put_prop_string(ctx, -2, "debugGetUIKeepAliveCount");
  120. duk_push_c_function(ctx, UI_DebugShowSettingsWindow, 1);
  121. duk_put_prop_string(ctx, -2, "debugShowSettingsWindow");
  122. duk_pop_2(ctx);
  123. js_class_get_prototype(ctx, "Atomic", "UIButton");
  124. duk_push_c_function(ctx, UIButton_Popup, 2);
  125. duk_put_prop_string(ctx, -2, "popup");
  126. duk_pop(ctx);
  127. js_class_get_prototype(ctx, "Atomic", "UIWindow");
  128. duk_push_c_function(ctx, UIWindow_GetResizeToFitContentRect, 0);
  129. duk_put_prop_string(ctx, -2, "getResizeToFitContentRect");
  130. duk_pop(ctx);
  131. }
  132. }