Context.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /*
  2. * This source file is part of RmlUi, the HTML/CSS Interface Middleware
  3. *
  4. * For the latest information, see http://github.com/mikke89/RmlUi
  5. *
  6. * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
  7. * Copyright (c) 2019-2023 The RmlUi Team, and contributors
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a copy
  10. * of this software and associated documentation files (the "Software"), to deal
  11. * in the Software without restriction, including without limitation the rights
  12. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. * copies of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. * THE SOFTWARE.
  26. *
  27. */
  28. #include "Context.h"
  29. #include "ContextDocumentsProxy.h"
  30. #include "LuaDataModel.h"
  31. #include "LuaEventListener.h"
  32. #include <RmlUi/Core/Context.h>
  33. #include <RmlUi/Core/ElementDocument.h>
  34. #include <RmlUi/Core/Factory.h>
  35. namespace Rml {
  36. namespace Lua {
  37. typedef ElementDocument Document;
  38. template <>
  39. void ExtraInit<Context>(lua_State* /*L*/, int /*metatable_index*/)
  40. {
  41. return;
  42. }
  43. // methods
  44. int ContextAddEventListener(lua_State* L, Context* obj)
  45. {
  46. // need to make an EventListener for Lua before I can do anything else
  47. const char* evt = luaL_checkstring(L, 1); // event
  48. Element* element = nullptr;
  49. bool capturephase = false;
  50. // get the rest of the stuff needed to construct the listener
  51. if (lua_gettop(L) > 2)
  52. {
  53. if (!lua_isnoneornil(L, 3))
  54. element = LuaType<Element>::check(L, 3);
  55. if (!lua_isnoneornil(L, 4))
  56. capturephase = RMLUI_CHECK_BOOL(L, 4);
  57. }
  58. int type = lua_type(L, 2);
  59. if (type == LUA_TFUNCTION)
  60. {
  61. if (element)
  62. element->AddEventListener(evt, new LuaEventListener(L, 2, element), capturephase);
  63. else
  64. obj->AddEventListener(evt, new LuaEventListener(L, 2, nullptr), capturephase);
  65. }
  66. else if (type == LUA_TSTRING)
  67. {
  68. if (element)
  69. element->AddEventListener(evt, new LuaEventListener(luaL_checkstring(L, 2), element), capturephase);
  70. else
  71. obj->AddEventListener(evt, new LuaEventListener(luaL_checkstring(L, 2), nullptr), capturephase);
  72. }
  73. else
  74. {
  75. Log::Message(Log::LT_WARNING, "Lua Context:AddEventLisener's 2nd argument can only be a Lua function or a string, you passed in a %s",
  76. lua_typename(L, type));
  77. }
  78. return 0;
  79. }
  80. int ContextCreateDocument(lua_State* L, Context* obj)
  81. {
  82. const char* tag;
  83. if (lua_gettop(L) < 1)
  84. tag = "body";
  85. else
  86. tag = luaL_checkstring(L, 1);
  87. Document* doc = obj->CreateDocument(tag);
  88. LuaType<Document>::push(L, doc, false);
  89. return 1;
  90. }
  91. int ContextLoadDocument(lua_State* L, Context* obj)
  92. {
  93. const char* path = luaL_checkstring(L, 1);
  94. Document* doc = obj->LoadDocument(path);
  95. LuaType<Document>::push(L, doc, false);
  96. return 1;
  97. }
  98. int ContextRender(lua_State* L, Context* obj)
  99. {
  100. lua_pushboolean(L, obj->Render());
  101. return 1;
  102. }
  103. int ContextUnloadAllDocuments(lua_State* /*L*/, Context* obj)
  104. {
  105. obj->UnloadAllDocuments();
  106. return 0;
  107. }
  108. int ContextUnloadDocument(lua_State* L, Context* obj)
  109. {
  110. Document* doc = LuaType<Document>::check(L, 1);
  111. obj->UnloadDocument(doc);
  112. return 0;
  113. }
  114. int ContextUpdate(lua_State* L, Context* obj)
  115. {
  116. lua_pushboolean(L, obj->Update());
  117. return 1;
  118. }
  119. int ContextOpenDataModel(lua_State* L, Context* obj)
  120. {
  121. if (!OpenLuaDataModel(L, obj, 1, 2))
  122. {
  123. // Open fails
  124. lua_pushboolean(L, false);
  125. }
  126. return 1;
  127. }
  128. // input
  129. int ContextProcessMouseMove(lua_State* L, Context* obj)
  130. {
  131. int x = (int)luaL_checkinteger(L, 1);
  132. int y = (int)luaL_checkinteger(L, 2);
  133. int flags = (int)luaL_checkinteger(L, 3);
  134. lua_pushboolean(L, obj->ProcessMouseMove(x, y, flags));
  135. return 1;
  136. }
  137. int ContextProcessMouseButtonDown(lua_State* L, Context* obj)
  138. {
  139. int button_index = (int)luaL_checkinteger(L, 1);
  140. int key_modifier_state = (int)luaL_checkinteger(L, 2);
  141. lua_pushboolean(L, obj->ProcessMouseButtonDown(button_index, key_modifier_state));
  142. return 1;
  143. }
  144. int ContextProcessMouseButtonUp(lua_State* L, Context* obj)
  145. {
  146. int button_index = (int)luaL_checkinteger(L, 1);
  147. int key_modifier_state = (int)luaL_checkinteger(L, 2);
  148. lua_pushboolean(L, obj->ProcessMouseButtonUp(button_index, key_modifier_state));
  149. return 1;
  150. }
  151. int ContextProcessMouseWheel(lua_State* L, Context* obj)
  152. {
  153. float wheel_delta = (float)luaL_checknumber(L, 1);
  154. int key_modifier_state = (int)luaL_checkinteger(L, 2);
  155. lua_pushboolean(L, obj->ProcessMouseWheel(wheel_delta, key_modifier_state));
  156. return 1;
  157. }
  158. int ContextProcessMouseLeave(lua_State* L, Context* obj)
  159. {
  160. lua_pushboolean(L, obj->ProcessMouseLeave());
  161. return 1;
  162. }
  163. int ContextIsMouseInteracting(lua_State* L, Context* obj)
  164. {
  165. lua_pushboolean(L, obj->IsMouseInteracting());
  166. return 1;
  167. }
  168. int ContextProcessKeyDown(lua_State* L, Context* obj)
  169. {
  170. Rml::Input::KeyIdentifier key_identifier = (Rml::Input::KeyIdentifier)luaL_checkinteger(L, 1);
  171. int key_modifier_state = (int)luaL_checkinteger(L, 2);
  172. lua_pushboolean(L, obj->ProcessKeyDown(key_identifier, key_modifier_state));
  173. return 1;
  174. }
  175. int ContextProcessKeyUp(lua_State* L, Context* obj)
  176. {
  177. Rml::Input::KeyIdentifier key_identifier = (Rml::Input::KeyIdentifier)luaL_checkinteger(L, 1);
  178. int key_modifier_state = (int)luaL_checkinteger(L, 2);
  179. lua_pushboolean(L, obj->ProcessKeyUp(key_identifier, key_modifier_state));
  180. return 1;
  181. }
  182. int ContextProcessTextInput(lua_State* L, Context* obj)
  183. {
  184. const char* text = NULL;
  185. int character = -1;
  186. if (lua_isstring(L, 1))
  187. text = lua_tostring(L, 1);
  188. else
  189. character = (int)luaL_checkinteger(L, 1);
  190. if (character > 0)
  191. lua_pushboolean(L, obj->ProcessTextInput((char)character));
  192. else if (text != NULL)
  193. lua_pushboolean(L, obj->ProcessTextInput(text));
  194. else
  195. Log::Message(Log::LT_WARNING, "Could not process text input on context '%s'.", obj->GetName().c_str());
  196. return 1;
  197. }
  198. // getters
  199. int ContextGetAttrdimensions(lua_State* L)
  200. {
  201. Context* cont = LuaType<Context>::check(L, 1);
  202. Vector2i* dim = new Vector2i(cont->GetDimensions());
  203. LuaType<Vector2i>::push(L, dim, true);
  204. return 1;
  205. }
  206. // returns a table of everything
  207. int ContextGetAttrdocuments(lua_State* L)
  208. {
  209. Context* cont = LuaType<Context>::check(L, 1);
  210. RMLUI_CHECK_OBJ(cont);
  211. ContextDocumentsProxy* cdp = new ContextDocumentsProxy();
  212. cdp->owner = cont;
  213. LuaType<ContextDocumentsProxy>::push(L, cdp, true); // does get garbage collected (deleted)
  214. return 1;
  215. }
  216. int ContextGetAttrdp_ratio(lua_State* L)
  217. {
  218. Context* cont = LuaType<Context>::check(L, 1);
  219. float dp_ratio = cont->GetDensityIndependentPixelRatio();
  220. lua_pushnumber(L, dp_ratio);
  221. return 1;
  222. }
  223. int ContextGetAttrfocus_element(lua_State* L)
  224. {
  225. Context* cont = LuaType<Context>::check(L, 1);
  226. RMLUI_CHECK_OBJ(cont);
  227. LuaType<Element>::push(L, cont->GetFocusElement());
  228. return 1;
  229. }
  230. int ContextGetAttrhover_element(lua_State* L)
  231. {
  232. Context* cont = LuaType<Context>::check(L, 1);
  233. RMLUI_CHECK_OBJ(cont);
  234. LuaType<Element>::push(L, cont->GetHoverElement());
  235. return 1;
  236. }
  237. int ContextGetAttrname(lua_State* L)
  238. {
  239. Context* cont = LuaType<Context>::check(L, 1);
  240. RMLUI_CHECK_OBJ(cont);
  241. lua_pushstring(L, cont->GetName().c_str());
  242. return 1;
  243. }
  244. int ContextGetAttrroot_element(lua_State* L)
  245. {
  246. Context* cont = LuaType<Context>::check(L, 1);
  247. RMLUI_CHECK_OBJ(cont);
  248. LuaType<Element>::push(L, cont->GetRootElement());
  249. return 1;
  250. }
  251. // setters
  252. int ContextSetAttrdimensions(lua_State* L)
  253. {
  254. Context* cont = LuaType<Context>::check(L, 1);
  255. RMLUI_CHECK_OBJ(cont);
  256. Vector2i* dim = LuaType<Vector2i>::check(L, 2);
  257. cont->SetDimensions(*dim);
  258. return 0;
  259. }
  260. int ContextSetAttrdp_ratio(lua_State* L)
  261. {
  262. Context* cont = LuaType<Context>::check(L, 1);
  263. RMLUI_CHECK_OBJ(cont);
  264. lua_Number dp_ratio = luaL_checknumber(L, 2);
  265. cont->SetDensityIndependentPixelRatio((float)dp_ratio);
  266. return 0;
  267. }
  268. RegType<Context> ContextMethods[] = {
  269. RMLUI_LUAMETHOD(Context, AddEventListener),
  270. RMLUI_LUAMETHOD(Context, CreateDocument),
  271. RMLUI_LUAMETHOD(Context, LoadDocument),
  272. RMLUI_LUAMETHOD(Context, Render),
  273. RMLUI_LUAMETHOD(Context, UnloadAllDocuments),
  274. RMLUI_LUAMETHOD(Context, UnloadDocument),
  275. RMLUI_LUAMETHOD(Context, Update),
  276. RMLUI_LUAMETHOD(Context, OpenDataModel),
  277. // todo: CloseDataModel
  278. RMLUI_LUAMETHOD(Context, ProcessMouseMove),
  279. RMLUI_LUAMETHOD(Context, ProcessMouseButtonDown),
  280. RMLUI_LUAMETHOD(Context, ProcessMouseButtonUp),
  281. RMLUI_LUAMETHOD(Context, ProcessMouseWheel),
  282. RMLUI_LUAMETHOD(Context, ProcessMouseLeave),
  283. RMLUI_LUAMETHOD(Context, IsMouseInteracting),
  284. RMLUI_LUAMETHOD(Context, ProcessKeyDown),
  285. RMLUI_LUAMETHOD(Context, ProcessKeyUp),
  286. RMLUI_LUAMETHOD(Context, ProcessTextInput),
  287. {nullptr, nullptr},
  288. };
  289. luaL_Reg ContextGetters[] = {
  290. RMLUI_LUAGETTER(Context, dimensions),
  291. RMLUI_LUAGETTER(Context, documents),
  292. RMLUI_LUAGETTER(Context, dp_ratio),
  293. RMLUI_LUAGETTER(Context, focus_element),
  294. RMLUI_LUAGETTER(Context, hover_element),
  295. RMLUI_LUAGETTER(Context, name),
  296. RMLUI_LUAGETTER(Context, root_element),
  297. {nullptr, nullptr},
  298. };
  299. luaL_Reg ContextSetters[] = {
  300. RMLUI_LUASETTER(Context, dimensions),
  301. RMLUI_LUASETTER(Context, dp_ratio),
  302. {nullptr, nullptr},
  303. };
  304. RMLUI_LUATYPE_DEFINE(Context)
  305. } // namespace Lua
  306. } // namespace Rml