00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdafx.h"
00026 #include "Radiant.h"
00027 #include "GroupDlg.h"
00028 #include "NameDlg.h"
00029
00030 #ifdef _DEBUG
00031 #define new DEBUG_NEW
00032 #undef THIS_FILE
00033 static char THIS_FILE[] = __FILE__;
00034 #endif
00035
00036 #define IMG_PATCH 0
00037 #define IMG_BRUSH 1
00038 #define IMG_GROUP 2
00039 #define IMG_ENTITY 3
00040 #define IMG_ENTITYGROUP 4
00041 #define IMG_MODEL 5
00042 #define IMG_SCRIPT 6
00043
00044
00045 #define MAX_GROUPS 4096
00046 #define GROUP_DELIMETER '@'
00047 #define GROUPNAME "QER_Group_%i"
00048
00049 CGroupDlg g_wndGroup;
00050 CGroupDlg *g_pGroupDlg = &g_wndGroup;
00051
00052
00053
00054 group_t *g_pGroups = NULL;
00055
00056 void Group_Add(entity_t *e)
00057 {
00058 group_t *g = (group_t*)qmalloc(sizeof(group_t));
00059 g->epairs = e->epairs;
00060 g->next = NULL;
00061 e->epairs = NULL;
00062
00063 HTREEITEM hItem = g_wndGroup.m_wndTree.GetSelectedItem();
00064 TVINSERTSTRUCT tvInsert;
00065 memset(&tvInsert, 0, sizeof(TVINSERTSTRUCT));
00066 tvInsert.item.iImage = IMG_GROUP;
00067 tvInsert.item.iSelectedImage = tvInsert.item.iImage;
00068
00069
00070 tvInsert.hParent = g_wndGroup.m_hWorld;
00071 tvInsert.hInsertAfter = NULL;
00072 tvInsert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
00073 char *pipo = ValueForKey(e->epairs, "group");
00074 tvInsert.item.pszText = _T(ValueForKey(g->epairs, "group"));
00075 g->itemOwner = g_wndGroup.m_wndTree.InsertItem(&tvInsert);
00076 g->next = g_pGroups;
00077 g_pGroups = g;
00078 }
00079
00080 group_t* Group_Alloc(char *name)
00081 {
00082 group_t *g = (group_t*)qmalloc(sizeof(group_t));
00083 SetKeyValue( g->epairs, "group", name );
00084 return g;
00085 }
00086
00087 group_t* Group_ForName(const char * name)
00088 {
00089 group_t *g = g_pGroups;
00090 while (g != NULL)
00091 {
00092 if (strcmp( ValueForKey(g->epairs,"group"), name ) == 0)
00093 break;
00094 g = g->next;
00095 }
00096 return g;
00097 }
00098
00099 void Group_AddToItem(brush_t *b, HTREEITEM item)
00100 {
00101 char cBuff[1024];
00102 int nImage = IMG_BRUSH;
00103 if (!g_qeglobals.m_bBrushPrimitMode)
00104 {
00105 return;
00106 }
00107 const char *pName = NULL;
00108 const char *pNamed = Brush_GetKeyValue(b, "name");
00109
00110 if (!b->owner || (b->owner == world_entity))
00111 {
00112 if (b->patchBrush)
00113 {
00114 pName = "Generic Patch";
00115 nImage = IMG_PATCH;
00116 }
00117 else
00118 {
00119 pName = "Generic Brush";
00120 nImage = IMG_BRUSH;
00121 }
00122 }
00123 else
00124 {
00125 pName = b->owner->eclass->name;
00126 if (b->owner->eclass->fixedsize)
00127 {
00128 nImage = IMG_ENTITY;
00129 }
00130 else
00131 {
00132 nImage = IMG_ENTITYGROUP;
00133 }
00134 }
00135
00136 strcpy(cBuff, pName);
00137
00138 TVINSERTSTRUCT tvInsert;
00139 memset(&tvInsert, 0, sizeof(TVINSERTSTRUCT));
00140 tvInsert.item.iImage = (b->patchBrush) ? IMG_PATCH : IMG_BRUSH;
00141 tvInsert.item.iSelectedImage = tvInsert.item.iImage;
00142 tvInsert.hParent = item;
00143 tvInsert.hInsertAfter = NULL;
00144 tvInsert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
00145 tvInsert.item.pszText = cBuff;
00146 HTREEITEM itemNew = g_pGroupDlg->m_wndTree.InsertItem(&tvInsert);
00147 g_pGroupDlg->m_wndTree.SetItemData(itemNew, reinterpret_cast<DWORD>(b));
00148 b->itemOwner = itemNew;
00149 g_pGroupDlg->m_wndTree.RedrawWindow();
00150
00151 }
00152
00153 void Group_RemoveBrush(brush_t *b)
00154 {
00155 if (!g_qeglobals.m_bBrushPrimitMode)
00156 {
00157 return;
00158 }
00159 if (b->itemOwner)
00160 {
00161 g_pGroupDlg->m_wndTree.DeleteItem(b->itemOwner);
00162 b->itemOwner = NULL;
00163 g_pGroupDlg->m_wndTree.RedrawWindow();
00164 }
00165 DeleteKey(b->epairs, "group");
00166 }
00167
00168 void Group_AddToWorld(brush_t *b)
00169 {
00170 if (!g_qeglobals.m_bBrushPrimitMode)
00171 {
00172 return;
00173 }
00174 HTREEITEM itemParent = g_pGroupDlg->m_wndTree.GetRootItem();
00175 Group_AddToItem(b, itemParent);
00176 }
00177
00178 void Group_AddToProperGroup(brush_t *b)
00179 {
00180 if (!g_qeglobals.m_bBrushPrimitMode)
00181 {
00182 return;
00183 }
00184
00185 const char *pGroup = Brush_GetKeyValue(b, "group");
00186
00187 if (b->itemOwner)
00188 {
00189 g_pGroupDlg->m_wndTree.DeleteItem(b->itemOwner);
00190 b->itemOwner = NULL;
00191 g_pGroupDlg->m_wndTree.RedrawWindow();
00192 }
00193
00194 if (*pGroup != 0)
00195 {
00196
00197 group_t *g = Group_ForName(pGroup);
00198 if (g)
00199 Group_AddToItem(b, g->itemOwner);
00200 #ifdef _DEBUG
00201 else
00202 Sys_Printf("WARNING: unexpected Group_ForName not found in Group_AddToProperGroup\n");
00203 #endif
00204 }
00205 else
00206 {
00207 Group_AddToWorld(b);
00208 }
00209 }
00210
00211 void Group_AddToSelected(brush_t *b)
00212 {
00213 if (!g_qeglobals.m_bBrushPrimitMode)
00214 {
00215 return;
00216 }
00217 HTREEITEM hItem = g_pGroupDlg->m_wndTree.GetSelectedItem();
00218 if (hItem == NULL)
00219 {
00220 hItem = g_pGroupDlg->m_wndTree.GetRootItem();
00221 }
00222 Group_AddToItem(b, hItem);
00223 }
00224
00225 void Group_Save(FILE *f)
00226 {
00227 group_t *g = g_pGroups;
00228 while (g)
00229 {
00230 fprintf(f,"{\n\"classname\" \"group_info\"\n\"group\" \"%s\"\n}\n", ValueForKey( g->epairs, "group" ));
00231 g = g->next;
00232 }
00233 }
00234
00235 void Group_Init()
00236 {
00237 if (!g_qeglobals.m_bBrushPrimitMode)
00238 {
00239 return;
00240 }
00241
00242
00243
00244 #ifdef _DEBUG
00245 Sys_Printf("TODO: fix leak in Group_Init\n");
00246 #endif
00247 group_t *g = g_pGroups;
00248 while (g)
00249 {
00250 epair_t *ep,*enext;
00251 for (ep = g->epairs ; ep ; ep=enext )
00252 {
00253 enext = ep->next;
00254 free (ep->key);
00255 free (ep->value);
00256 free (ep);
00257 }
00258 g = g->next;
00259 }
00260 g_pGroups = NULL;
00261 g_wndGroup.m_wndTree.DeleteAllItems();
00262 TVINSERTSTRUCT tvInsert;
00263 memset(&tvInsert, 0, sizeof(TVINSERTSTRUCT));
00264 tvInsert.hParent = NULL;
00265 tvInsert.hInsertAfter = NULL;
00266 tvInsert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
00267 tvInsert.item.pszText = _T("World");
00268 tvInsert.item.iImage = IMG_GROUP;
00269 tvInsert.item.iSelectedImage = IMG_GROUP;
00270 HTREEITEM hWorld = g_wndGroup.m_wndTree.InsertItem(&tvInsert);
00271
00272 brush_t *b;
00273 for (b = active_brushes.next; b != &active_brushes; b = b->next)
00274 {
00275 b->itemOwner = NULL;
00276 Group_AddToProperGroup(b);
00277 }
00278 for (b = selected_brushes.next ; b != &selected_brushes ; b = b->next)
00279 {
00280 b->itemOwner = NULL;
00281 Group_AddToProperGroup(b);
00282 }
00283 }
00284
00285
00286
00287
00288 void Group_GetListFromWorld(CStringArray *pArray)
00289 {
00290 if (!g_qeglobals.m_bBrushPrimitMode)
00291 {
00292 return;
00293 }
00294
00295 if (world_entity == NULL)
00296 {
00297 return;
00298 }
00299
00300 pArray->RemoveAll();
00301 char cBuff[1024];
00302 for (int i =0; i < MAX_GROUPS; i++)
00303 {
00304 sprintf(cBuff, GROUPNAME, i);
00305 char *pGroup = ValueForKey(world_entity, cBuff);
00306 if (pGroup && strlen(pGroup) > 0)
00307 {
00308 pArray->Add(pGroup);
00309 }
00310 else
00311 {
00312 break;
00313 }
00314 }
00315 }
00316
00317 void Group_RemoveListFromWorld()
00318 {
00319 if (!g_qeglobals.m_bBrushPrimitMode)
00320 {
00321 return;
00322 }
00323 CStringArray array;
00324 Group_GetListFromWorld(&array);
00325 int nCount = array.GetSize();
00326 for (int i = 0; i < nCount; i++)
00327 {
00328 DeleteKey(world_entity, array.GetAt(i));
00329 }
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 int CountChar(const char *p, char c)
00351 {
00352 int nCount = 0;
00353 int nLen = strlen(p)-1;
00354 while (nLen-- >= 0)
00355 {
00356 if (p[nLen] == c)
00357 {
00358 nCount++;
00359 }
00360 }
00361 return nCount;
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 void DecomposeSiblingList(const char *p, CStringArray *pArray, CTreeCtrl *pTree, HTREEITEM itemChild)
00425 {
00426 CString str = p;
00427 str += GROUP_DELIMETER;
00428 while (itemChild)
00429 {
00430 CString strAdd = str;
00431 strAdd += pTree->GetItemText(itemChild);
00432
00433 if (pTree->GetItemData(itemChild) == 0)
00434 {
00435 pArray->Add(strAdd);
00436 }
00437 if (pTree->ItemHasChildren(itemChild))
00438 {
00439 HTREEITEM itemOffspring = pTree->GetChildItem(itemChild);
00440 DecomposeSiblingList(strAdd, pArray, pTree, itemOffspring);
00441 }
00442 itemChild = pTree->GetNextSiblingItem(itemChild);
00443 }
00444 }
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00465
00466
00467
00468 CGroupDlg::CGroupDlg(CWnd* pParent )
00469 : CDialog(CGroupDlg::IDD, pParent)
00470 {
00471
00472
00473
00474 }
00475
00476
00477 void CGroupDlg::DoDataExchange(CDataExchange* pDX)
00478 {
00479 CDialog::DoDataExchange(pDX);
00480
00481 DDX_Control(pDX, IDC_TREE_GROUP, m_wndTree);
00482 DDX_Control(pDX, IDC_BTN_EDIT, m_wndEdit);
00483 DDX_Control(pDX, IDC_BTN_DEL, m_wndDel);
00484 DDX_Control(pDX, IDC_BTN_ADD, m_wndAdd);
00485
00486 }
00487
00488
00489 BEGIN_MESSAGE_MAP(CGroupDlg, CDialog)
00490
00491 ON_WM_SIZE()
00492 ON_BN_CLICKED(IDC_BTN_ADD, OnBtnAdd)
00493 ON_BN_CLICKED(IDC_BTN_DEL, OnBtnDel)
00494 ON_BN_CLICKED(IDC_BTN_EDIT, OnBtnEdit)
00495 ON_NOTIFY(NM_RCLICK, IDC_TREE_GROUP, OnRclickTreeGroup)
00496 ON_NOTIFY(TVN_ENDLABELEDIT, IDC_TREE_GROUP, OnEndlabeleditTreeGroup)
00497 ON_NOTIFY(NM_CLICK, IDC_TREE_GROUP, OnClickTreeGroup)
00498 ON_NOTIFY(TVN_SETDISPINFO, IDC_TREE_GROUP, OnSetdispinfoTreeGroup)
00499 ON_NOTIFY(TVN_BEGINDRAG, IDC_TREE_GROUP, OnBegindragTreeGroup)
00500
00501 END_MESSAGE_MAP()
00502
00504
00505
00506 void CGroupDlg::OnSize(UINT nType, int cx, int cy)
00507 {
00508 CDialog::OnSize(nType, cx, cy);
00509 CRect rct;
00510 GetClientRect(rct);
00511
00512 if ( m_wndAdd.GetSafeHwnd())
00513 {
00514
00515 CRect rctButton;
00516 m_wndAdd.GetWindowRect(rctButton);
00517 int nWidth = rctButton.Width();
00518 int nHeight = rctButton.Height();
00519
00520 int nTop = rct.Height() - nHeight - 4;
00521
00522 m_wndAdd.SetWindowPos(NULL, 4, nTop, 0, 0, SWP_NOSIZE);
00523 m_wndEdit.SetWindowPos(NULL, 8 + nWidth , nTop, 0, 0, SWP_NOSIZE);
00524 m_wndDel.SetWindowPos(NULL, 12 + (nWidth * 2), nTop, 0, 0, SWP_NOSIZE);
00525 rct.bottom = nTop;
00526 m_wndTree.SetWindowPos(NULL, rct.left + 4, rct.top + 4, rct.Width() - 8, rct.Height() - 8, SWP_SHOWWINDOW);
00527 }
00528 }
00529
00530 BOOL CGroupDlg::OnInitDialog()
00531 {
00532 CDialog::OnInitDialog();
00533 m_imgList.Create(IDB_BITMAP_GROUPS, 16, 0, ILC_COLOR);
00534 m_wndTree.SetImageList(&m_imgList, TVSIL_NORMAL);
00535 InitGroups();
00536 return TRUE;
00537
00538 }
00539
00540 void CGroupDlg::InitGroups()
00541 {
00542 Group_Init();
00543 }
00544
00545
00546 void CGroupDlg::OnBtnAdd()
00547 {
00548 CNameDlg dlg("New Group", this);
00549 if (dlg.DoModal() == IDOK)
00550 {
00551
00552 HTREEITEM hItem = m_wndTree.GetSelectedItem();
00553 TVINSERTSTRUCT tvInsert;
00554 memset(&tvInsert, 0, sizeof(TVINSERTSTRUCT));
00555 tvInsert.item.iImage = IMG_GROUP;
00556 tvInsert.item.iSelectedImage = tvInsert.item.iImage;
00557
00558
00559 tvInsert.hParent = m_hWorld;
00560 tvInsert.hInsertAfter = NULL;
00561 tvInsert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
00562 tvInsert.item.pszText = _T(dlg.m_strName.GetBuffer(0));
00563
00564 group_t *g = Group_Alloc( dlg.m_strName.GetBuffer(0) );
00565 g->itemOwner = m_wndTree.InsertItem(&tvInsert);
00566 g->next = g_pGroups;
00567 g_pGroups = g;
00568
00569
00570
00571 Select_AddToGroup( dlg.m_strName.GetBuffer(0) );
00572 }
00573 }
00574
00575 void CGroupDlg::OnBtnDel()
00576 {
00577 }
00578
00579 void CGroupDlg::OnBtnEdit()
00580 {
00581 }
00582
00583 BOOL CGroupDlg::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult)
00584 {
00585 return CDialog::OnChildNotify(message, wParam, lParam, pLResult);
00586 }
00587
00588 BOOL CGroupDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
00589 {
00590 return CDialog::OnNotify(wParam, lParam, pResult);
00591 }
00592
00593 void CGroupDlg::OnRclickTreeGroup(NMHDR* pNMHDR, LRESULT* pResult)
00594 {
00595
00596
00597 *pResult = 0;
00598 }
00599
00600 void CGroupDlg::OnEndlabeleditTreeGroup(NMHDR* pNMHDR, LRESULT* pResult)
00601 {
00602 TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
00603 const char *pText = pTVDispInfo->item.pszText;
00604 if (pText && strlen(pText) > 0)
00605 {
00606 HTREEITEM item = pTVDispInfo->item.hItem;
00607 if (m_wndTree.GetRootItem() != item)
00608 {
00609 m_wndTree.SetItemText(item, pText);
00610 if (pTVDispInfo->item.iImage != IMG_GROUP)
00611 {
00612
00613 }
00614 }
00615 else
00616 {
00617 Sys_Printf("Cannot rename the world\n");
00618 }
00619 }
00620 m_wndTree.RedrawWindow();
00621 *pResult = 0;
00622 }
00623
00624 void CGroupDlg::OnClickTreeGroup(NMHDR* pNMHDR, LRESULT* pResult)
00625 {
00626
00627
00628 *pResult = 0;
00629 }
00630
00631 void CGroupDlg::OnSetdispinfoTreeGroup(NMHDR* pNMHDR, LRESULT* pResult)
00632 {
00633 TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
00634
00635
00636 *pResult = 0;
00637 }
00638
00639 void CGroupDlg::OnCancel()
00640 {
00641 TreeView_EndEditLabelNow(m_wndTree.GetSafeHwnd(), TRUE);
00642 }
00643
00644 void CGroupDlg::OnOK()
00645 {
00646 TreeView_EndEditLabelNow(m_wndTree.GetSafeHwnd(), FALSE);
00647 }
00648
00649 void CGroupDlg::OnBegindragTreeGroup(NMHDR* pNMHDR, LRESULT* pResult)
00650 {
00651 NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
00652
00653
00654 *pResult = 0;
00655 }