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