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 + -
显示快捷键?