ElementStyleProxy.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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 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 "ElementStyleProxy.h"
  29. #include <RmlUi/Lua/LuaType.h>
  30. #include <RmlUi/Lua/IncludeLua.h>
  31. #include <RmlUi/Core/Element.h>
  32. #include <RmlUi/Core/Property.h>
  33. #include <RmlUi/Core/PropertyDefinition.h>
  34. #include <RmlUi/Core/PropertiesIteratorView.h>
  35. namespace Rml {
  36. namespace Lua {
  37. template<> void ExtraInit<ElementStyleProxy>(lua_State* L, int metatable_index)
  38. {
  39. lua_pushcfunction(L,ElementStyleProxy__index);
  40. lua_setfield(L,metatable_index,"__index");
  41. lua_pushcfunction(L,ElementStyleProxy__newindex);
  42. lua_setfield(L,metatable_index,"__newindex");
  43. lua_pushcfunction(L,ElementStyleProxy__pairs);
  44. lua_setfield(L,metatable_index,"__pairs");
  45. }
  46. int ElementStyleProxy__index(lua_State* L)
  47. {
  48. /*the table obj and the missing key are currently on the stack(index 1 & 2) as defined by the Lua language*/
  49. int keytype = lua_type(L,2);
  50. if(keytype == LUA_TSTRING) //if we are trying to access a string, then we will assume that it is a property
  51. {
  52. ElementStyleProxy* es = LuaType<ElementStyleProxy>::check(L,1);
  53. RMLUI_CHECK_OBJ(es);
  54. const Property* prop = es->owner->GetProperty(lua_tostring(L,2));
  55. RMLUI_CHECK_OBJ(prop)
  56. lua_pushstring(L,prop->ToString().c_str());
  57. return 1;
  58. }
  59. else //if it wasn't trying to get a string
  60. {
  61. lua_settop(L,2);
  62. return LuaType<ElementStyleProxy>::index(L);
  63. }
  64. }
  65. int ElementStyleProxy__newindex(lua_State* L)
  66. {
  67. //[1] = obj, [2] = key, [3] = value
  68. ElementStyleProxy* es = LuaType<ElementStyleProxy>::check(L,1);
  69. RMLUI_CHECK_OBJ(es);
  70. int keytype = lua_type(L,2);
  71. int valuetype = lua_type(L,3);
  72. if(keytype == LUA_TSTRING )
  73. {
  74. const char* key = lua_tostring(L,2);
  75. if(valuetype == LUA_TSTRING)
  76. {
  77. const char* value = lua_tostring(L,3);
  78. lua_pushboolean(L,es->owner->SetProperty(key,value));
  79. return 1;
  80. }
  81. else if (valuetype == LUA_TNIL)
  82. {
  83. es->owner->RemoveProperty(key);
  84. return 0;
  85. }
  86. }
  87. //everything else returns when it needs to, so we are safe to pass it
  88. //on if needed
  89. lua_settop(L,3);
  90. return LuaType<ElementStyleProxy>::newindex(L);
  91. }
  92. struct ElementStyleProxyPairs
  93. {
  94. static int next(lua_State* L)
  95. {
  96. ElementStyleProxyPairs* self = static_cast<ElementStyleProxyPairs*>(lua_touserdata(L, lua_upvalueindex(1)));
  97. if (self->m_view.AtEnd())
  98. {
  99. return 0;
  100. }
  101. const String& key = self->m_view.GetName();
  102. const Property& property = self->m_view.GetProperty();
  103. String val;
  104. property.definition->GetValue(val, property);
  105. lua_pushlstring(L, key.c_str(), key.size());
  106. lua_pushlstring(L, val.c_str(), val.size());
  107. ++self->m_view;
  108. return 2;
  109. }
  110. static int destroy(lua_State* L)
  111. {
  112. static_cast<ElementStyleProxyPairs*>(lua_touserdata(L, 1))->~ElementStyleProxyPairs();
  113. return 0;
  114. }
  115. static int constructor(lua_State* L, ElementStyleProxy* obj)
  116. {
  117. void* storage = lua_newuserdata(L, sizeof(ElementStyleProxyPairs));
  118. if (luaL_newmetatable(L, "RmlUi::Lua::ElementStyleProxyPairs"))
  119. {
  120. static luaL_Reg mt[] =
  121. {
  122. {"__gc", destroy},
  123. {NULL, NULL},
  124. };
  125. luaL_setfuncs(L, mt, 0);
  126. }
  127. lua_setmetatable(L, -2);
  128. lua_pushcclosure(L, next, 1);
  129. new (storage) ElementStyleProxyPairs(obj);
  130. return 1;
  131. }
  132. ElementStyleProxyPairs(ElementStyleProxy* obj)
  133. : m_view(obj->owner->IterateLocalProperties())
  134. { }
  135. PropertiesIteratorView m_view;
  136. };
  137. int ElementStyleProxy__pairs(lua_State* L)
  138. {
  139. ElementStyleProxy* obj = LuaType<ElementStyleProxy>::check(L,1);
  140. RMLUI_CHECK_OBJ(obj);
  141. ElementStyleProxyPairs::constructor(L, obj);
  142. return 1;
  143. }
  144. RegType<ElementStyleProxy> ElementStyleProxyMethods[] =
  145. {
  146. { nullptr, nullptr },
  147. };
  148. luaL_Reg ElementStyleProxyGetters[] =
  149. {
  150. { nullptr, nullptr },
  151. };
  152. luaL_Reg ElementStyleProxySetters[] =
  153. {
  154. { nullptr, nullptr },
  155. };
  156. RMLUI_LUATYPE_DEFINE(ElementStyleProxy)
  157. } // namespace Lua
  158. } // namespace Rml