Win_ent.cpp 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "stdafx.h"
  19. #include "qe3.h"
  20. #include "entityw.h"
  21. #include "TexWnd.h"
  22. #include "WaveOpen.h"
  23. int rgIds[EntLast] = {
  24. IDC_E_LIST,
  25. IDC_E_COMMENT,
  26. IDC_CHECK1,
  27. IDC_CHECK2,
  28. IDC_CHECK3,
  29. IDC_CHECK4,
  30. IDC_CHECK5,
  31. IDC_CHECK6,
  32. IDC_CHECK7,
  33. IDC_CHECK8,
  34. IDC_CHECK9,
  35. IDC_CHECK10,
  36. IDC_CHECK11,
  37. IDC_CHECK12,
  38. IDC_E_PROPS,
  39. IDC_E_0,
  40. IDC_E_45,
  41. IDC_E_90,
  42. IDC_E_135,
  43. IDC_E_180,
  44. IDC_E_225,
  45. IDC_E_270,
  46. IDC_E_315,
  47. IDC_E_UP,
  48. IDC_E_DOWN,
  49. IDC_E_DELPROP,
  50. IDC_STATIC_KEY,
  51. IDC_E_KEY_FIELD,
  52. IDC_STATIC_VALUE,
  53. IDC_E_VALUE_FIELD,
  54. IDC_E_COLOR,
  55. IDC_BTN_ASSIGNSOUND,
  56. IDC_BTN_ASSIGNMODEL
  57. };
  58. HWND hwndEnt[EntLast];
  59. CTabCtrl g_wndTabs;
  60. int inspector_mode; // W_TEXTURE, W_ENTITY, or W_CONSOLE
  61. qboolean multiple_entities;
  62. entity_t *edit_entity;
  63. BOOL CALLBACK EntityWndProc(
  64. HWND hwndDlg, // handle to dialog box
  65. UINT uMsg, // message
  66. WPARAM wParam, // first message parameter
  67. LPARAM lParam); // second message parameter
  68. void SizeEntityDlg(int iWidth, int iHeight);
  69. void AddProp();
  70. void GetTexMods(void);
  71. LRESULT (CALLBACK* OldFieldWindowProc) (HWND, UINT, WPARAM, LPARAM);
  72. LRESULT (CALLBACK* OldEntityListWindowProc) (HWND, UINT, WPARAM, LPARAM);
  73. /*
  74. =========================
  75. FieldWndProc
  76. Just to handle tab and enter...
  77. =========================
  78. */
  79. BOOL CALLBACK FieldWndProc(
  80. HWND hwnd,
  81. UINT uMsg,
  82. WPARAM wParam,
  83. LPARAM lParam)
  84. {
  85. switch (uMsg)
  86. {
  87. case WM_CHAR:
  88. if (LOWORD(wParam) == VK_TAB)
  89. return FALSE;
  90. if (LOWORD(wParam) == VK_RETURN)
  91. return FALSE;
  92. if (LOWORD(wParam) == VK_ESCAPE)
  93. {
  94. SetFocus (g_qeglobals.d_hwndCamera);
  95. return FALSE;
  96. }
  97. break;
  98. case WM_KEYDOWN:
  99. if (LOWORD(wParam) == VK_TAB)
  100. {
  101. if (hwnd == hwndEnt[EntKeyField])
  102. {
  103. SendMessage (hwndEnt[EntValueField], WM_SETTEXT, 0, (long)"");
  104. SetFocus (hwndEnt[EntValueField]);
  105. }
  106. else
  107. SetFocus (hwndEnt[EntKeyField]);
  108. }
  109. if (LOWORD(wParam) == VK_RETURN)
  110. {
  111. if (hwnd == hwndEnt[EntKeyField])
  112. {
  113. SendMessage (hwndEnt[EntValueField], WM_SETTEXT, 0, (long)"");
  114. SetFocus (hwndEnt[EntValueField]);
  115. }
  116. else
  117. {
  118. AddProp ();
  119. SetFocus (g_qeglobals.d_hwndCamera);
  120. }
  121. }
  122. break;
  123. // case WM_NCHITTEST:
  124. case WM_LBUTTONDOWN:
  125. SetFocus (hwnd);
  126. break;
  127. }
  128. return CallWindowProc (OldFieldWindowProc, hwnd, uMsg, wParam, lParam);
  129. }
  130. /*
  131. =========================
  132. EntityListWndProc
  133. Just to handle enter...
  134. =========================
  135. */
  136. BOOL CALLBACK EntityListWndProc(
  137. HWND hwnd,
  138. UINT uMsg,
  139. WPARAM wParam,
  140. LPARAM lParam)
  141. {
  142. switch (uMsg)
  143. {
  144. case WM_KEYDOWN:
  145. if (LOWORD(wParam) == VK_RETURN)
  146. {
  147. SendMessage ( g_qeglobals.d_hwndEntity,
  148. WM_COMMAND,
  149. (LBN_DBLCLK<<16) + IDC_E_LIST,
  150. 0 );
  151. return 0;
  152. }
  153. break;
  154. }
  155. return CallWindowProc (OldEntityListWindowProc, hwnd, uMsg, wParam, lParam);
  156. }
  157. /*
  158. ================
  159. GetEntityControls
  160. Finds the controls from the dialog and
  161. moves them to the window
  162. ================
  163. */
  164. void GetEntityControls(HWND ghwndEntity)
  165. {
  166. int i;
  167. for (i = 0; i < EntLast; i++)
  168. {
  169. if (i == EntList || i == EntProps || i == EntComment)
  170. continue;
  171. if (i == EntKeyField || i == EntValueField)
  172. continue;
  173. hwndEnt[i] = GetDlgItem(ghwndEntity, rgIds[i]);
  174. if (hwndEnt[i])
  175. {
  176. SetParent (hwndEnt[i], g_qeglobals.d_hwndEntity );
  177. SendMessage(hwndEnt[i], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
  178. }
  179. }
  180. // SetParent apears to not modify some internal state
  181. // on listboxes, so create it from scratch...
  182. hwndEnt[EntList] = CreateWindow ("listbox", NULL,
  183. LBS_STANDARD | LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT
  184. | WS_VSCROLL | WS_CHILD | WS_VISIBLE,
  185. 5, 5, 180, 99,
  186. g_qeglobals.d_hwndEntity,
  187. (HMENU)IDC_E_LIST,
  188. g_qeglobals.d_hInstance,
  189. NULL);
  190. if (!hwndEnt[EntList])
  191. Error ("CreateWindow failed");
  192. hwndEnt[EntProps] = CreateWindow ("listbox", NULL,
  193. LBS_STANDARD | LBS_NOINTEGRALHEIGHT | LBS_USETABSTOPS
  194. | WS_VSCROLL | WS_CHILD | WS_VISIBLE,
  195. 5, 100, 180, 99,
  196. g_qeglobals.d_hwndEntity,
  197. (HMENU)IDC_E_PROPS,
  198. g_qeglobals.d_hInstance,
  199. NULL);
  200. if (!hwndEnt[EntProps])
  201. Error ("CreateWindow failed");
  202. hwndEnt[EntComment] = CreateWindow ("edit", NULL,
  203. ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER,
  204. 5, 100, 180, 99,
  205. g_qeglobals.d_hwndEntity,
  206. (HMENU)IDC_E_COMMENT,
  207. g_qeglobals.d_hInstance,
  208. NULL);
  209. if (!hwndEnt[EntComment])
  210. Error ("CreateWindow failed");
  211. hwndEnt[EntKeyField] = CreateWindow ("edit", NULL,
  212. WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
  213. 5, 100, 180, 99,
  214. g_qeglobals.d_hwndEntity,
  215. (HMENU)IDC_E_KEY_FIELD,
  216. g_qeglobals.d_hInstance,
  217. NULL);
  218. if (!hwndEnt[EntKeyField])
  219. Error ("CreateWindow failed");
  220. hwndEnt[EntValueField] = CreateWindow ("edit", NULL,
  221. WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
  222. 5, 100, 180, 99,
  223. g_qeglobals.d_hwndEntity,
  224. (HMENU)IDC_E_VALUE_FIELD,
  225. g_qeglobals.d_hInstance,
  226. NULL);
  227. if (!hwndEnt[EntValueField])
  228. Error ("CreateWindow failed");
  229. g_wndTabs.SubclassDlgItem(IDC_TAB_MODE, CWnd::FromHandle(ghwndEntity));
  230. hwndEnt[EntTab] = g_wndTabs.GetSafeHwnd();
  231. g_wndTabs.InsertItem(0, "Groups");
  232. ::SetParent(g_wndTabs.GetSafeHwnd(), g_qeglobals.d_hwndEntity);
  233. if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3)
  234. {
  235. g_qeglobals.d_hwndEdit = CreateWindow ("edit", NULL, ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER,
  236. 5, 100, 180, 99, g_qeglobals.d_hwndEntity, (HMENU)IDC_E_STATUS,
  237. g_qeglobals.d_hInstance, NULL);
  238. if (!g_qeglobals.d_hwndEdit)
  239. Error ("CreateWindow failed");
  240. g_wndTabs.InsertItem(0, "Console");
  241. g_wndTabs.InsertItem(0, "Textures");
  242. }
  243. g_wndTabs.InsertItem(0, "Entities");
  244. g_wndTabs.ShowWindow(SW_SHOW);
  245. #if 0
  246. for (i=0 ; i<12 ; i++)
  247. {
  248. hwndEnt[EntCheck1 + i] = CreateWindow ("button", NULL,
  249. BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE,
  250. 5, 100, 180, 99,
  251. entwindow,
  252. (HMENU)IDC_E_STATUS,
  253. main_instance,
  254. NULL);
  255. if (!hwndEnt[EntCheck1 + i])
  256. Error ("CreateWindow failed");
  257. }
  258. #endif
  259. SendMessage(hwndEnt[EntList], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
  260. SendMessage(hwndEnt[EntProps], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
  261. SendMessage(hwndEnt[EntComment], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
  262. SendMessage(hwndEnt[EntKeyField], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
  263. SendMessage(hwndEnt[EntValueField], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
  264. SendMessage(hwndEnt[EntTab], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
  265. if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3)
  266. SendMessage(g_qeglobals.d_hwndEdit, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
  267. }
  268. /*
  269. ===============================================================
  270. ENTITY WINDOW
  271. ===============================================================
  272. */
  273. void FillClassList (void)
  274. {
  275. eclass_t *pec;
  276. int iIndex;
  277. SendMessage(hwndEnt[EntList], LB_RESETCONTENT, 0 , 0);
  278. for (pec = eclass ; pec ; pec = pec->next)
  279. {
  280. iIndex = SendMessage(hwndEnt[EntList], LB_ADDSTRING, 0 , (LPARAM)pec->name);
  281. SendMessage(hwndEnt[EntList], LB_SETITEMDATA, iIndex, (LPARAM)pec);
  282. }
  283. }
  284. /*
  285. ==============
  286. WEnt_Create
  287. ==============
  288. */
  289. void WEnt_Create (HINSTANCE hInstance)
  290. {
  291. WNDCLASS wc;
  292. /* Register the camera class */
  293. memset (&wc, 0, sizeof(wc));
  294. wc.style = CS_NOCLOSE | CS_OWNDC;
  295. wc.lpfnWndProc = (WNDPROC)EntityWndProc;
  296. wc.cbClsExtra = 0;
  297. wc.cbWndExtra = 0;
  298. wc.hInstance = hInstance;
  299. wc.hIcon = 0;
  300. wc.hCursor = LoadCursor (NULL,IDC_ARROW);
  301. wc.hbrBackground = (HBRUSH)GetStockObject (LTGRAY_BRUSH);
  302. wc.lpszMenuName = NULL;
  303. wc.lpszClassName = ENT_WINDOW_CLASS;
  304. RegisterClass (&wc);
  305. int nStyle = (g_pParentWnd->CurrentStyle() == QR_QE4) ? QE3_STYLE : QE3_STYLE2;
  306. g_qeglobals.d_hwndEntity = CreateWindow (ENT_WINDOW_CLASS ,
  307. "Entity",
  308. nStyle,
  309. 20,
  310. 20,
  311. 100,
  312. 480, // size
  313. g_qeglobals.d_hwndMain, // parent
  314. 0, // no menu
  315. hInstance,
  316. NULL);
  317. if (!g_qeglobals.d_hwndEntity )
  318. Error ("Couldn't create Entity window");
  319. }
  320. /*
  321. ==============
  322. CreateEntityWindow
  323. ==============
  324. */
  325. BOOL CreateEntityWindow(HINSTANCE hInstance)
  326. {
  327. HWND hwndEntityPalette;
  328. inspector_mode = W_ENTITY;
  329. WEnt_Create (hInstance);
  330. hwndEntityPalette = CreateDialog(hInstance, (char *)IDD_ENTITY, g_qeglobals.d_hwndMain, (DLGPROC)NULL);
  331. if (!hwndEntityPalette)
  332. Error ("CreateDialog failed");
  333. GetEntityControls (hwndEntityPalette);
  334. DestroyWindow (hwndEntityPalette);
  335. OldFieldWindowProc = (WNDPROC)GetWindowLong (hwndEnt[EntKeyField], GWL_WNDPROC);
  336. SetWindowLong (hwndEnt[EntKeyField], GWL_WNDPROC, (long)FieldWndProc);
  337. SetWindowLong (hwndEnt[EntValueField], GWL_WNDPROC, (long)FieldWndProc);
  338. OldEntityListWindowProc = (WNDPROC)GetWindowLong (hwndEnt[EntList], GWL_WNDPROC);
  339. SetWindowLong (hwndEnt[EntList], GWL_WNDPROC, (long)EntityListWndProc);
  340. FillClassList ();
  341. LoadWindowPlacement(g_qeglobals.d_hwndEntity, "EntityWindowPlace");
  342. ShowWindow (g_qeglobals.d_hwndEntity, SW_HIDE);
  343. SetInspectorMode (W_CONSOLE);
  344. return TRUE;
  345. }
  346. /*
  347. ==============
  348. SetInspectorMode
  349. ==============
  350. */
  351. void SetInspectorMode(int iType)
  352. {
  353. RECT rc;
  354. HMENU hMenu = GetMenu( g_qeglobals.d_hwndMain );
  355. if ((g_pParentWnd->CurrentStyle() == QR_SPLIT || g_pParentWnd->CurrentStyle() == QR_SPLITZ) && (iType == W_TEXTURE || iType == W_CONSOLE))
  356. return;
  357. // Is the caller asking us to cycle to the next window?
  358. if (iType == -1)
  359. {
  360. if (inspector_mode == W_ENTITY)
  361. iType = W_TEXTURE;
  362. else if (inspector_mode == W_TEXTURE)
  363. iType = W_CONSOLE;
  364. else if (inspector_mode == W_CONSOLE)
  365. iType = W_GROUP;
  366. else
  367. iType = W_ENTITY;
  368. }
  369. inspector_mode = iType;
  370. switch(iType)
  371. {
  372. case W_ENTITY:
  373. SetWindowText(g_qeglobals.d_hwndEntity, "Entity");
  374. EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_ENABLED | MF_BYCOMMAND );
  375. // entity is always first in the inspector
  376. g_wndTabs.SetCurSel(0);
  377. break;
  378. case W_TEXTURE:
  379. SetWindowText(g_qeglobals.d_hwndEntity, "Textures");
  380. g_pParentWnd->GetTexWnd()->FocusEdit();
  381. EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_GRAYED | MF_DISABLED | MF_BYCOMMAND );
  382. if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3)
  383. g_wndTabs.SetCurSel(1);
  384. break;
  385. case W_CONSOLE:
  386. SetWindowText(g_qeglobals.d_hwndEntity, "Console");
  387. EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_GRAYED | MF_DISABLED | MF_BYCOMMAND );
  388. if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3)
  389. g_wndTabs.SetCurSel(2);
  390. break;
  391. case W_GROUP:
  392. SetWindowText(g_qeglobals.d_hwndEntity, "Groups");
  393. EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_GRAYED | MF_DISABLED | MF_BYCOMMAND );
  394. if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3)
  395. g_wndTabs.SetCurSel(3);
  396. else
  397. g_wndTabs.SetCurSel(1);
  398. break;
  399. default:
  400. break;
  401. }
  402. GetWindowRect (g_qeglobals.d_hwndEntity, &rc);
  403. SizeEntityDlg( rc.right - rc.left - 8, rc.bottom - rc.top - 20);
  404. // InvalidateRect(entwindow, NULL, true);
  405. // ShowWindow (entwindow, SW_SHOW);
  406. // UpdateWindow (entwindow);
  407. HWND hFlag = (g_pParentWnd->CurrentStyle() == QR_QE4) ? HWND_TOP : HWND_TOPMOST;
  408. SetWindowPos( g_qeglobals.d_hwndEntity, hFlag, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOSIZE | SWP_NOMOVE );
  409. RedrawWindow (g_qeglobals.d_hwndEntity, NULL, NULL, RDW_ERASE | RDW_INVALIDATE| RDW_ERASENOW | RDW_UPDATENOW | RDW_ALLCHILDREN);
  410. }
  411. // SetKeyValuePairs
  412. //
  413. // Reset the key/value (aka property) listbox and fill it with the
  414. // k/v pairs from the entity being edited.
  415. //
  416. void SetKeyValuePairs (bool bClearMD3)
  417. {
  418. epair_t *pep;
  419. RECT rc;
  420. char sz[4096];
  421. if (edit_entity == NULL)
  422. return;
  423. // set key/value pair list
  424. GetWindowRect(hwndEnt[EntProps], &rc);
  425. SendMessage(hwndEnt[EntProps], LB_SETCOLUMNWIDTH, (rc.right - rc.left)/2, 0);
  426. SendMessage(hwndEnt[EntProps], LB_RESETCONTENT, 0, 0);
  427. // Walk through list and add pairs
  428. for (pep = edit_entity->epairs ; pep ; pep = pep->next)
  429. {
  430. // if the key is less than 8 chars, add a tab for alignment
  431. if (strlen(pep->key) > 8)
  432. sprintf (sz, "%s\t%s", pep->key, pep->value);
  433. else
  434. sprintf (sz, "%s\t\t%s", pep->key, pep->value);
  435. SendMessage(hwndEnt[EntProps], LB_ADDSTRING, 0, (LPARAM)sz);
  436. }
  437. if (edit_entity->eclass->nShowFlags & ECLASS_MISCMODEL)
  438. {
  439. // if this is a misc_model
  440. // cache the md3 for display later
  441. if (bClearMD3)
  442. {
  443. edit_entity->md3Class = NULL;
  444. }
  445. //char *pModel = ValueForKey(edit_entity, "model");
  446. /*
  447. if (pModel != NULL)
  448. {
  449. GetCachedModel(pModel, vMin, vMax);
  450. }
  451. */
  452. }
  453. Sys_UpdateWindows(W_CAMERA | W_XY);
  454. }
  455. // SetSpawnFlags
  456. //
  457. // Update the checkboxes to reflect the flag state of the entity
  458. //
  459. void SetSpawnFlags(void)
  460. {
  461. int f;
  462. int i;
  463. int v;
  464. f = atoi(ValueForKey (edit_entity, "spawnflags"));
  465. for (i=0 ; i<12 ; i++)
  466. {
  467. v = !!(f&(1<<i));
  468. SendMessage(hwndEnt[EntCheck1+i], BM_SETCHECK, v, 0);
  469. }
  470. }
  471. // GetSpawnFlags
  472. //
  473. // Update the entity flags to reflect the state of the checkboxes
  474. //
  475. void GetSpawnFlags(void)
  476. {
  477. int f;
  478. int i, v;
  479. char sz[32];
  480. f = 0;
  481. for (i=0 ; i<12 ; i++)
  482. {
  483. v = SendMessage(hwndEnt[EntCheck1+i], BM_GETCHECK, 0, 0);
  484. f |= v<<i;
  485. }
  486. sprintf (sz, "%i", f);
  487. if (multiple_entities)
  488. {
  489. brush_t *b;
  490. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  491. SetKeyValue(b->owner, "spawnflags", sz);
  492. }
  493. else
  494. SetKeyValue (edit_entity, "spawnflags", sz);
  495. SetKeyValuePairs ();
  496. }
  497. // UpdateSel
  498. //
  499. // Update the listbox, checkboxes and k/v pairs to reflect the new selection
  500. //
  501. BOOL UpdateSel(int iIndex, eclass_t *pec)
  502. {
  503. int i;
  504. brush_t *b;
  505. if (selected_brushes.next == &selected_brushes)
  506. {
  507. edit_entity = world_entity;
  508. multiple_entities = false;
  509. }
  510. else
  511. {
  512. edit_entity = selected_brushes.next->owner;
  513. for (b=selected_brushes.next->next ; b != &selected_brushes ; b=b->next)
  514. {
  515. if (b->owner != edit_entity)
  516. {
  517. multiple_entities = true;
  518. break;
  519. }
  520. }
  521. }
  522. if (iIndex != LB_ERR)
  523. SendMessage(hwndEnt[EntList], LB_SETCURSEL, iIndex, 0);
  524. if (pec == NULL)
  525. return TRUE;
  526. // Set up the description
  527. SendMessage(hwndEnt[EntComment], WM_SETTEXT, 0,
  528. (LPARAM)TranslateString(pec->comments));
  529. for (i=0 ; i<8 ; i++)
  530. {
  531. HWND hwnd = hwndEnt[EntCheck1+i];
  532. if (pec->flagnames[i] && pec->flagnames[i][0] != 0)
  533. {
  534. EnableWindow(hwnd, TRUE);
  535. SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)pec->flagnames[i]);
  536. } else {
  537. // disable check box
  538. SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)" ");
  539. EnableWindow(hwnd, FALSE);
  540. }
  541. }
  542. SetSpawnFlags();
  543. SetKeyValuePairs();
  544. return TRUE;
  545. }
  546. BOOL UpdateEntitySel(eclass_t *pec)
  547. {
  548. int iIndex;
  549. iIndex = (int)SendMessage(hwndEnt[EntList], LB_FINDSTRINGEXACT,
  550. (WPARAM)-1, (LPARAM)pec->name);
  551. return UpdateSel(iIndex, pec);
  552. }
  553. // CreateEntity
  554. //
  555. // Creates a new entity based on the currently selected brush and entity type.
  556. //
  557. void CreateEntity(void)
  558. {
  559. eclass_t *pecNew;
  560. entity_t *petNew;
  561. int i;
  562. HWND hwnd;
  563. char sz[1024];
  564. // check to make sure we have a brush
  565. if (selected_brushes.next == &selected_brushes)
  566. {
  567. MessageBox(g_qeglobals.d_hwndMain, "You must have a selected brush to create an entity"
  568. , "info", 0);
  569. return;
  570. }
  571. // find out what type of entity we are trying to create
  572. hwnd = hwndEnt[EntList];
  573. i = SendMessage(hwndEnt[EntList], LB_GETCURSEL, 0, 0);
  574. if (i < 0)
  575. {
  576. MessageBox(g_qeglobals.d_hwndMain, "You must have a selected class to create an entity"
  577. , "info", 0);
  578. return;
  579. }
  580. SendMessage(hwnd, LB_GETTEXT, i, (LPARAM)sz);
  581. if (!stricmp(sz, "worldspawn"))
  582. {
  583. MessageBox(g_qeglobals.d_hwndMain, "Can't create an entity with worldspawn.", "info", 0);
  584. return;
  585. }
  586. pecNew = Eclass_ForName(sz, false);
  587. // create it
  588. petNew = Entity_Create(pecNew);
  589. if (petNew == NULL)
  590. {
  591. MessageBox(g_qeglobals.d_hwndMain, "Failed to create entity.", "info", 0);
  592. return;
  593. }
  594. if (selected_brushes.next == &selected_brushes)
  595. edit_entity = world_entity;
  596. else
  597. edit_entity = selected_brushes.next->owner;
  598. SetKeyValuePairs();
  599. Select_Deselect ();
  600. Select_Brush (edit_entity->brushes.onext);
  601. Sys_UpdateWindows(W_ALL);
  602. }
  603. /*
  604. ===============
  605. AddProp
  606. ===============
  607. */
  608. void AddProp()
  609. {
  610. char key[4096];
  611. char value[4096];
  612. if (edit_entity == NULL)
  613. return;
  614. // Get current selection text
  615. SendMessage(hwndEnt[EntKeyField], WM_GETTEXT, sizeof(key)-1, (LPARAM)key);
  616. SendMessage(hwndEnt[EntValueField], WM_GETTEXT, sizeof(value)-1, (LPARAM)value);
  617. if (multiple_entities)
  618. {
  619. brush_t *b;
  620. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  621. SetKeyValue(b->owner, key, value);
  622. }
  623. else
  624. SetKeyValue(edit_entity, key, value);
  625. // refresh the prop listbox
  626. SetKeyValuePairs();
  627. // if it's a plugin entity, perhaps we need to update some drawing parameters
  628. // NOTE: perhaps moving this code to a seperate func would help if we need it in other places
  629. // TODO: we need to call some update func in the IPluginEntity in case model name changes etc.
  630. // ( for the moment only bounding brush is updated ), see UpdateModelBrush in Ritual's Q3Radiant
  631. if (edit_entity->eclass->nShowFlags & ECLASS_PLUGINENTITY)
  632. {
  633. vec3_t mins, maxs;
  634. edit_entity->pPlugEnt->GetBounds( mins, maxs );
  635. // replace old bounding brush by newly computed one
  636. // NOTE: this part is similar to Entity_BuildModelBrush in Ritual's Q3Radiant, it can be
  637. // usefull moved into a seperate func
  638. brush_t *b,*oldbrush;
  639. if (edit_entity->brushes.onext != &edit_entity->brushes)
  640. oldbrush = edit_entity->brushes.onext;
  641. b = Brush_Create (mins, maxs, &edit_entity->eclass->texdef);
  642. Entity_LinkBrush (edit_entity, b);
  643. Brush_Build( b, true );
  644. Select_Deselect();
  645. Brush_AddToList (edit_entity->brushes.onext, &selected_brushes);
  646. if (oldbrush)
  647. Brush_Free( oldbrush );
  648. }
  649. }
  650. /*
  651. ===============
  652. DelProp
  653. ===============
  654. */
  655. void DelProp(void)
  656. {
  657. char sz[4096];
  658. if (edit_entity == NULL)
  659. return;
  660. // Get current selection text
  661. SendMessage(hwndEnt[EntKeyField], WM_GETTEXT, sizeof(sz)-1, (LPARAM)sz);
  662. if (multiple_entities)
  663. {
  664. brush_t *b;
  665. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  666. DeleteKey(b->owner, sz);
  667. }
  668. else
  669. DeleteKey(edit_entity, sz);
  670. // refresh the prop listbox
  671. SetKeyValuePairs();
  672. }
  673. BOOL GetSelectAllCriteria(CString &strKey, CString &strVal) {
  674. char sz[4096];
  675. HWND hwnd = hwndEnt[EntProps];
  676. int i = SendMessage(hwnd, LB_GETCURSEL, 0, 0);
  677. if (i >= 0 && inspector_mode == W_ENTITY) {
  678. SendMessage(hwndEnt[EntKeyField], WM_GETTEXT, sizeof(sz), (LPARAM)sz);
  679. strKey = sz;
  680. SendMessage(hwndEnt[EntValueField], WM_GETTEXT, sizeof(sz), (LPARAM)sz);
  681. strVal = sz;
  682. return TRUE;
  683. }
  684. return FALSE;
  685. }
  686. /*
  687. ===============
  688. EditProp
  689. ===============
  690. */
  691. void EditProp(void)
  692. {
  693. int i;
  694. HWND hwnd;
  695. char sz[4096];
  696. char *val;
  697. if (edit_entity == NULL)
  698. return;
  699. hwnd = hwndEnt[EntProps];
  700. // Get current selection text
  701. i = SendMessage(hwnd, LB_GETCURSEL, 0, 0);
  702. if (i < 0)
  703. return;
  704. SendMessage(hwnd, LB_GETTEXT, i, (LPARAM)sz);
  705. // strip it down to the key name
  706. for(i=0;sz[i] != '\t';i++)
  707. ;
  708. sz[i] = '\0';
  709. val = sz + i + 1;
  710. if (*val == '\t')
  711. val++;
  712. SendMessage(hwndEnt[EntKeyField], WM_SETTEXT, 0, (LPARAM)sz);
  713. SendMessage(hwndEnt[EntValueField], WM_SETTEXT, 0, (LPARAM)val);
  714. }
  715. HDWP defer;
  716. int col;
  717. void MOVE(HWND e, int x, int y, int w, int h, HWND hwndPlacement = HWND_TOP, int swp = SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOZORDER)
  718. {
  719. // defer=DeferWindowPos(defer,e,HWND_TOP,col+(x),y,w,h,SWP_SHOWWINDOW);
  720. // MoveWindow (e, col+x, y, w, h, FALSE);
  721. SetWindowPos (e, hwndPlacement, col+x, y, w, h, swp);
  722. }
  723. /*
  724. ===============
  725. SizeEnitityDlg
  726. Positions all controls so that the active inspector
  727. is displayed correctly and the inactive ones are
  728. off the side
  729. ===============
  730. */
  731. void SizeEntityDlg(int iWidth, int iHeight)
  732. {
  733. int y, x, xCheck, yCheck;
  734. int i, iRow;
  735. int w, h;
  736. if (iWidth < 32 || iHeight < 32)
  737. return;
  738. SendMessage( g_qeglobals.d_hwndEntity, WM_SETREDRAW, 0, 0);
  739. iHeight -= 24;
  740. //==========================================
  741. //
  742. // console
  743. //
  744. if (inspector_mode == W_CONSOLE)
  745. {
  746. col = 0;
  747. }
  748. else
  749. {
  750. col = iWidth;
  751. }
  752. if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3)
  753. MOVE(g_qeglobals.d_hwndEdit, DlgXBorder, DlgYBorder, iWidth - (2 * DlgXBorder), iHeight - (2 * DlgYBorder) );
  754. //==========================================
  755. //
  756. // texture controls
  757. //
  758. if (inspector_mode == W_TEXTURE)
  759. {
  760. col = 0;
  761. }
  762. else
  763. {
  764. col = iWidth;
  765. }
  766. if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3)
  767. MOVE(g_qeglobals.d_hwndTexture, DlgXBorder, DlgYBorder, iWidth - (2 * DlgXBorder), iHeight - (2 * DlgYBorder) );
  768. if (inspector_mode == W_GROUP)
  769. {
  770. col = 0;
  771. }
  772. else
  773. {
  774. col = iWidth;
  775. }
  776. MOVE(g_qeglobals.d_hwndGroup, DlgXBorder, DlgYBorder, iWidth - (2 * DlgXBorder), iHeight - (2 * DlgYBorder) );
  777. //==========================================
  778. //
  779. // entity controls
  780. //
  781. if (inspector_mode == W_ENTITY)
  782. {
  783. col = 0;
  784. }
  785. else
  786. {
  787. col = iWidth;
  788. }
  789. // top half includes the entity list (2/3) and the
  790. // comments (1/3) - 2 gaps, above and below.
  791. y = iHeight/2;
  792. y -= 2 * DlgYBorder;
  793. y = y / 3;
  794. w = iWidth - (2 * DlgXBorder);
  795. MOVE(hwndEnt[EntList], DlgXBorder, DlgYBorder, w, 2 * y);
  796. MOVE(hwndEnt[EntComment], DlgXBorder, 2 * DlgYBorder + 2 * y, w, y - (2 * DlgYBorder));
  797. // bottom half includes flags (fixed), k/v pairs,
  798. // and buttons (fixed).
  799. // xCheck = width of a single check box
  800. // yCheck = distance from top of one check to the next
  801. xCheck = (iWidth - (2 * DlgXBorder)) / 3;
  802. yCheck = 18;
  803. x = DlgXBorder;
  804. for (iRow = 0; iRow <= 12; iRow += 4)
  805. {
  806. y = iHeight/2;
  807. for (i = 0; i < 4; i++)
  808. {
  809. MOVE(hwndEnt[EntCheck1 + i + iRow],
  810. x, y, xCheck, yCheck);
  811. y += yCheck;
  812. }
  813. x += xCheck;
  814. }
  815. //
  816. // properties scroll box
  817. //
  818. y = iHeight/2 + 4 * yCheck;
  819. w = iWidth - (2 * DlgXBorder);
  820. h = (iHeight - (yCheck * 5 + 2 * DlgYBorder) ) - y;
  821. MOVE(hwndEnt[EntProps], DlgXBorder, y, w, h);
  822. y += h + DlgYBorder;
  823. //
  824. // key / value fields
  825. //
  826. w = iWidth-(DlgXBorder+45);
  827. MOVE(hwndEnt[EntKeyLabel], DlgXBorder, y, 40, yCheck);
  828. MOVE(hwndEnt[EntKeyField], DlgXBorder+40, y, w, yCheck);
  829. y += yCheck;
  830. MOVE(hwndEnt[EntValueLabel], DlgXBorder, y, 40, yCheck);
  831. MOVE(hwndEnt[EntValueField], DlgXBorder+40, y, w, yCheck);
  832. y += yCheck;
  833. //
  834. // angle check boxes
  835. //
  836. y += 2;
  837. i = y;
  838. x = DlgXBorder;
  839. xCheck = yCheck*2;
  840. MOVE(hwndEnt[EntDir135], x, y, xCheck, yCheck);
  841. y += yCheck;
  842. MOVE(hwndEnt[EntDir180], x, y, xCheck, yCheck);
  843. y += yCheck;
  844. MOVE(hwndEnt[EntDir225], x, y, xCheck, yCheck);
  845. y = i;
  846. x += xCheck;
  847. MOVE(hwndEnt[EntDir90], x, y, xCheck, yCheck);
  848. y += yCheck;
  849. y += yCheck;
  850. MOVE(hwndEnt[EntDir270], x, y, xCheck, yCheck);
  851. y = i;
  852. x += xCheck;
  853. MOVE(hwndEnt[EntDir45], x, y, xCheck, yCheck);
  854. y += yCheck;
  855. MOVE(hwndEnt[EntDir0], x, y, xCheck, yCheck);
  856. y += yCheck;
  857. MOVE(hwndEnt[EntDir315], x, y, xCheck, yCheck);
  858. y = i + yCheck/2;
  859. x += xCheck + xCheck/2;
  860. MOVE(hwndEnt[EntDirUp], x, y, xCheck, yCheck);
  861. y += yCheck;
  862. MOVE(hwndEnt[EntDirDown], x, y, xCheck, yCheck);
  863. y = i;
  864. x += 1.5 * xCheck;
  865. MOVE(hwndEnt[EntDelProp], x, y, xCheck*2, yCheck);
  866. y += yCheck + 4;
  867. MOVE(hwndEnt[EntAssignSounds], x, y, xCheck*2, yCheck);
  868. y += yCheck;
  869. MOVE(hwndEnt[EntAssignModels], x, y, xCheck*2, yCheck);
  870. // tab selector is always visible
  871. col = 0;
  872. iHeight += 24;
  873. MOVE(hwndEnt[EntTab], 0,0,iWidth,iHeight, HWND_BOTTOM, SWP_NOACTIVATE | SWP_NOCOPYBITS);
  874. SendMessage( g_qeglobals.d_hwndEntity, WM_SETREDRAW, 1, 0);
  875. // InvalidateRect(entwindow, NULL, TRUE);
  876. }
  877. void AssignSound()
  878. {
  879. CString strBasePath = ValueForKey(g_qeglobals.d_project_entity, "basepath");
  880. AddSlash(strBasePath);
  881. CString strPath = strBasePath;
  882. strPath += "sound\\";
  883. CWaveOpen dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Sound files (*.wav)|*.wav||", g_pParentWnd);
  884. dlgFile.m_ofn.lpstrInitialDir = strPath;
  885. if (dlgFile.DoModal() == IDOK)
  886. {
  887. SendMessage(hwndEnt[EntKeyField], WM_SETTEXT, 0, (LPARAM)"noise");
  888. CString str = dlgFile.GetPathName().GetBuffer(0);
  889. str.MakeLower();
  890. strBasePath.MakeLower();
  891. QE_ConvertDOSToUnixName(str.GetBuffer(0), str.GetBuffer(0));
  892. QE_ConvertDOSToUnixName(strBasePath.GetBuffer(0), strBasePath.GetBuffer(0));
  893. int n = str.Find(strBasePath);
  894. if (n == 0)
  895. {
  896. str = str.Right(str.GetLength() - strBasePath.GetLength());
  897. }
  898. SendMessage(hwndEnt[EntValueField], WM_SETTEXT, 0, (LPARAM)str.GetBuffer(0));
  899. AddProp();
  900. g_pParentWnd->GetXYWnd()->SetFocus();
  901. }
  902. }
  903. void AssignModel()
  904. {
  905. CString strBasePath = ValueForKey(g_qeglobals.d_project_entity, "basepath");
  906. AddSlash(strBasePath);
  907. CString strPath = strBasePath;
  908. strPath += "models\\mapobjects\\";
  909. CFileDialog dlgFile(TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, "Model files (*.md3)|*.md3||", g_pParentWnd);
  910. dlgFile.m_ofn.lpstrInitialDir = strPath;
  911. if (dlgFile.DoModal() == IDOK)
  912. {
  913. SendMessage(hwndEnt[EntKeyField], WM_SETTEXT, 0, (LPARAM)"model");
  914. CString str = dlgFile.GetPathName().GetBuffer(0);
  915. str.MakeLower();
  916. strBasePath.MakeLower();
  917. QE_ConvertDOSToUnixName(str.GetBuffer(0), str.GetBuffer(0));
  918. QE_ConvertDOSToUnixName(strBasePath.GetBuffer(0), strBasePath.GetBuffer(0));
  919. int n = str.Find(strBasePath);
  920. if (n == 0)
  921. {
  922. str = str.Right(str.GetLength() - strBasePath.GetLength());
  923. }
  924. SendMessage(hwndEnt[EntValueField], WM_SETTEXT, 0, (LPARAM)str.GetBuffer(0));
  925. AddProp();
  926. edit_entity->md3Class = NULL;
  927. edit_entity->brushes.onext->bModelFailed = false;
  928. g_pParentWnd->GetXYWnd()->SetFocus();
  929. }
  930. }
  931. /*
  932. =========================
  933. EntityWndProc
  934. =========================
  935. */
  936. BOOL CALLBACK EntityWndProc(
  937. HWND hwndDlg, // handle to dialog box
  938. UINT uMsg, // message
  939. WPARAM wParam, // first message parameter
  940. LPARAM lParam) // second message parameter
  941. {
  942. LPNMHDR lpnmh = NULL;
  943. RECT rc;
  944. GetClientRect(hwndDlg, &rc);
  945. switch (uMsg)
  946. {
  947. case WM_CHAR :
  948. {
  949. char c = toupper(LOWORD(wParam));
  950. // escape: hide the window
  951. if (c == 27)
  952. ShowWindow(hwndDlg, SW_HIDE);
  953. if (c == 'N')
  954. g_pParentWnd->PostMessage(WM_COMMAND, ID_VIEW_ENTITY, 0);
  955. else
  956. if (c == 'O')
  957. g_pParentWnd->PostMessage(WM_COMMAND, ID_VIEW_CONSOLE, 0);
  958. else
  959. if (c == 'T')
  960. g_pParentWnd->PostMessage(WM_COMMAND, ID_VIEW_TEXTURE, 0);
  961. else
  962. if (c == 'G')
  963. g_pParentWnd->PostMessage(WM_COMMAND, ID_VIEW_GROUPS, 0);
  964. else
  965. DefWindowProc (hwndDlg, uMsg, wParam, lParam);
  966. break;
  967. }
  968. case WM_NOTIFY:
  969. lpnmh = reinterpret_cast<LPNMHDR>(lParam);
  970. if (lpnmh->hwndFrom == g_wndTabs.GetSafeHwnd()) {
  971. if ( lpnmh->code == TCN_SELCHANGE)
  972. {
  973. int n = g_wndTabs.GetCurSel();
  974. if (g_pParentWnd->CurrentStyle() == 2 || g_pParentWnd->CurrentStyle() == 1)
  975. {
  976. if (n == 0) {
  977. SetInspectorMode(W_ENTITY);
  978. } else if (n == 1) {
  979. SetInspectorMode(W_TEXTURE);
  980. } else if (n == 2) {
  981. SetInspectorMode(W_CONSOLE);
  982. } else {
  983. SetInspectorMode(W_GROUP);
  984. }
  985. }
  986. else
  987. {
  988. if (n == 0) {
  989. SetInspectorMode(W_ENTITY);
  990. } else if (n == 1) {
  991. SetInspectorMode(W_GROUP);
  992. }
  993. }
  994. }
  995. }
  996. break;
  997. case WM_SIZE:
  998. DefWindowProc (hwndDlg, uMsg, wParam, lParam);
  999. break;
  1000. case WM_DESTROY:
  1001. SaveWindowPlacement(g_qeglobals.d_hwndEntity, "EntityWindowPlace");
  1002. DefWindowProc(hwndDlg, uMsg, wParam, lParam);
  1003. break;
  1004. case WM_GETMINMAXINFO:
  1005. {
  1006. LPMINMAXINFO lpmmi;
  1007. lpmmi = (LPMINMAXINFO) lParam;
  1008. lpmmi->ptMinTrackSize.x = 320;
  1009. lpmmi->ptMinTrackSize.y = 500;
  1010. }
  1011. return 0;
  1012. case WM_WINDOWPOSCHANGING:
  1013. {
  1014. LPWINDOWPOS lpwp;
  1015. lpwp = (LPWINDOWPOS) lParam;
  1016. DefWindowProc (hwndDlg, uMsg, wParam, lParam);
  1017. lpwp->flags |= SWP_NOCOPYBITS;
  1018. SizeEntityDlg(lpwp->cx-8, lpwp->cy-32);
  1019. return 0;
  1020. }
  1021. return 0;
  1022. case WM_COMMAND:
  1023. switch (LOWORD(wParam)) {
  1024. case IDC_BTN_ASSIGNSOUND:
  1025. AssignSound();
  1026. break;
  1027. case IDC_BTN_ASSIGNMODEL:
  1028. AssignModel();
  1029. break;
  1030. case IDC_E_DELPROP:
  1031. DelProp();
  1032. SetFocus (g_qeglobals.d_hwndCamera);
  1033. break;
  1034. case IDC_E_0:
  1035. SetKeyValue (edit_entity, "angle", "360");
  1036. SetFocus (g_qeglobals.d_hwndCamera);
  1037. SetKeyValuePairs ();
  1038. break;
  1039. case IDC_E_45:
  1040. SetKeyValue (edit_entity, "angle", "45");
  1041. SetFocus (g_qeglobals.d_hwndCamera);
  1042. SetKeyValuePairs ();
  1043. break;
  1044. case IDC_E_90:
  1045. SetKeyValue (edit_entity, "angle", "90");
  1046. SetFocus (g_qeglobals.d_hwndCamera);
  1047. SetKeyValuePairs ();
  1048. break;
  1049. case IDC_E_135:
  1050. SetKeyValue (edit_entity, "angle", "135");
  1051. SetFocus (g_qeglobals.d_hwndCamera);
  1052. SetKeyValuePairs ();
  1053. break;
  1054. case IDC_E_180:
  1055. SetKeyValue (edit_entity, "angle", "180");
  1056. SetFocus (g_qeglobals.d_hwndCamera);
  1057. SetKeyValuePairs ();
  1058. break;
  1059. case IDC_E_225:
  1060. SetKeyValue (edit_entity, "angle", "225");
  1061. SetFocus (g_qeglobals.d_hwndCamera);
  1062. SetKeyValuePairs ();
  1063. break;
  1064. case IDC_E_270:
  1065. SetKeyValue (edit_entity, "angle", "270");
  1066. SetFocus (g_qeglobals.d_hwndCamera);
  1067. SetKeyValuePairs ();
  1068. break;
  1069. case IDC_E_315:
  1070. SetKeyValue (edit_entity, "angle", "315");
  1071. SetFocus (g_qeglobals.d_hwndCamera);
  1072. SetKeyValuePairs ();
  1073. break;
  1074. case IDC_E_UP:
  1075. SetKeyValue (edit_entity, "angle", "-1");
  1076. SetFocus (g_qeglobals.d_hwndCamera);
  1077. SetKeyValuePairs ();
  1078. break;
  1079. case IDC_E_DOWN:
  1080. SetKeyValue (edit_entity, "angle", "-2");
  1081. SetFocus (g_qeglobals.d_hwndCamera);
  1082. SetKeyValuePairs ();
  1083. break;
  1084. case IDC_BTN_HIDE:
  1085. ::PostMessage(g_qeglobals.d_hwndMain, WM_COMMAND, ID_VIEW_CAMERATOGGLE, 0);
  1086. break;
  1087. case IDC_CHECK1:
  1088. case IDC_CHECK2:
  1089. case IDC_CHECK3:
  1090. case IDC_CHECK4:
  1091. case IDC_CHECK5:
  1092. case IDC_CHECK6:
  1093. case IDC_CHECK7:
  1094. case IDC_CHECK8:
  1095. case IDC_CHECK9:
  1096. case IDC_CHECK10:
  1097. case IDC_CHECK11:
  1098. case IDC_CHECK12:
  1099. GetSpawnFlags();
  1100. SetFocus (g_qeglobals.d_hwndCamera);
  1101. break;
  1102. case IDC_E_PROPS:
  1103. switch (HIWORD(wParam))
  1104. {
  1105. case LBN_SELCHANGE:
  1106. EditProp();
  1107. return TRUE;
  1108. }
  1109. break;
  1110. case IDC_E_LIST:
  1111. switch (HIWORD(wParam)) {
  1112. case LBN_SELCHANGE:
  1113. {
  1114. int iIndex;
  1115. eclass_t *pec;
  1116. iIndex = SendMessage(hwndEnt[EntList], LB_GETCURSEL, 0, 0);
  1117. pec = (eclass_t *)SendMessage(hwndEnt[EntList], LB_GETITEMDATA,
  1118. iIndex, 0);
  1119. UpdateSel(iIndex, pec);
  1120. return TRUE;
  1121. break;
  1122. }
  1123. case LBN_DBLCLK:
  1124. CreateEntity ();
  1125. SetFocus (g_qeglobals.d_hwndCamera);
  1126. break;
  1127. }
  1128. break;
  1129. default:
  1130. return DefWindowProc( hwndDlg, uMsg, wParam, lParam );
  1131. }
  1132. return 0;
  1133. }
  1134. return DefWindowProc (hwndDlg, uMsg, wParam, lParam);
  1135. }