XmlScreenFile.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /*
  2. * Copyright (C) 2022 The V-Gears Team
  3. *
  4. * This file is part of V-Gears
  5. *
  6. * V-Gears is free software: you can redistribute it and/or modify it under
  7. * terms of the GNU General Public License as published by the Free Software
  8. * Foundation, version 3.0 (GPLv3) of the License.
  9. *
  10. * V-Gears is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #include "core/Logger.h"
  16. #include "core/ScriptManager.h"
  17. #include "core/UiManager.h"
  18. #include "core/UiSprite.h"
  19. #include "core/UiTextArea.h"
  20. #include "core/UiWidget.h"
  21. #include "core/XmlScreenFile.h"
  22. #include "core/Utilites.h"
  23. #include "TextHandler.h"
  24. XmlScreenFile::XmlScreenFile(const Ogre::String& file): XmlFile(file){}
  25. XmlScreenFile::~XmlScreenFile(){}
  26. void XmlScreenFile::LoadScreen(){
  27. TiXmlNode* node = file_.RootElement();
  28. if (node == nullptr || node->ValueStr() != "screen"){
  29. LOG_ERROR(file_.ValueStr() + " is not a valid screen file! No <screen> in root.");
  30. return;
  31. }
  32. Ogre::String base_name = GetString(node, "name");
  33. Ogre::String script = GetString(node, "script");
  34. if (script != "") ScriptManager::getSingleton().RunFile(script);
  35. UiWidget* widget = new UiWidget(base_name);
  36. widget->SetVisible(GetBool(node, "visible", false));
  37. node = node->FirstChild();
  38. if (node != nullptr) LoadScreenRecursive(node, base_name, widget);
  39. UiManager::getSingleton().AddWidget(widget);
  40. }
  41. void XmlScreenFile::LoadScreenRecursive(
  42. TiXmlNode* node, const Ogre::String& base_name, UiWidget* widget
  43. ){
  44. while (node != nullptr){
  45. // parse widgets
  46. if (
  47. node->Type() == TiXmlNode::TINYXML_ELEMENT
  48. && (
  49. node->ValueStr() == "widget"
  50. || node->ValueStr() == "sprite"
  51. || node->ValueStr() == "text_area"
  52. || node->ValueStr() == "prototype"
  53. )
  54. ){
  55. if (node->ValueStr() == "prototype"){
  56. Ogre::String name = GetString(node, "name");
  57. if (name != ""){
  58. TiXmlNode* node2 = UiManager::getSingleton().GetPrototype(name);
  59. if (node != nullptr){
  60. node2 = node2->FirstChild();
  61. if (node2 != nullptr) LoadScreenRecursive(node2, base_name, widget);
  62. }
  63. }
  64. }
  65. else{
  66. Ogre::String name = GetString(node, "name");
  67. if (name != ""){
  68. UiWidget* widget2;
  69. if (node->ValueStr() == "sprite")
  70. widget2 = new UiSprite(name, base_name + "." + name, widget);
  71. else if (node->ValueStr() == "text_area")
  72. widget2 = new UiTextArea(name, base_name + "." + name, widget);
  73. else
  74. widget2 = new UiWidget(name, base_name + "." + name, widget);
  75. if (node->ValueStr() == "sprite"){
  76. Ogre::String image = GetString(node, "image");
  77. if (image != "") (static_cast<UiSprite*>(widget2))->SetImage(image);
  78. Ogre::String vertex_shader = GetString(node, "vertex_shader");
  79. if (vertex_shader != "")
  80. static_cast<UiSprite*>(widget2)->SetVertexShader(vertex_shader);
  81. Ogre::String fragment_shader = GetString(node, "fragment_shader");
  82. if (fragment_shader != "")
  83. static_cast<UiSprite*>(widget2)->SetFragmentShader(fragment_shader);
  84. }
  85. if (node->ValueStr() == "text_area"){
  86. Ogre::String text = GetString(node, "text_name", "");
  87. if (text != ""){
  88. TiXmlNode* utf = TextHandler::getSingleton().GetText(text);
  89. if (utf != nullptr) static_cast<UiTextArea*>(widget2)->SetText(utf);
  90. }
  91. Ogre::String font = GetString(node, "font", "");
  92. if (font != "") static_cast<UiTextArea*>(widget2)->SetFont(font);
  93. Ogre::String align = GetString(node, "text_align", "");
  94. if (align != ""){
  95. static_cast<UiTextArea*>(widget2)->SetTextAlign(
  96. align == "center"
  97. ? UiTextArea::CENTER
  98. : (align == "right" ? UiTextArea::RIGHT : UiTextArea::LEFT)
  99. );
  100. }
  101. Ogre::Vector4 padding = GetVector4(node, "padding", Ogre::Vector4::ZERO);
  102. if (padding != Ogre::Vector4::ZERO){
  103. static_cast<UiTextArea*>(widget2)->SetPadding(
  104. padding.x, padding.y, padding.z, padding.w
  105. );
  106. }
  107. }
  108. Ogre::String colours = GetString(node, "colours", "");
  109. if (colours != ""){
  110. Ogre::StringVector colour_string = Ogre::StringUtil::split(colours, ",");
  111. Ogre::Vector3 colour[4];
  112. for (unsigned int i = 0; i < 4; ++ i){
  113. Ogre::StringUtil::trim(colour_string[i]);
  114. colour[i] = (i < colour_string.size())
  115. ? Ogre::StringConverter::parseVector3(colour_string[i])
  116. : Ogre::Vector3(1, 1, 1);
  117. }
  118. widget2->SetColours(
  119. colour[0].x, colour[0].y, colour[0].z,
  120. colour[1].x, colour[1].y, colour[1].z,
  121. colour[2].x, colour[2].y, colour[2].z,
  122. colour[3].x, colour[3].y, colour[3].z
  123. );
  124. }
  125. else{
  126. Ogre::Vector3 colour = GetVector3(node, "colour", Ogre::Vector3(1, 1, 1));
  127. widget2->SetColour(colour.x, colour.y, colour.z);
  128. }
  129. if (GetBool(node, "window_background", false) == true){
  130. widget2->SetWindowBackground(true);
  131. UiManager::getSingleton().ApplyWindowColours(widget2);
  132. }
  133. float alpha = GetFloat(node, "alpha", 1);
  134. widget2->SetAlpha(alpha);
  135. Ogre::String align = GetString(node, "align");
  136. if (align != ""){
  137. widget2->SetAlign(
  138. align == "center"
  139. ? UiWidget::CENTER
  140. : (align == "right" ? UiWidget::RIGHT : UiWidget::LEFT)
  141. );
  142. }
  143. Ogre::String valign = GetString(node, "valign");
  144. if (valign != ""){
  145. widget2->SetVerticalAlign(
  146. valign == "middle"
  147. ? UiWidget::MIDDLE
  148. : (valign == "bottom" ? UiWidget::BOTTOM : UiWidget::TOP)
  149. );
  150. }
  151. Ogre::String origin_x_str = GetString(node, "origin_x");
  152. if (origin_x_str != ""){
  153. float x_percent = 0;
  154. float x = 0;
  155. ParsePercent(x_percent, x, origin_x_str);
  156. widget2->SetOriginX(x_percent, x);
  157. }
  158. Ogre::String origin_y_str = GetString(node, "origin_y");
  159. if (origin_y_str != ""){
  160. float y_percent = 0;
  161. float y = 0;
  162. ParsePercent(y_percent, y, origin_y_str);
  163. widget2->SetOriginY(y_percent, y);
  164. }
  165. Ogre::String x_str = GetString(node, "x");
  166. if (x_str != ""){
  167. float x_percent = 0;
  168. float x = 0;
  169. ParsePercent(x_percent, x, x_str);
  170. widget2->SetX(x_percent, x);
  171. }
  172. Ogre::String y_str = GetString(node, "y");
  173. if (y_str != ""){
  174. float y_percent = 0;
  175. float y = 0;
  176. ParsePercent(y_percent, y, y_str);
  177. widget2->SetY(y_percent, y);
  178. }
  179. Ogre::String width_str = GetString(node, "width");
  180. if (width_str != ""){
  181. float width_percent = 0;
  182. float width = 0;
  183. ParsePercent(width_percent, width, width_str);
  184. widget2->SetWidth(width_percent, width);
  185. }
  186. Ogre::String height_str = GetString(node, "height");
  187. if (height_str != ""){
  188. float height_percent = 0;
  189. float height = 0;
  190. ParsePercent(height_percent, height, height_str);
  191. widget2->SetHeight(height_percent, height);
  192. }
  193. Ogre::Vector2 scale = GetVector2(node, "scale", Ogre::Vector2(1.0f, 1.0f));
  194. widget2->SetScale(scale);
  195. widget2->SetRotation(GetFloat(node, "rotation", 0.0f));
  196. Ogre::String scissor_area = GetString(node, "scissor_area");
  197. if (scissor_area != ""){
  198. Ogre::StringVector coords = Ogre::StringUtil::split(scissor_area, " ");
  199. if (coords.size() == 4){
  200. float percent_x1, x1, percent_y1, y1;
  201. float percent_x2, x2, percent_y2, y2 = 0;
  202. ParsePercent(percent_x1, x1, coords[0]);
  203. ParsePercent(percent_y1, y1, coords[1]);
  204. ParsePercent(percent_x2, x2, coords[2]);
  205. ParsePercent(percent_y2, y2, coords[3]);
  206. widget2->SetScissorArea(
  207. percent_x1, x1, percent_y1, y1, percent_x2, x2, percent_y2, y2
  208. );
  209. }
  210. }
  211. widget2->SetGlobalScissor(GetBool(node, "global_scissor", true));
  212. widget2->SetVisible(GetBool(node, "visible", false));
  213. if (node->ValueStr() == "sprite")
  214. static_cast<UiSprite*>(widget2)->UpdateGeometry();
  215. else if (node->ValueStr() == "text_area")
  216. static_cast<UiTextArea*>(widget2)->UpdateGeometry();
  217. widget->AddChild(widget2);
  218. TiXmlNode* node2 = node->FirstChild();
  219. if (node2 != nullptr)
  220. LoadScreenRecursive(node2, base_name + "." + name, widget2);
  221. }
  222. else LOG_ERROR("There is no name in entity with base name " + base_name);
  223. }
  224. }
  225. // Parse animation data for widget.
  226. else if (node->Type() == TiXmlNode::TINYXML_ELEMENT&& node->ValueStr() == "animation"){
  227. Ogre::String name = GetString(node, "name", "");
  228. if (name != ""){
  229. UiAnimation* animation = new UiAnimation(name, widget);
  230. float anim_length = GetFloat(node, "length", 0);
  231. animation->SetLength(anim_length);
  232. Ogre::String scale = GetString(node, "scale", "");
  233. if (scale != ""){
  234. Ogre::StringVector key_frame = Ogre::StringUtil::split(scale, ",");
  235. for (unsigned int i = 0; i < key_frame.size(); ++ i){
  236. Ogre::StringUtil::trim(key_frame[i]);
  237. Ogre::StringVector data = Ogre::StringUtil::split(key_frame[i], ":");
  238. if (data.size() > 1){
  239. UiKeyFrameVector2 key;
  240. key.time = ParseKeyFrameTime(anim_length, data[0]);
  241. key.value = Ogre::StringConverter::parseVector2(data[1]);
  242. animation->AddScaleKeyFrame(key);
  243. }
  244. }
  245. }
  246. Ogre::String x = GetString(node, "x", "");
  247. if (x != ""){
  248. Ogre::StringVector key_frame = Ogre::StringUtil::split(x, ",");
  249. for (unsigned int i = 0; i < key_frame.size(); ++ i){
  250. Ogre::StringUtil::trim(key_frame[i]);
  251. Ogre::StringVector data = Ogre::StringUtil::split(key_frame[i], ":");
  252. if (data.size() > 1){
  253. UiKeyFrameVector2 key;
  254. key.time = ParseKeyFrameTime(anim_length, data[0]);
  255. ParsePercent(key.value.x, key.value.y, data[1]);
  256. animation->AddXKeyFrame(key);
  257. }
  258. }
  259. }
  260. Ogre::String y = GetString(node, "y", "");
  261. if (y != ""){
  262. Ogre::StringVector key_frame = Ogre::StringUtil::split(y, ",");
  263. for (unsigned int i = 0; i < key_frame.size(); ++ i){
  264. Ogre::StringUtil::trim(key_frame[i]);
  265. Ogre::StringVector data = Ogre::StringUtil::split(key_frame[i], ":");
  266. if (data.size() > 1){
  267. UiKeyFrameVector2 key;
  268. key.time = ParseKeyFrameTime(anim_length, data[0]);
  269. ParsePercent(key.value.x, key.value.y, data[1]);
  270. animation->AddYKeyFrame(key);
  271. }
  272. }
  273. }
  274. Ogre::String width = GetString(node, "width", "");
  275. if (width != ""){
  276. Ogre::StringVector key_frame = Ogre::StringUtil::split(width, ",");
  277. for (unsigned int i = 0; i < key_frame.size(); ++ i){
  278. Ogre::StringUtil::trim(key_frame[i]);
  279. Ogre::StringVector data = Ogre::StringUtil::split(key_frame[i], ":");
  280. if (data.size() > 1){
  281. UiKeyFrameVector2 key;
  282. key.time = ParseKeyFrameTime(anim_length, data[0]);
  283. ParsePercent(key.value.x, key.value.y, data[1]);
  284. animation->AddWidthKeyFrame(key);
  285. }
  286. }
  287. }
  288. Ogre::String height = GetString(node, "height", "");
  289. if (height != ""){
  290. Ogre::StringVector key_frame = Ogre::StringUtil::split(height, ",");
  291. for (unsigned int i = 0; i < key_frame.size(); ++ i){
  292. Ogre::StringUtil::trim(key_frame[i]);
  293. Ogre::StringVector data = Ogre::StringUtil::split(key_frame[i], ":");
  294. if (data.size() > 1){
  295. UiKeyFrameVector2 key;
  296. key.time = ParseKeyFrameTime(anim_length, data[0]);
  297. ParsePercent(key.value.x, key.value.y, data[1]);
  298. animation->AddHeightKeyFrame(key);
  299. }
  300. }
  301. }
  302. Ogre::String rotation = GetString(node, "rotation", "");
  303. if (rotation != ""){
  304. Ogre::StringVector key_frame = Ogre::StringUtil::split(rotation, ",");
  305. for (unsigned int i = 0; i < key_frame.size(); ++ i){
  306. Ogre::StringUtil::trim(key_frame[i]);
  307. Ogre::StringVector data = Ogre::StringUtil::split(key_frame[i], ":");
  308. if (data.size() > 1){
  309. UiKeyFrameFloat key;
  310. key.time = ParseKeyFrameTime(anim_length, data[0]);
  311. key.value = Ogre::StringConverter::parseReal(data[1]);
  312. animation->AddRotationKeyFrame(key);
  313. }
  314. }
  315. }
  316. Ogre::String alpha = GetString(node, "alpha", "");
  317. if (alpha != ""){
  318. Ogre::StringVector key_frame = Ogre::StringUtil::split(alpha, ",");
  319. for (unsigned int i = 0; i < key_frame.size(); ++ i){
  320. Ogre::StringUtil::trim(key_frame[i]);
  321. Ogre::StringVector data = Ogre::StringUtil::split(key_frame[i], ":");
  322. if (data.size() > 1){
  323. UiKeyFrameFloat key;
  324. key.time = ParseKeyFrameTime(anim_length, data[0]);
  325. key.value = Ogre::StringConverter::parseReal(data[1]);
  326. animation->AddAlphaKeyFrame(key);
  327. }
  328. }
  329. }
  330. Ogre::String scissor_area = GetString(node, "scissor_area", "");
  331. if (scissor_area != ""){
  332. Ogre::StringVector key_frame = Ogre::StringUtil::split(scissor_area, ",");
  333. for (unsigned int i = 0; i < key_frame.size(); ++ i){
  334. Ogre::StringUtil::trim(key_frame[i]);
  335. Ogre::StringVector data = Ogre::StringUtil::split(key_frame[i], ":");
  336. if (data.size() > 1){
  337. UiKeyFrameVector2 key1, key2, key3, key4;
  338. key1.time = ParseKeyFrameTime(anim_length, data[0]);
  339. key2.time = key1.time;
  340. key3.time = key1.time;
  341. key4.time = key1.time;
  342. Ogre::StringVector keys = Ogre::StringUtil::split(data[1], " ");
  343. ParsePercent(key1.value.x, key1.value.y, keys[0]);
  344. ParsePercent(key2.value.x, key2.value.y, keys[1]);
  345. ParsePercent(key3.value.x, key3.value.y, keys[2]);
  346. ParsePercent(key4.value.x, key4.value.y, keys[3]);
  347. animation->AddScissorKeyFrame(key1, key2, key3, key4);
  348. }
  349. }
  350. }
  351. widget->AddAnimation(animation);
  352. }
  353. }
  354. node = node->NextSibling();
  355. }
  356. }