GUITable.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. #include "GUITable.h"
  2. #include "GUIWidget.h"
  3. GUITable:: GUITable() :
  4. elems(_FL_),
  5. items(_FL_)
  6. {
  7. }
  8. GUITable::~GUITable()
  9. {
  10. if( EditMode_IsOn())
  11. return;
  12. for( int i = 0 ; i < elems ; i++ )
  13. {
  14. Element &e = elems[i];
  15. RELEASE(e.number.p);
  16. RELEASE(e.activity.p);
  17. }
  18. }
  19. void GUITable::Restart()
  20. {
  21. //
  22. }
  23. bool GUITable::Create (MOPReader &reader)
  24. {
  25. InitParams(reader);
  26. return true;
  27. }
  28. bool GUITable::EditMode_Update(MOPReader &reader)
  29. {
  30. InitParams(reader);
  31. return true;
  32. }
  33. void GUITable::Show(bool isShow)
  34. {
  35. if( elems && isShow != IsShow())
  36. {
  37. if( isShow )
  38. {
  39. SetUpdate(&GUITable::Update,ML_GUI1);
  40. }
  41. else
  42. {
  43. DelUpdate(&GUITable::Update);
  44. }
  45. }
  46. MissionObject::Show(isShow);
  47. }
  48. void _cdecl GUITable::Update(float dltTime, long level)
  49. {
  50. for( int i = 0 ; i < elems ; i++ )
  51. {
  52. Element &e = elems[i];
  53. bool update = false;
  54. if( e.widget.p && e.number.p && e.widget.p->IsShow())
  55. {
  56. int val = (int)e.number.p->Get();
  57. if( val != e.val )
  58. {
  59. static char buf[32];
  60. sprintf_s(buf,sizeof(buf),"%d",val);
  61. const char *s = buf;
  62. e.widget.p->Command("SetString",1,&s);
  63. e.val = val;
  64. update = true;
  65. }
  66. }
  67. if( update )
  68. {
  69. if( e.time <= 0.0f )
  70. {
  71. e.from_x = items[e.item].x;
  72. e.from_y = items[e.item].y;
  73. }
  74. for( int j = e.item + 1 ; j < items ; j++ )
  75. {
  76. Item &t = items[j]; Element &next = elems[t.elem];
  77. if( e.val < next.val )
  78. {
  79. Item &c = items[j - 1];
  80. c.elem = t.elem; next.item = j - 1;
  81. if( next.time <= 0.0f )
  82. {
  83. next.from_x = t.x;
  84. next.from_y = t.y;
  85. }
  86. next.time = delay;
  87. next.to_x = c.x;
  88. next.to_y = c.y;
  89. if( next.panel.p )
  90. next.panel.p->ResetDrawUpdate(0);
  91. e.item = j; t.elem = i;
  92. e.time = delay;
  93. e.to_x = t.x;
  94. e.to_y = t.y;
  95. if( e.panel.p )
  96. e.panel.p->ResetDrawUpdate(1);
  97. }
  98. else
  99. break;
  100. }
  101. for( int j = e.item - 1 ; j >= 0 ; j-- )
  102. {
  103. Item &t = items[j]; Element &prev = elems[t.elem];
  104. if( e.val > prev.val )
  105. {
  106. Item &c = items[j + 1];
  107. c.elem = t.elem; prev.item = j + 1;
  108. if( prev.time <= 0.0f )
  109. {
  110. prev.from_x = t.x;
  111. prev.from_y = t.y;
  112. }
  113. prev.time = delay;
  114. prev.to_x = c.x;
  115. prev.to_y = c.y;
  116. if( prev.panel.p )
  117. prev.panel.p->ResetDrawUpdate(0);
  118. e.item = j; t.elem = i;
  119. e.time = delay;
  120. e.to_x = t.x;
  121. e.to_y = t.y;
  122. if( e.panel.p )
  123. e.panel.p->ResetDrawUpdate(1);
  124. }
  125. else
  126. break;
  127. }
  128. }
  129. if( e.time > 0.0f )
  130. {
  131. e.time -= dltTime;
  132. float k = e.time/0.5f;
  133. if( k < 0.0f )
  134. k = 0.0f;
  135. if( e.panel.p )
  136. {
  137. e.panel.p->MoveTo(
  138. Lerp(e.to_x,e.from_x,k),
  139. Lerp(e.to_y,e.from_y,k));
  140. }
  141. }
  142. else
  143. {
  144. if( e.panel.p )
  145. {
  146. const Item &item = items[e.item];
  147. e.panel.p->MoveTo(item.x,item.y);
  148. }
  149. }
  150. }
  151. }
  152. void GUITable::PostCreate()
  153. {
  154. MOSafePointer p; MissionObject *q;
  155. for( int i = 0 ; i < elems ; i++ )
  156. {
  157. Element &e = elems[i];
  158. if( string::NotEmpty(e.panel.name))
  159. {
  160. FindObject(ConstString(e.panel.name),p); q = p.Ptr();
  161. if( q && q->Is(InterfaceUtils::GetBaseId()))
  162. {
  163. e.panel.p = (BaseGUIElement *)q;
  164. }
  165. else
  166. {
  167. LogicDebugError("GUIElement \"%s\" not found.",e.panel.name);
  168. e.panel.p = null;
  169. }
  170. }
  171. else
  172. {
  173. LogicDebugError("Elements[%d].Panel is empty.",i);
  174. e.panel.p = null;
  175. }
  176. if( string::NotEmpty(e.widget.name))
  177. {
  178. FindObject(ConstString(e.widget.name),p); q = p.Ptr();
  179. if( q && q->Is(InterfaceUtils::GetWidgetId()))
  180. {
  181. e.widget.p = (GUIWidget *)q;
  182. }
  183. else
  184. {
  185. LogicDebugError("GUIWidget \"%s\" not found.",e.widget.name);
  186. e.widget.p = null;
  187. }
  188. }
  189. else
  190. {
  191. LogicDebugError("Elements[%d].Widget is empty.",i);
  192. e.widget.p = null;
  193. }
  194. }
  195. for( int i = 0 ; i < elems ; i++ )
  196. {
  197. Element &e = elems[i];
  198. if( string::NotEmpty(e.activity.name))
  199. {
  200. LogicDebug("Elements[%d].Activity set for key '%s'", i, e.activity.name);
  201. e.activity.p = api->Storage().GetItemFloat(e.activity.name, _FL_);
  202. if (e.activity.p == null)
  203. {
  204. LogicDebugError("--Elements[%d].Activity. key in database not found!", i);
  205. }
  206. } else
  207. {
  208. LogicDebug("Elements[%d].Activity not set (don't change visibility state)", i);
  209. e.activity.p = null;
  210. }
  211. if( string::NotEmpty(e.number.name))
  212. {
  213. e.number.p = api->Storage().GetItemFloat(e.number.name,_FL_);
  214. }
  215. else
  216. {
  217. LogicDebugError("Elements[%d].Number is empty.",i);
  218. e.number.p = null;
  219. }
  220. }
  221. UpdateActivity();
  222. Show(show);
  223. }
  224. void GUITable::UpdateActivity()
  225. {
  226. for( dword i = 0 ; i < elems.Size(); i++ )
  227. {
  228. Element &e = elems[i];
  229. if (e.activity.p && e.widget.p)
  230. {
  231. float fActivity = e.activity.p->Get();
  232. if (fActivity <= 0.000001f)
  233. {
  234. LogicDebug("Elements[%d] Hide widget, because key in database says is not active", i);
  235. e.widget.p->Show(false);
  236. //что бы при сортировке был внизу всегда, невидимый...
  237. e.val = -10000;
  238. } else
  239. {
  240. LogicDebug("Elements[%d] Show widget, because key in database says is active", i);
  241. e.widget.p->Show(true);
  242. }
  243. }
  244. }
  245. }
  246. void GUITable::InitParams(MOPReader &reader)
  247. {
  248. delay = reader.Float();
  249. long count = reader.Array();
  250. elems.DelAll();
  251. elems.Reserve(count);
  252. items.DelAll();
  253. items.Reserve(count);
  254. for( int i = 0 ; i < count ; i++ )
  255. {
  256. Element &e = elems[elems.Add()];
  257. Item &t = items[items.Add()];
  258. e.panel.name = reader.String().c_str();
  259. t.x = reader.Float();
  260. t.y = reader.Float();
  261. t.elem = i;
  262. e.number.name = reader.String().c_str();
  263. e.activity.name = reader.String().c_str();
  264. e.val = 0;
  265. e.item = i;
  266. e.time = -1.0f;
  267. e.widget.name = reader.String().c_str();
  268. }
  269. show = reader.Bool();
  270. MissionObject::Show(false);
  271. }
  272. void GUITable::Command(const char *id, dword numParams, const char **params)
  273. {
  274. if( string::IsEmpty(id))
  275. return;
  276. if( EditMode_IsOn())
  277. return;
  278. if( false )
  279. {
  280. }
  281. else
  282. {
  283. LogicDebugError("Invalid command name: \"%s\"",id);
  284. }
  285. }
  286. static const char *_desc =
  287. "GUI Table\n\n"
  288. " Use to display game scores";
  289. MOP_BEGINLISTCG(GUITable, "ScoreTable", '1.00', 2000, _desc, "Interface")
  290. MOP_FLOATEXC("Anim time", 0.5f, 0.0f, 1.0f, "Время анимации смены позиции элемента")
  291. MOP_ARRAYBEG("Elements", 0, 100)
  292. MOP_STRINGC("Panel", "", "Контейнер для элемента")
  293. MOP_FLOAT("X", 0.0f)
  294. MOP_FLOAT("Y", 0.0f)
  295. MOP_STRINGC("Number", "", "Имя переменной из базы")
  296. MOP_STRINGC("Activity", "", "Имя переменной из базы, если переменная установлена и меньше или равна нулю, не показывать данный пункт")
  297. MOP_STRINGC("Widget", "", "Виджет для отображения значения переменной")
  298. MOP_ARRAYEND
  299. MOP_BOOLC("Show", false, "Показать таблицу")
  300. MOP_ENDLIST(GUITable)