2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
26 ===========================================================================
29 #include "../../idlib/precompiled.h"
35 #include "PreviewDlg.h"
36 #include "CommentsDlg.h"
38 const int PARENTID = 99999;
40 extern HTREEITEM FindTreeItem(CTreeCtrl *tree, HTREEITEM root, const char *text, HTREEITEM forceParent);
44 IMPLEMENT_DYNAMIC(CPreviewDlg, CDialog)
45 CPreviewDlg::CPreviewDlg(CWnd* pParent /*=NULL*/)
46 : CDialog(CPreviewDlg::IDD, pParent)
49 disablePreview = false;
52 CPreviewDlg::~CPreviewDlg()
56 void CPreviewDlg::DoDataExchange(CDataExchange* pDX)
58 CDialog::DoDataExchange(pDX);
59 DDX_Control(pDX, IDC_TREE_MEDIA, treeMedia);
60 DDX_Control(pDX, IDC_EDIT_INFO, editInfo);
61 DDX_Control(pDX, IDC_PREVIEW, wndPreview);
65 BEGIN_MESSAGE_MAP(CPreviewDlg, CDialog)
66 ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_MEDIA, OnTvnSelchangedTreeMedia)
67 ON_BN_CLICKED(IDC_BUTTON_RELOAD, OnBnClickedButtonReload)
68 ON_BN_CLICKED(IDC_BUTTON_ADD, OnBnClickedButtonAdd)
69 ON_BN_CLICKED(IDC_BUTTON_PLAY, OnBnClickedButtonPlay)
73 // CPreviewDlg message handlers
75 BOOL CPreviewDlg::OnInitDialog()
77 CDialog::OnInitDialog();
79 m_image.Create(IDB_BITMAP_MATERIAL, 16, 1, RGB(255, 255, 255));
80 treeMedia.SetImageList(&m_image, TVSIL_NORMAL);
81 if ( disablePreview ) {
82 wndPreview.ShowWindow( SW_HIDE );
84 wndPreview.setDrawable(&m_testDrawable);
90 if ( mediaName.Length() ) {
91 HTREEITEM root = treeMedia.GetRootItem();
92 HTREEITEM sel = FindTreeItem(&treeMedia, root, mediaName, NULL );
94 treeMedia.SelectItem(sel);
98 return TRUE; // return TRUE unless you set the focus to a control
102 void CPreviewDlg::BuildTree() {
106 treeMedia.DeleteAllItems();
110 if ( currentMode == GUIS ) {
111 files = fileSystem->ListFilesTree( "guis", ".gui" );
112 AddStrList( "base", files->GetList(), GUIS );
113 fileSystem->FreeFileList( files );
114 } else if ( currentMode == MODELS ) {
115 files = fileSystem->ListFilesTree( "models", ".lwo" );
116 AddStrList( "base", files->GetList(), MODELS );
117 fileSystem->FreeFileList( files );
118 files = fileSystem->ListFilesTree( "models", ".ase" );
119 AddStrList( "base", files->GetList(), MODELS );
120 fileSystem->FreeFileList( files );
121 files = fileSystem->ListFilesTree( "models", ".ma" );
122 AddStrList( "base", files->GetList(), MODELS );
123 fileSystem->FreeFileList( files );
124 } else if ( currentMode == SOUNDS ) {
126 } else if ( currentMode == MATERIALS ) {
127 AddMaterials( true );
128 } else if ( currentMode == PARTICLES ) {
129 AddParticles( true );
130 } else if ( currentMode == SKINS ) {
135 void CPreviewDlg::RebuildTree( const char *_data ) {
141 void CPreviewDlg::AddCommentedItems() {
142 const char *buffer = NULL;
145 path = (currentMode == GUIS) ? "guis/guis.commented" : "models/models.commented";
146 idParser src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
147 if (fileSystem->ReadFile(path, (void**)&buffer, NULL) && buffer) {
148 src.LoadMemory(buffer, strlen(buffer), path);
149 if (src.IsLoaded()) {
150 idToken token, tok1, tok2, tok3;
151 while( src.ReadToken( &token ) ) {
153 // start a new commented item
155 if (src.ReadToken(&tok1) && src.ReadToken(&tok2) && src.ReadToken(&tok3)) {
164 fileSystem->FreeFile((void*)buffer);
166 commentItem = treeMedia.InsertItem("Commented");
169 for (int i = 0; i < c; i++) {
170 HTREEITEM child = treeMedia.InsertItem(items[i].Name, commentItem);
171 treeMedia.SetItemData(child, -1 - i);
172 treeMedia.SetItemImage(child, 2, 2);
179 void CPreviewDlg::AddStrList( const char *root, const idStrList &list, int id ) {
181 HTREEITEM base = treeMedia.GetRootItem();
183 out = treeMedia.GetItemText(base);
184 if (stricmp(root, out)) {
190 base = treeMedia.InsertItem(root);
191 treeMedia.SetItemData(base, PARENTID);
194 HTREEITEM item = base;
197 int count = list.Num();
200 for (int i = 0; i < count; i++) {
201 idStr name = list[i];
203 // now break the name down convert to slashes
204 name.BackSlashesToSlashes();
208 int len = last.Length();
210 index = name.Last('/');
212 name.Left(index, last);
215 else if (idStr::Icmpn(last, name, len) == 0 && name.Last('/') <= len) {
216 name.Right(name.Length() - len - 1, out);
217 add = treeMedia.InsertItem(out, item);
221 quickTree.Set(qt, add);
222 treeMedia.SetItemImage(add, 2, 2);
223 treeMedia.SetItemData(add, id);
234 index = name.Find('/');
236 HTREEITEM newItem = NULL;
237 HTREEITEM *check = NULL;
238 name.Left( index, out );
243 if (quickTree.Get(qt, &check)) {
246 //HTREEITEM newItem = FindTreeItem(&treeMedia, item, name.Left(index, out), item);
247 if (newItem == NULL) {
248 newItem = treeMedia.InsertItem(out, item);
252 quickTree.Set(qt, newItem);
253 treeMedia.SetItemImage(newItem, 0, 1);
254 treeMedia.SetItemData(newItem, PARENTID);
259 name.Right(name.Length() - index - 1, out);
264 add = treeMedia.InsertItem(name, item);
269 quickTree.Set(qt, add);
270 treeMedia.SetItemImage(add, 2, 2);
271 treeMedia.SetItemData(add, id);
279 void CPreviewDlg::OnTvnSelchangedTreeMedia(NMHDR *pNMHDR, LRESULT *pResult)
281 LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
282 HTREEITEM item = treeMedia.GetSelectedItem();
284 CWnd *add = GetDlgItem(IDC_BUTTON_ADD);
286 add->EnableWindow(treeMedia.GetItemData(item) == GUIS || treeMedia.GetItemData(item) == MODELS);
290 editInfo.SetWindowText("No comments for this item");
291 int id = treeMedia.GetItemData(item);
292 if ( id == GUIS || id == MODELS || id == MATERIALS || id == WAVES || id == PARTICLES || id == SKINS ) {
293 mediaName = treeMedia.GetItemText( item );
295 // have to build the name back up
296 HTREEITEM parent = treeMedia.GetParentItem( item );
297 while ( parent != NULL ) {
298 idStr strParent = treeMedia.GetItemText( parent );
300 strParent += mediaName;
301 mediaName = strParent;
302 parent = treeMedia.GetParentItem( parent );
304 // strip the leading "base/"
305 if (id == MATERIALS) {
306 mediaName.Strip("Materials/");
307 } else if (id == WAVES) {
308 mediaName.Strip( "Wave files/" );
309 } else if (id == PARTICLES) {
310 mediaName.Strip("Particles/");
312 } else if ( id == SKINS ) {
313 mediaName.Strip( "Matching Skins/" );
314 mediaName.Strip( "Skins/" );
316 mediaName.Strip( "base/" );
319 } else if (id == WAVES || id == SOUNDS) {
320 mediaName = treeMedia.GetItemText( item );
322 if ( treeMedia.ItemHasChildren(item) == FALSE ) {
323 int dw = abs(( int )treeMedia.GetItemData( item )) - 1;
324 if ( dw < items.Num() ) {
325 idStr work = items[dw].Path;
327 work += items[dw].Comments;
328 editInfo.SetWindowText( work );
329 mediaName = items[dw].Path;
334 if ( currentMode == MODELS || currentMode == SKINS ) {
336 if ( currentMode == MODELS ) {
337 modelMedia = mediaName;
341 if ( modelMedia.Length() ) {
342 int size = fileSystem->ReadFile( modelMedia, NULL, NULL );
344 if ( strstr( modelMedia, ".lwo" ) ) {
350 if ( size > lsize ) {
351 if ( MessageBox("Model appears to be quite large, are you sure you want to preview it?", "High Poly Model?", MB_YESNO ) == IDNO ) {
356 m_drawModel.setMedia( modelMedia );
357 if ( currentMode == SKINS ) {
358 m_drawModel.SetSkin( mediaName );
361 m_drawModel.SetRealTime(0);
362 wndPreview.setDrawable( &m_drawModel );
363 wndPreview.Invalidate();
364 wndPreview.RedrawWindow();
367 else if ( currentMode == PARTICLES ) {
368 m_drawModel.setMedia( mediaName );
369 m_drawModel.SetRealTime(50);
370 wndPreview.setDrawable( &m_drawModel );
371 wndPreview.Invalidate();
372 wndPreview.RedrawWindow();
374 } else if ( currentMode == GUIS ) {
375 const idMaterial *mat = declManager->FindMaterial("guisurfs/guipreview");
376 mat->SetGui(mediaName);
377 m_drawMaterial.setMedia("guisurfs/guipreview");
378 m_drawMaterial.setScale(4.4f);
379 wndPreview.setDrawable(&m_drawMaterial);
380 wndPreview.Invalidate();
381 wndPreview.RedrawWindow();
382 idUserInterface *gui = uiManager->FindGui( mediaName, false, false, true );
384 idStr str = gui->Comment();
385 str.Replace( "\n", "\r\n" );
387 editInfo.SetWindowText( str );
391 } else if (currentMode == MATERIALS) {
392 m_drawMaterial.setMedia(mediaName);
393 m_drawMaterial.setScale(1.0);
394 wndPreview.setDrawable(&m_drawMaterial);
395 wndPreview.Invalidate();
396 wndPreview.RedrawWindow();
400 //m_drawGui.setMedia(matName);
401 //wndPreview.setDrawable(&m_drawMaterial);
402 //wndPreview.RedrawWindow();
409 BOOL CPreviewDlg::Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd)
411 BOOL b = CDialog::Create(lpszTemplateName, pParentWnd);
416 void CPreviewDlg::OnCancel()
418 if ( AfxGetApp()->GetMainWnd() == GetParent() && GetParent() ) {
419 GetParent()->EnableWindow(TRUE);
420 g_qeglobals.sw->StopAllSounds();
425 returnCode = IDCANCEL;
428 void CPreviewDlg::OnOK()
430 if ( AfxGetApp()->GetMainWnd() == GetParent() && GetParent() ) {
431 GetParent()->EnableWindow(TRUE);
432 g_qeglobals.sw->StopAllSounds();
440 bool CPreviewDlg::Waiting() {
441 AfxGetApp()->PumpMessage();
442 return (returnCode == -1);
445 void CPreviewDlg::SetModal() {
448 void CPreviewDlg::OnBnClickedButtonReload()
451 g_qeglobals.sw->StopAllSounds();
454 void CPreviewDlg::OnBnClickedButtonAdd()
456 HTREEITEM item = treeMedia.GetSelectedItem();
457 if (treeMedia.ItemHasChildren(item) == FALSE && (treeMedia.GetItemData(item) == GUIS || treeMedia.GetItemData(item) == MODELS)) {
459 dlg.strPath = mediaName;
462 ci.Name = dlg.strName;
463 ci.Path = dlg.strPath;
464 ci.Comments = dlg.strComments;
466 item = treeMedia.InsertItem(ci.Name, commentItem);
467 treeMedia.SetItemData(item, -1 - (items.Num() + 1));
468 treeMedia.SetItemImage(item, 2, 2);
470 path = (currentMode == GUIS) ? "guis/guis.commented" : "models/models.commented";
473 fileSystem->ReadFile( path, &buffer );
474 str = (char *) buffer;
475 fileSystem->FreeFile( buffer );
476 str += "\r\n\r\n{\r\n\t\"";
482 str += "\"\r\n}\r\n";
483 fileSystem->WriteFile(path, (void*)&str[0], str.Length(), "fs_devpath");
490 void CPreviewDlg::AddSounds(bool rootItems) {
492 idStrList list(1024);
493 idStrList list2(1024);
494 HTREEITEM base = treeMedia.InsertItem("Sound Shaders");
496 for( i = 0; i < declManager->GetNumDecls( DECL_SOUND ); i++ ) {
497 const idSoundShader *poo = declManager->SoundByIndex( i, false );
498 list.AddUnique( poo->GetFileName() );
502 for ( i = 0; i < list.Num(); i++ ) {
503 HTREEITEM child = treeMedia.InsertItem(list[i], base);
504 treeMedia.SetItemData(child, SOUNDPARENT);
505 treeMedia.SetItemImage(child, 0, 1);
507 for (j = 0; j < declManager->GetNumDecls( DECL_SOUND ); j++) {
508 const idSoundShader *poo = declManager->SoundByIndex( j, false );
509 if ( idStr::Icmp( list[i], poo->GetFileName() ) == 0 ) {
510 list2.Append( poo->GetName() );
514 for (j = 0; j < list2.Num(); j++) {
515 HTREEITEM child2 = treeMedia.InsertItem( list2[j], child );
516 treeMedia.SetItemData(child2, SOUNDS);
517 treeMedia.SetItemImage(child2, 2, 2);
522 files = fileSystem->ListFilesTree( "sound", ".wav" );
523 AddStrList( "Wave files", files->GetList(), WAVES );
524 fileSystem->FreeFileList( files );
527 void CPreviewDlg::SetMode( int mode, const char *preSelect ) {
531 mediaName = preSelect;
534 if (GetSafeHwnd() == NULL) {
539 switch (currentMode) {
544 wndPreview.ShowWindow(SW_SHOW);
545 wnd = GetDlgItem(IDC_BUTTON_PLAY);
547 wnd->ShowWindow(SW_HIDE);
549 wnd = GetDlgItem(IDC_BUTTON_ADD);
551 wnd->ShowWindow(SW_SHOW);
553 wnd = GetDlgItem(IDC_EDIT_INFO);
555 wnd->ShowWindow(SW_SHOW);
559 wndPreview.ShowWindow(SW_SHOW);
560 wnd = GetDlgItem(IDC_BUTTON_PLAY);
562 wnd->ShowWindow(SW_HIDE);
564 wnd = GetDlgItem(IDC_BUTTON_ADD);
566 wnd->ShowWindow(SW_HIDE);
568 wnd = GetDlgItem(IDC_EDIT_INFO);
570 wnd->ShowWindow(SW_HIDE);
575 wndPreview.ShowWindow(SW_HIDE);
576 wnd = GetDlgItem(IDC_BUTTON_PLAY);
578 wnd->ShowWindow(SW_SHOW);
580 wnd = GetDlgItem(IDC_BUTTON_ADD);
582 wnd->ShowWindow(SW_HIDE);
584 wnd = GetDlgItem(IDC_EDIT_INFO);
586 wnd->ShowWindow(SW_HIDE);
592 void CPreviewDlg::OnBnClickedButtonPlay() {
593 g_qeglobals.sw->PlayShaderDirectly(mediaName);
596 void CPreviewDlg::AddMaterials(bool rootItems) {
597 idStrList list(1024);
599 int count = declManager->GetNumDecls( DECL_MATERIAL );
601 for (int i = 0; i < count; i++) {
602 const idMaterial *mat = declManager->MaterialByIndex(i, false);
604 if (strchr(mat->GetName(), '/') == NULL && strchr(mat->GetName(), '\\') == NULL) {
608 list.Append(mat->GetName());
611 AddStrList("Materials", list, MATERIALS);
616 void CPreviewDlg::AddParticles(bool rootItems) {
617 idStrList list(1024);
618 int count = declManager->GetNumDecls( DECL_PARTICLE );
620 for (int i = 0; i < count; i++) {
621 const idDecl *ips = declManager->DeclByIndex( DECL_PARTICLE, i );
623 if (strchr(ips->GetName(), '/') == NULL && strchr(ips->GetName(), '\\') == NULL) {
627 list.Append(ips->GetName());
630 AddStrList("Particles", list, PARTICLES);
634 void CPreviewDlg::AddSkins( bool rootItems ) {
635 idStrList list(1024);
636 idStrList list2(1024);
638 int count = declManager->GetNumDecls( DECL_SKIN );
640 for (int i = 0; i < count; i++) {
641 const idDeclSkin *skin = declManager->SkinByIndex(i);
643 if (strchr(skin->GetName(), '/') == NULL && strchr(skin->GetName(), '\\') == NULL) {
647 if ( data.Length() ) {
648 for ( int j = 0; j < skin->GetNumModelAssociations(); j++ ){
649 str = skin->GetAssociatedModel( j );
651 if ( data.Cmp(str) == 0 ) {
652 list.Append(skin->GetName());
656 list2.Append(skin->GetName());
660 AddStrList( "Matching Skins", list, SKINS );
661 AddStrList( "Skins", list2, SKINS );
665 void CPreviewDlg::OnShowWindow( BOOL bShow, UINT status ) {
666 if ( bShow && AfxGetApp()->GetMainWnd() == GetParent() && GetParent() ) {
667 GetParent()->EnableWindow( FALSE );