]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/extra/qe4/win_ent.c
Q2Tools source - didn't import this in initially
[xonotic/netradiant.git] / tools / quake2 / extra / qe4 / win_ent.c
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 */
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 */
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 */
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
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 */
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 */
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 */
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
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 //
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 //
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
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
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
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 */
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 */
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 */
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;
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 */
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 */
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 }