newobject.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. //****************************************************************
  2. #include "newobject.h"
  3. #include "mainwindow.h"
  4. #include "..\attributes\AttributeList.h"
  5. #define WINDOW_POSX 100
  6. #define WINDOW_POSY 100
  7. #define WINDOW_WIDTH 512
  8. #define WINDOW_HEIGHT 384
  9. #define DEFAULT_GROUP_NAME "Default"
  10. extern IMission* miss;
  11. extern MissionEditor* sMission;
  12. extern TMainWindow* MainWindow;
  13. extern TreeNodesPool* globalNodesPool;
  14. bool bCanCreate = false;
  15. MissionEditor::tAvailableMO* cSelectedMissionTemplate = NULL;
  16. char Temp8K[8192];
  17. char CutName[8192];
  18. bool ExistInMission (const char* name)
  19. {
  20. return miss->FindObject(ConstString(name), MOSafePointer());
  21. /*
  22. MGIterator& iterator = miss->GroupIterator (MG_OBJECTS, _FL_);
  23. for (;!iterator.IsDone();iterator.Next())
  24. {
  25. MOSafePointer mo = iterator.Get ();
  26. const char* mName = mo->GetObjectID ();
  27. if (crt_stricmp (mName, name) == 0) return true;
  28. }
  29. iterator.Release ();
  30. return false;
  31. */
  32. }
  33. char* MakeUniqueName (const char* Name)
  34. {
  35. // Сохраняем во временный буффер
  36. crt_snprintf (Temp8K, ARRSIZE(Temp8K), "%s", Name);
  37. if (!ExistInMission(Temp8K)) return Temp8K;
  38. int slen = strlen (Temp8K);
  39. for (int n = 0; n < slen; n++)
  40. {
  41. char cur_char = Temp8K[slen-n-1];
  42. if ((cur_char < '0') || (cur_char > '9')) break;
  43. }
  44. // Выбираем номер :)
  45. int unique_num = 0;
  46. if (n > 0)
  47. {
  48. static char Temp8K_Digit[8192];
  49. crt_strcpy (Temp8K_Digit, 8191, Temp8K + (slen-n));
  50. Temp8K [slen-n] = 0;
  51. unique_num = atoi (Temp8K_Digit);
  52. unique_num++;
  53. }
  54. crt_strncpy (CutName, 8191, Temp8K, 8192);
  55. if (n > 0) crt_snprintf (Temp8K, ARRSIZE(Temp8K), "%s%d", CutName, unique_num);
  56. for (;;)
  57. {
  58. bool NeedMore = false;
  59. if (ExistInMission(Temp8K))
  60. {
  61. crt_snprintf (Temp8K, ARRSIZE(Temp8K), "%s%d", CutName, unique_num);
  62. unique_num++;
  63. NeedMore = true;
  64. }
  65. if (!NeedMore) break;
  66. }
  67. return Temp8K;
  68. }
  69. bool CompareFunc (const string& s1, const string& s2)
  70. {
  71. if (s1 < s2) return true;
  72. return false;
  73. }
  74. TNewObjectWindow::TNewObjectWindow () : GUIWindow (NULL, WINDOW_POSX, WINDOW_POSY, WINDOW_WIDTH, WINDOW_HEIGHT), Groups(_FL_)
  75. {
  76. dwWindowBackColor = 0xFFCECEE8;
  77. bCanCreate = false;
  78. bPopupStyle = true;
  79. bAlwaysOnTop = true;
  80. icon->Load ("newobject");
  81. Caption = "Create mission object";
  82. pFont->SetSize (16);
  83. txtObjectName = NEW GUIEdit (this, 10, 5, 365, 20);
  84. txtObjectName->pFont->SetName("arialcyrsmall");
  85. txtObjectName->OnAccept = (CONTROL_EVENT)&TNewObjectWindow::NameChanged;
  86. txtObjectName->Hint = "Object name";
  87. txtObjectName->Flat = true;
  88. /*
  89. TreeView1 = NEW GUITreeView (this, 340, 36, WINDOW_WIDTH-320-30, WINDOW_HEIGHT-80);
  90. TreeView1->FontColor = 0xFF000000;
  91. TreeView1->pFont->SetName("arialcyrsmall");
  92. TreeView1->SetImagesArray ("gtree");
  93. TreeView1->OnChange = (CONTROL_EVENT)SelChange;
  94. TreeView1->OnDblClick = (CONTROL_EVENT)SelectionChange;
  95. TreeView1->Hint = "Object parameters";
  96. TreeView1->MakeFlat(true);
  97. TreeView1->OnBeforeHintShow = (CONTROL_EVENT)TreeShowHint;
  98. */
  99. btnOK = NEW GUIButton (this, 140, WINDOW_HEIGHT-38, 110, 30);
  100. btnOK->Caption = "Create";
  101. btnOK->Glyph->Load ("lamp");
  102. btnOK->FontColor = 0xFF000000;
  103. btnOK->pFont->SetSize (16);
  104. btnOK->OnMousePressed = (CONTROL_EVENT)&TNewObjectWindow::btnCreatePressed;
  105. btnOK->FlatButton = true;
  106. btnCancel = NEW GUIButton (this, 20, WINDOW_HEIGHT-38, 110, 30);
  107. btnCancel->Caption = "< Back";
  108. //btnCancel->Glyph->Load ("exit");
  109. btnCancel->FontColor = 0xFF000000;
  110. btnCancel->pFont->SetSize (16);
  111. btnCancel->OnMousePressed = (CONTROL_EVENT)&TNewObjectWindow::btnCancelPressed;
  112. btnCancel->FlatButton = true;
  113. //AvailObj = NEW GUIComboBox (this, 5, 5, 200, 20);;
  114. //AvailObj->OnChange = (CONTROL_EVENT)MissionObjectSelected;
  115. //GUIListBox*
  116. ObjectsList = NEW GUIListBox (this, 230, 36, 260, WINDOW_HEIGHT-80);
  117. ObjectsList->pFont->SetName("arialcyrsmall");
  118. ObjectsList->bCaptureKeyboard = false;
  119. ObjectsList->OnChange = (CONTROL_EVENT)&TNewObjectWindow::MissionObjectSelected;
  120. ObjectsList->Hint = "Available mission objects";
  121. ObjectsList->OnBeforeHintShow= (CONTROL_EVENT)&TNewObjectWindow::ObjectShowHint;
  122. ObjectsList->MakeFlat(true);
  123. ObjectsList->OnMouseDBLClick = (CONTROL_EVENT)&TNewObjectWindow::btnCreatePressed;
  124. GroupList = NEW GUIListBox (this, 10, 36, 200, WINDOW_HEIGHT-80);
  125. GroupList->pFont->SetName("arialcyrsmall");
  126. GroupList->bCaptureKeyboard = false;
  127. GroupList->OnChange = (CONTROL_EVENT)&TNewObjectWindow::GroupChanged;
  128. GroupList->Hint = "Object groups...";
  129. GroupList->MakeFlat(true);
  130. //GroupList->OnMouseDBLClick = (CONTROL_EVENT)btnCreatePressed;
  131. Groups.DelAll();
  132. for (DWORD n = 0; n < sMission->AvailableMO.Size(); n++)
  133. {
  134. MissionEditor::tAvailableMO* availMO = &sMission->AvailableMO[n];
  135. const char* ObjectGroup = availMO->Params->GetGroup();
  136. AddGroup(ObjectGroup);
  137. //availMO->
  138. //ObjectsList->Items.Add (availMO->Name);
  139. }
  140. //ObjectsList->Items.Sort(CompareFunc);
  141. ObjectsList->Items.Clear();
  142. for (n = 0; n < Groups.Size(); n++)
  143. {
  144. GroupList->Items.Add (Groups[n].c_str());
  145. }
  146. GroupList->Items.Sort(CompareFunc);
  147. GroupChanged(NULL);
  148. SetScreenCenter ();
  149. }
  150. void _cdecl TNewObjectWindow::GroupChanged (GUIControl* sender)
  151. {
  152. int index = GroupList->SelectedLine;
  153. if (index == -1) return;
  154. string MasterGroup = GroupList->Items[index];
  155. ObjectsList->Items.Clear();
  156. for (DWORD n = 0; n < sMission->AvailableMO.Size(); n++)
  157. {
  158. MissionEditor::tAvailableMO* availMO = &sMission->AvailableMO[n];
  159. string ObjectGroup = DEFAULT_GROUP_NAME;
  160. const char* szGName = availMO->Params->GetGroup();
  161. if (szGName) ObjectGroup = szGName;
  162. if (ObjectGroup == MasterGroup)
  163. {
  164. ObjectsList->Items.Add (availMO->Name);
  165. }
  166. }
  167. ObjectsList->Items.Sort(CompareFunc);
  168. }
  169. void TNewObjectWindow::AddGroup (const char* szGroup)
  170. {
  171. string GroupName = DEFAULT_GROUP_NAME;
  172. if (szGroup != NULL) GroupName = szGroup;
  173. for (dword i = 0; i < Groups.Size(); i++)
  174. {
  175. if (Groups[i] == GroupName) return;
  176. }
  177. Groups.Add(GroupName);
  178. }
  179. void TNewObjectWindow::OnCreate ()
  180. {
  181. //txtObjectName->SetFocus ();
  182. }
  183. TNewObjectWindow::~TNewObjectWindow ()
  184. {
  185. }
  186. void _cdecl TNewObjectWindow::OnAcceptNewObjectName (GUIControl* sender)
  187. {
  188. }
  189. void _cdecl TNewObjectWindow::SelectionChange (GUIControl* sender)
  190. {
  191. }
  192. GUITreeNode* TNewObjectWindow::FindFirstFolder (GUITreeNode* m_node)
  193. {
  194. if (m_node->Tag == TAG_FOLDER) return m_node;
  195. if (m_node->Parent == NULL) return NULL;
  196. return FindFirstFolder (m_node->Parent);
  197. }
  198. void _cdecl TNewObjectWindow::btnCreatePressed (GUIControl* sender)
  199. {
  200. //if (!pMissionObject) return;
  201. if (!bCanCreate) return;
  202. if (txtObjectName->Text.IsEmpty())
  203. {
  204. return;
  205. }
  206. MissionEditor::tAvailableMO* pMissionObject = NULL;
  207. int index = ObjectsList->SelectedLine;
  208. if (index == -1) return;
  209. for (DWORD n = 0; n < sMission->AvailableMO.Size(); n++)
  210. {
  211. pMissionObject = &sMission->AvailableMO[n];
  212. if (crt_stricmp (pMissionObject->Name, ObjectsList->Items[index].GetBuffer()) == 0)
  213. {
  214. break;
  215. }
  216. }
  217. //api->Trace("!!!!!!!!!!!!!!! Close window - 0x%08X", this);
  218. MOPWriter wrt(pMissionObject->Params->GetVersion (), MakeUniqueName (txtObjectName->Text.GetBuffer()));
  219. pMissionObject->AttrList->AddToWriter (wrt);
  220. MOSafePointer mo;
  221. miss->CreateObject (mo, pMissionObject->ClassName, wrt.Reader ());
  222. //mo = NULL;
  223. if (!mo.Validate())
  224. {
  225. Application->MessageBox (" Can't create object !!! ", "Error", GUIMB_OK);
  226. //_asm int 3;
  227. return;
  228. }
  229. //OnAcceptNewObjectName (sender);
  230. MissionEditor::tCreatedMO* nEntry = &sMission->AddCreatedMissionObjectStruct();
  231. GUITreeNode* tn = MainWindow->TreeView1->GetSelectedNode ();
  232. if (tn)
  233. {
  234. GUITreeNode* upperfolder = FindFirstFolder (tn);
  235. if (upperfolder)
  236. {
  237. const char* fullname = upperfolder->GetFullPath();
  238. nEntry->PathInTree = fullname;
  239. //strncpy (nEntry->PathInTree, fullname, MAXOBJECTPATH);
  240. } else
  241. {
  242. nEntry->PathInTree = "";
  243. }
  244. } else
  245. {
  246. nEntry->PathInTree = "";
  247. }
  248. GUITreeNode* treenode = globalNodesPool->CreateNode();
  249. treenode->SetText(mo.Ptr()->GetObjectID ().c_str());
  250. treenode->Image->Load ("meditor\\mobject");
  251. treenode->Tag = TAG_OBJECT;
  252. treenode->Data = nEntry;
  253. treenode->CanDrop = false;
  254. GUITreeNode* folder = MainWindow->TreeView1->FindItem (nEntry->PathInTree);
  255. if (folder)
  256. {
  257. folder->Childs.Add (treenode);
  258. } else
  259. {
  260. MainWindow->TreeView1->Items->Add (treenode);
  261. }
  262. nEntry->Version = pMissionObject->Params->GetVersion ();
  263. nEntry->pObject = mo;
  264. nEntry->AttrList = NEW AttributeList;
  265. nEntry->Level = pMissionObject->Params->GetLevel ();
  266. nEntry->ClassName = pMissionObject->ClassName;
  267. //strncpy (nEntry->ClassName, pMissionObject->ClassName, MAX_ENTITY_NAME);
  268. nEntry->AttrList->CreateFromList (pMissionObject->AttrList);
  269. nEntry->AttrList->AddToTree (treenode, globalNodesPool);
  270. //Записываем в каждый аттрибут указатель
  271. // на объект...
  272. nEntry->AttrList->SetMasterData (nEntry);
  273. pMissionObject->AttrList->BeforeDelete ();
  274. pMissionObject = NULL;
  275. Close (this);
  276. }
  277. void _cdecl TNewObjectWindow::btnCancelPressed (GUIControl* sender)
  278. {
  279. Close (this);
  280. }
  281. void _cdecl TNewObjectWindow::NameChanged (GUIControl* sender)
  282. {
  283. txtObjectName->Text = MakeUniqueName (txtObjectName->Text);
  284. }
  285. void _cdecl TNewObjectWindow::MissionObjectSelected (GUIControl* sender)
  286. {
  287. bCanCreate = false;
  288. int index = ObjectsList->SelectedLine;
  289. if (index == -1) return;
  290. bCanCreate = true;
  291. txtObjectName->Text = MakeUniqueName (ObjectsList->Items[index].GetBuffer());
  292. NameChanged(NULL);
  293. txtObjectName->SetFocus();
  294. txtObjectName->SelectText(0, txtObjectName->Text.Len());
  295. }
  296. void TNewObjectWindow::KeyPressed(int Key, bool bSysKey)
  297. {
  298. if (!bSysKey) return;
  299. // if (!IsActive()) return;
  300. if (!IsActive) return;
  301. if (Key == VK_ESCAPE)
  302. {
  303. btnCancelPressed (this);
  304. }
  305. if (Key == 13)
  306. {
  307. btnCreatePressed (this);
  308. }
  309. }
  310. void _cdecl TNewObjectWindow::ObjectShowHint (GUIControl* sender)
  311. {
  312. // Получить узел находящийся под курсором
  313. int Line = ObjectsList->GetElementNumAtPos(Application->GetCursor()->GetPosition());
  314. if (Line < 0)
  315. {
  316. ObjectsList->Hint = " ";
  317. ObjectsList->OnHintShow_RetValue = false;
  318. } else
  319. {
  320. string TextHint = sMission->GetCommentForName(ObjectsList->Items[Line].c_str());
  321. //Если подсказка не пустая...
  322. if (ObjectsList->Hint != " ")
  323. {
  324. // Сравнить, то, что мы хотим показать
  325. // с тем, что мы уже показываем
  326. if (TextHint != ObjectsList->Hint)
  327. {
  328. //Если подсказки разные погасить, на время :)
  329. ObjectsList->OnHintShow_RetValue = false;
  330. }
  331. }
  332. // Присвоить нужный текст...
  333. ObjectsList->Hint = TextHint;
  334. }
  335. }