workspacemanager.cpp

来自「hl2 source code. Do not use it illegal.」· C++ 代码 · 共 1,903 行 · 第 1/3 页

CPP
1,903
字号
#include "cbase.h"
#include "workspacemanager.h"
#include "workspacebrowser.h"
#include "workspace.h"
#include "statuswindow.h"
#include "SoundEmitterSystemBase.h"
#include "drawhelper.h"
#include "InputProperties.h"
#include "filesystem.h"
#include "cmdlib.h"
#include "project.h"
#include "scene.h"
#include <KeyValues.h>
#include "utlbuffer.h"
#include "iscenemanagersound.h"
#include "soundentry.h"
#include "vcdfile.h"
#include "soundbrowser.h"
#include "wavebrowser.h"
#include "VSSProperties.h"
#include "resource.h"
#include "soundproperties.h"
#include "waveproperties.h"
#include "wavefile.h"
#include "ifileloader.h"
#include "MultipleRequest.h"

char g_appTitle[] = "Source Engine SceneManager v0.1";
static char g_appTitleFmt[] = "%s - SceneManager Workspace";
static char g_appTitleFmtModified[] = "%s * - SceneManager Workspace";

#define RECENT_FILES_FILE "scenemanager.rf"

enum
{
	// Menu options
	IDC_WSM_FILE_EXIT = 1000,

	IDC_WSM_FILE_WS_NEW,
	IDC_WSM_FILE_WS_OPEN,
	IDC_WSM_FILE_WS_CLOSE,
	IDC_WSM_FILE_WS_SAVE,

	IDC_WSM_FILE_WS_REFRESH,

	IDC_WSM_FILE_WS_VSSPROPERTIES,
	IDC_WSM_FILE_WS_CHECKOUT,
	IDC_WSM_FILE_WS_CHECKIN,

	IDC_WSM_FILE_SCENE_NEW, // + prompt for add to active project

	IDC_WSM_PROJECT_PRJ_NEW,   // + Prompt for add to workspace

	IDC_WSM_PROJECT_PRJ_INSERT,
	IDC_WSM_PROJECT_PRJ_REMOVE,
	IDC_WSM_PROJECT_PRJ_MODIFYCOMMENTS,

	IDC_WSM_PROJECT_SCENE_NEW,
	IDC_WSM_SCENE_REMOVE,

	IDC_WSM_SOUNDENTRY_PLAY,
	IDC_WSM_SOUNDENTRY_TOGGLEVOICEDUCK,
	IDC_WSM_SOUNDENTRY_EDITTEXT,
	IDC_WSM_SOUNDENTRY_SHOWINBROWSERS,
	IDC_WSM_SOUNDENTRY_PROPERTIES,

	IDC_WSM_SCENE_VCD_ADD,
	IDC_WSM_SCENE_VCD_REMOVE,
	IDC_WSM_SCENE_EDIT_COMMENTS,

	IDC_WSM_VCD_EDIT_COMMENTS,

	IDC_WSM_SELECTION_CHECKOUT,
	IDC_WSM_SELECTION_CHECKIN,

	IDC_WSM_SELECTION_MOVEUP,
	IDC_WSM_SELECTION_MOVEDOWN,

	IDC_WSM_WAVEFILE_PROPERTIES,

	// Controls
	IDC_WS_BROWSER,
	IDC_WS_SOUNDBROWSER,
	IDC_WS_WAVEBROWSER,

	// These should be the final entriex
	IDC_WSM_FILE_RECENT_WORKSPACE_START = 1500,
	IDC_WSM_FILE_RECENT_WORKSPACE_END = 1510,
};

static CWorkspaceManager *g_pManager = NULL;
CWorkspaceManager *GetWorkspaceManager()
{
	Assert( g_pManager );
	return g_pManager;
}

class CWorkspaceWorkArea : public mxWindow
{
public:
	CWorkspaceWorkArea( mxWindow *parent )
		: mxWindow( parent, 0, 0, 0, 0, "" )
	{
		SceneManager_AddWindowStyle( this, WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS );
	}

	virtual void redraw()
	{
		CDrawHelper helper( this, RGB( 200, 200, 200 ) );
	}
};

CWorkspaceManager::CWorkspaceManager()
	: mxWindow (0, 0, 0, 0, 0, g_appTitle, mxWindow::Normal)
{
	g_pManager = this;

	g_pStatusWindow = new CStatusWindow( this, 0, 0, 1024, 150, "" );
	g_pStatusWindow->setVisible( true );

	m_pWorkArea = new CWorkspaceWorkArea( this );

	Con_Printf( "Initializing\n" );

	Con_Printf( "CSoundEmitterSystemBase::Init()\n" );
	soundemitter->BaseInit();

	m_nRecentMenuItems = 0;

	// create menu stuff
	m_pMenuBar = new mxMenuBar (this);
	m_pFileMenu = new mxMenu ();
	m_pProjectMenu = new mxMenu ();

	m_pMenuBar->addMenu ("File", m_pFileMenu );
	m_pMenuBar->addMenu( "Project", m_pProjectMenu );
	
	CreateFileMenu( m_pFileMenu );
	CreateProjectMenu( m_pProjectMenu );

	setMenuBar ( m_pMenuBar );

	Con_Printf( "Creating browser\n" );

	m_pBrowser = new CWorkspaceBrowser( m_pWorkArea, this, IDC_WS_BROWSER );

	m_pSoundBrowser = NULL;
	m_pWaveBrowser = NULL;

	int w = 1280;
	setBounds (10, 10, w, 960);

	setVisible (true);

	Con_Printf( "Creating wave browser\n" );

	m_pWaveBrowser = new CWaveBrowser( m_pWorkArea, this, IDC_WS_WAVEBROWSER );

	Con_Printf( "Creating sound browser\n" );

	m_pSoundBrowser = new CSoundBrowser( m_pWorkArea, this, IDC_WS_SOUNDBROWSER );

	GetBrowser()->SetWorkspace( NULL );

	// See if command line requested workspace

	// Default layout
	PerformLayout( true );

	LoadRecentFilesMenuFromDisk();
}

CWorkspaceManager::~CWorkspaceManager()
{
}

bool CWorkspaceManager::Closing()
{
	Con_Printf( "Checking for sound script changes...\n" );

	MultipleRequestChangeContext();

	// Save any changed sound script files
	int c = soundemitter->GetNumSoundScripts();
	for ( int i = 0; i < c; i++ )
	{
		if ( !soundemitter->IsSoundScriptDirty( i ) )
			continue;

		char const *scriptname = soundemitter->GetSoundScriptName( i );
		if ( !scriptname )
			continue;

		Assert( filesystem->FileExists( scriptname ) );

		bool save = true;

		if ( filesystem->FileExists( scriptname ) )
		{
			if ( !filesystem->IsFileWritable( scriptname ) )
			{
				int retval = MultipleRequest( va( "Check out '%s'?", scriptname ));
				// Cancel
				if ( retval == 2 ) 
					return false;

				if ( retval == 0 )
				{
					VSS_Checkout( scriptname );

					if ( !filesystem->IsFileWritable( scriptname ) )
					{
						mxMessageBox( NULL, va( "Aborting shutdown, %s, not writable!!", scriptname ), g_appTitle, MX_MB_OK );
						return false;
					}
				}
				else if ( retval == 1 )
				{
					// Don't save
					save = false;
				}
			}

			if ( filesystem->IsFileWritable( scriptname ) )
			{
				int retval = mxMessageBox( NULL, va( "Save changes to out '%s'?", scriptname ), g_appTitle, MX_MB_YESNOCANCEL );
				// Cancel
				if ( retval == 2 ) 
					return false;

				if ( retval == 0 )
				{
					if ( !filesystem->IsFileWritable( scriptname ) )
					{
						mxMessageBox( NULL, va( "Aborting shutdown, %s, not writable!!", scriptname ), g_appTitle, MX_MB_OK );
						return false;
					}
				}
				else if ( retval == 1 )
				{
					// Skip changes!!!
					save = false;
				}
			}
		}

		// Try and save it
		if ( !save )
			continue;

		soundemitter->SaveChangesToSoundScript( i );
	}

	return CloseWorkspace();
}

void CWorkspaceManager::OnDelete()
{
	SaveRecentFilesMenuToDisk();
}

void CWorkspaceManager::CreateFileMenu( mxMenu *m )
{
	m->add ("&New Workspace", IDC_WSM_FILE_WS_NEW );
	m->addSeparator();
	m->add ("Open &Workspace...", IDC_WSM_FILE_WS_OPEN );
	m->add ("Sa&ve Workspace", IDC_WSM_FILE_WS_SAVE );
	m->add ("Close Wor&kspace", IDC_WSM_FILE_WS_CLOSE );
	m->addSeparator();
	m->add ("&Create New Scene...", IDC_WSM_FILE_SCENE_NEW );
	m->addSeparator();

	m->add( "V&SS Properties...", IDC_WSM_FILE_WS_VSSPROPERTIES );
	m->addSeparator();

	m->add( "Refresh\tF5", IDC_WSM_FILE_WS_REFRESH );

	m->addSeparator();

	m_pRecentFileMenu = new mxMenu ();
	m->addMenu ("Recent Files", m_pRecentFileMenu);

	m->addSeparator();
	m->add ("E&xit", IDC_WSM_FILE_EXIT );
}

void CWorkspaceManager::UpdateMenus()
{
	CWorkspace *ws = GetBrowser()->GetWorkspace();

	ITreeItem *item = GetBrowser()->GetSelectedItem();

	bool hasworkspace = ws != NULL ? true : false;
	bool workspacedirty = ws && ws->IsDirty() ? true : false;
	bool hasproject = item && item->GetProject() ? true : false;

	m_pMenuBar->setEnabled( IDC_WSM_FILE_WS_SAVE, true );
	m_pMenuBar->setEnabled( IDC_WSM_FILE_WS_CLOSE, hasworkspace );

	
	if ( hasproject )
	{
		m_pMenuBar->modify( IDC_WSM_FILE_SCENE_NEW, IDC_WSM_FILE_SCENE_NEW, va( "&Create Scene in '%s'", item->GetProject()->GetName() ) );
	}
	else
	{
		m_pMenuBar->modify( IDC_WSM_FILE_SCENE_NEW, IDC_WSM_FILE_SCENE_NEW, "&Create New Scene..." );
	}
	m_pMenuBar->setEnabled( IDC_WSM_FILE_SCENE_NEW, hasproject );

}

void CWorkspaceManager::CreateProjectMenu( mxMenu *m )
{
	m->add ("Create New Project...", IDC_WSM_PROJECT_PRJ_NEW );
	m->addSeparator();
	m->add ("Insert Project...", IDC_WSM_PROJECT_PRJ_INSERT );
	m->add ("Remove Project...", IDC_WSM_PROJECT_PRJ_REMOVE );
	m->addSeparator();
	m->add ("Properties...", IDC_WSM_PROJECT_PRJ_MODIFYCOMMENTS );
}

CWorkspaceBrowser *CWorkspaceManager::GetBrowser()
{
	return m_pBrowser;
}

CSoundBrowser *CWorkspaceManager::GetSoundBrowser()
{
	return m_pSoundBrowser;
}

CWaveBrowser *CWorkspaceManager::GetWaveBrowser()
{
	return m_pWaveBrowser;
}

int CWorkspaceManager::GetMaxRecentFiles() const
{
	return IDC_WSM_FILE_RECENT_WORKSPACE_END - IDC_WSM_FILE_RECENT_WORKSPACE_START;
}

#define MAX_FPS 250.0f
#define MIN_TIMESTEP ( 1.0f / MAX_FPS )

double realtime = 0.0f;

void CWorkspaceManager::Think( float dt )
{
	sound->Update( dt );
	int c = fileloader->ProcessCompleted();
	if ( c > 0 )
	{
		RefreshBrowsers();
		Con_Printf( "Thread loaded %i sounds\n", c );
	}
}

void CWorkspaceManager::Frame( void )
{
	static bool recursion_guard = false;

	static double prev = 0.0;
	double curr = (double) mx::getTickCount () / 1000.0;
	double dt = ( curr - prev );
	
	if ( recursion_guard )
		return;

	recursion_guard = true;

	// clamp to MAX_FPS
	if ( dt >= 0.0 && dt < MIN_TIMESTEP )
	{
		Sleep( max( 0, (int)( ( MIN_TIMESTEP - dt ) * 1000.0f ) ) );

		recursion_guard = false;
		return;
	}

	if ( prev != 0.0 )
	{
		dt = min( 0.1, dt );
		
		Think( dt );

		realtime += dt;
	}
	
	prev = curr;

	recursion_guard = false;
}

int CWorkspaceManager::handleEvent( mxEvent *event )
{
	int iret = 0;
	switch ( event->event )
	{
	default:
		break;
	case mxEvent::Activate:
		{
			if (event->action)
			{
				mx::setIdleWindow( this );
			}
			else
			{
				mx::setIdleWindow( 0 );
			}
			iret = 1;
		}
		break;
	case mxEvent::Idle:
		{
			iret = 1;
			Frame();
		}
		break;
	case mxEvent::KeyUp:
		{
			if ( event->key == VK_F5 )
			{
				RefreshBrowsers();
			}
		}
		break;
	case mxEvent::Action:
		{
			iret = 1;
			switch ( event->action )
			{
			default:
				{
					if ( event->action >= IDC_WSM_FILE_RECENT_WORKSPACE_START && 
						 event->action < IDC_WSM_FILE_RECENT_WORKSPACE_END )
					{
						OnRecentWorkspace( event->action - IDC_WSM_FILE_RECENT_WORKSPACE_START );
					}
					else
					{
						iret = 0;
					}
				}
				break;
			case IDC_WSM_FILE_EXIT:
				{
					mx::quit();
				}
				break;
			case IDC_WSM_FILE_WS_REFRESH:
				{
					RefreshBrowsers();
				}
				break;
			case IDC_WSM_FILE_WS_NEW:
				{
					OnNewWorkspace();
				}
				break;
			case IDC_WSM_FILE_WS_OPEN:
				{
					OnOpenWorkspace();
				}
				break;
			case IDC_WSM_FILE_WS_CLOSE:
				{
					OnCloseWorkspace();
				}
				break;
			case IDC_WSM_FILE_WS_SAVE:
				{
					OnSaveWorkspace();
				}
				break;
			case IDC_WSM_FILE_WS_VSSPROPERTIES:
				{
					OnChangeVSSProperites();
				}
				break;
			case IDC_WSM_FILE_WS_CHECKOUT:
				{
					OnCheckoutWorkspace();
				}
				break;
			case IDC_WSM_FILE_WS_CHECKIN:
				{
					OnCheckinWorkspace();
				}
				break;
			case IDC_WSM_PROJECT_PRJ_NEW:
				{
					OnNewProject();
				}
				break;
			case IDC_WSM_PROJECT_PRJ_INSERT:
				{
					OnInsertProject();
				}
				break;
			case IDC_WSM_PROJECT_PRJ_REMOVE:
				{
					OnRemoveProject();
				}
				break;
			case IDC_WSM_PROJECT_PRJ_MODIFYCOMMENTS:
				{
					OnModifyProjectComments();
				}
				break;
			case IDC_WSM_PROJECT_SCENE_NEW:
				{
					OnNewScene();
				}
				break;
			case IDC_WSM_SOUNDENTRY_PLAY:
				{
					OnSoundPlay();
				}
				break;
			case IDC_WSM_SOUNDENTRY_TOGGLEVOICEDUCK:
				{
					OnSoundToggleVoiceDuck();
				}
				break;
			case IDC_WSM_SOUNDENTRY_EDITTEXT:
				{
					OnSoundEditText();
				}
				break;
			case IDC_WSM_SOUNDENTRY_PROPERTIES:
				{
					OnSoundProperties();
				}
				break;
			case  IDC_WSM_SCENE_VCD_ADD:
				{
					OnSceneAddVCD();
				}
				break;
			case IDC_WSM_SCENE_VCD_REMOVE:
				{
					OnSceneRemoveVCD();
				}
				break;
			case IDC_WSM_SCENE_EDIT_COMMENTS:
				{
					OnModifySceneComments();
				}
				break;
			case IDC_WSM_VCD_EDIT_COMMENTS:
				{
					OnModifyVCDComments();
				}
				break;
			case IDC_WSM_SCENE_REMOVE:
				{
					OnRemoveScene();
				}
				break;
			case IDC_WSM_SOUNDENTRY_SHOWINBROWSERS:
				{
					OnSoundShowInBrowsers();
				}
				break;
			case IDC_WSM_SELECTION_CHECKOUT:
				{
					OnCheckout();
				}
				break;
			case IDC_WSM_SELECTION_CHECKIN:
				{
					OnCheckin();
				}
				break;
			case IDC_WSM_SELECTION_MOVEUP:
				{
					OnMoveUp();
				}
				break;
			case IDC_WSM_SELECTION_MOVEDOWN:
				{
					OnMoveDown();
				}
				break;
			case IDC_WSM_WAVEFILE_PROPERTIES:
				{
					OnWaveProperties();
				}
				break;
			}
		}
		break;
	case mxEvent::Size:
		{
			iret = 1;
			PerformLayout( false );
		}
		break;
	}

	return iret;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWorkspaceManager::PerformLayout( bool movebrowsers )
{
	int width = w2();
	int height = h2();

	int statush = 100;
	m_pWorkArea->setBounds( 0, 0, width, height - statush );
	if ( movebrowsers )
	{
		GetBrowser()->setBounds( 0, 0, m_pWorkArea->w2(), m_pWorkArea->h2() / 3 );
		if ( GetSoundBrowser() )
		{
			GetSoundBrowser()->setBounds( 0, m_pWorkArea->h2() / 3, m_pWorkArea->w2(), m_pWorkArea->h2() / 3 );
		}
		if ( GetWaveBrowser() ) 
		{
			GetWaveBrowser()->setBounds( 0, 2 * m_pWorkArea->h2() / 3, m_pWorkArea->w2(), m_pWorkArea->h2() / 3 );
		}
	}

	g_pStatusWindow->setBounds( 0, height - statush, width, statush );

}

//-----------------------------------------------------------------------------
// Purpose: 
// Output : Returns true on success, false on failure.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?